Why is my float division off by 0.00390625?
float a=67107842,b=512;
float c=a/b;
printf开发者_运维知识库("%lf\n",c);
Why is c
131070.000000 instead of the correct value 131070.00390625?
Your compiler's float
type is probably using the 32-bit IEEE 754 single-precision format.
67107842 is a 26-bit binary number:
11111111111111110000000010
The single-precision format represents most numbers as 1.x
multipled by some (positive or negative) power of two, where 23 bits are stored after the binary place, with the leading 1.
being implied (very small numbers are an exception).
But 67107842 would require 24 bits after the binary place (to be represented as 1.111111111111111000000001
multipled by 225). As there is only room to store 23 bits, the final 1
gets lost. So it is the value in a
that is wrong in this case, not the division - a
actually contains 67107840 (11111111111111110000000000
), which is exactly 131070 * 512.
You can see this if you print a
as well:
printf("%lf %lf %lf\n", a, b, c);
gives
67107840.000000 512.000000 131070.000000
Try changing a and c to be type "double", rather than float. That will give you better precision / accuracy. (Floats have about 6 or so significant digits; doubles have more than twice that.)
A float
typically uses 32bit IEEE-754 single precision representation, and is good for only approximately 6 significant decimal figures. A double
is good for 15, and where supported an 80 bit long double
gets to 20 significant figures.
Note that on some compilers there is no distinction between double
and long double
, or even no support for long double
at all.
One solution is to use an arbitrary-precision numeric library, or to use a decimal-floating point library rather then the built-in binary floating point support. Decimal floating point is not intrinsically more precise (though often such libraries support larger, more precise types), but will not show up the artefacts that occur when displaying a decimal representation of a binary floating point value. Decimal floating point is also likely to be much slower, since it is not typically implemented in hardware.
精彩评论