Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
585 views
in Technique[技术] by (71.8m points)

c++ - std::pow produce different result in 32 bit and 64 bit application

I have found the mismatch in the result of some complex calculations. When i thoroughly observed the intermediate results, its the std::pow function which creates that mismatch. Below are the inputs/output.

long double dvalue = 2.7182818284589998;
long double dexp = -0.21074699576017999;
long double result = std::powl( dvalue, dexp); 

64bit -> result = 0.80997896907296496 and 32bit -> result = 0.80997896907296507

I am using VS2008. I have tried with other variation of pow function which takes long double and return long double, but still see the same difference.

double pow( double base, double exponent );

long double powl( long double base, long double exponent );

I have read some info on this:

Intel x86 processors use 80-bit extended precision internally, whereas double is normally 64-bit wide.Different optimization levels affect how often floating point values from CPU get saved into memory and thus rounded from 80-bit precision to 64-bit precision. Alternatively, use the long double type, which is normally 80-bit wide on gcc to avoid rounding from 80-bit to 64-bit precision.

Could someone make me clearly understand the difference and ways to overcome this difference.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

What's probably happening is that the 32-bit build is using the 80-bit FPU registers to do the calculation and the 64-bit build is using the SIMD operations using 64-bit values, causing a slight discrepancy. Note that both answers agree to 14 decimal places, which is about the best you can hope for with 64-bit floating point values.

Visual C++ offers compiler options that let you say whether you prefer speed, consistency, or precision with regard to floating point operations. Using those options (e.g., /fp:strict), you can probably get consistent values between the two builds if that's important to you.

Also note that VC++2008 is rather old. Newer versions have fixes for many bugs, including some related to floating point. (Popular implementations of strtod in open source software have had bugs detected and fixed since 2008.) In addition to the precision difference between 80-bit and 64-bit operations, you may also be encountering parsing and display bugs. Nonetheless, floating point is hard, and bugs persist.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...