Precision error in double

4.8k views Asked by At

A large double value gets changed when printed with %Lf Values upto the following combination gives proper results 9 digits before decimal / 6 digits after decimal e.g. of a value with 9 digits before decimal printed with %Lf Input : 3435537287.32 Output : 3435537287.320000

Once I increase the digits before decimal to 10, the values printed with %Lf adds garbage value. e.g. of a value with 10 digits before decimal printed with %Lf Input : 34355372871.3487 Output : 34355372871.348701 As you can see from the above output the input value is changed.

Is there any compile time option for g++/xlc++ that can be used so that the value is'nt changed?

::Code Snippet::

double d2 =  34355372871.3487; 
double d4 =  3435537287.3487; 

printf("d2 = %lf\n", d2); 
printf("d4 = %lf\n", d4); 

Thanks, Hudson

3

There are 3 answers

0
rbelli On

It is the precision of the double. The double is stored with 64 bits (8bytes).

(http://en.wikipedia.org/wiki/Double-precision_floating-point_format)

It uses 52 bits for a mantissa, 1 bit for the signal and 11 bits for the exponent.

Then, the 52 bits mantissa gives a 15–17 significant decimal digits precision.

2
Jürgen Schwietering On

Short explanation: you need long doubles

long double d2 =  34355372871.3487L; 
long double d4 =  3435537287.3487L; 

printf("d2 = %Lf\n", d2); 
printf("d4 = %Lf\n", d4);

long explanation: your significand takes to much space ;-) Here are the bits used in a Floatingpoint value.

//Type       Sign  Exponent Significand Total bit 
//Double        1        11          52        64 
//Long Double   1        15          64        80

Keep in mind that every digit in decimal takes about 3.3 bits (log(10)/log(2)) so 52bits/3.3 ~ 15-16 digits.

0
Hulk On

Due to the limited precision of floating point numbers, not every (or actually, only a few) decimal floating point literals correspond exactly to an existing binary representation.

Every literal is mapped to the closest existing value. This happens for every floating point type, but it will be less noticeable for higher precision types because there are more distinct numbers.