Reputation: 4019
I've been struggling to find a crazy bug in some C++ code and narrowed it down to this small section. I placed into a simple main.c to debug it and can't figure out why the floating point math is rounding when it shouldn't.
// setup the variables for this simple case
int writep = 672;
float offset = 672.000122;
int bufferSize = 2400;
float bufferSizeF = (float)bufferSize;
float outPointer = (float)writep - offset; // outPointer: -0.000122070313
if(outPointer < 0.0f){
printf("outPointer: %.9f \n", outPointer); // outPointer: -0.000122070313
outPointer += bufferSizeF; // outPointer SHOULD be: 2399.9998779296875
printf("outpointer: %.9f \n", outPointer); // outPointer: 2400.000000000
}
Someone...please explain. Thanks.
Upvotes: 0
Views: 106
Reputation: 2079
In IEEE 754 standard the floating point numbers are not equidistantly distributed over the number axis. Density of floating point values is higher around 0 than around 2400, so this is why the rounding is done when value is around 2400.
Here is the picture to illustrate it: https://www.google.fi/search?q=IEEE+754+distribution&biw=1920&bih=895&source=lnms&tbm=isch&sa=X&ved=0ahUKEwj-tKOWkMzPAhUEDywKHRdRAEUQ_AUIBigB#imgrc=rshe5_x1ZXFoKM%3A
Upvotes: 2
Reputation:
2400.000000000
and 2399.9998779296875
are too close for a standard float
to differentiate them. Try this:
#include<iostream>
int main() {
std::cout << (float)2399.9998779296875 << "\n";
}
It will probably give 2400
as output.
An IEEE 754 single precision float
can only hold about 7 to 8 significant decimal digits. If you need a higher number of significant digits use a double precision double
.
Upvotes: 2