Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Float doesn't change when i add 0.1 to it

Tags:

c

I am quite a newbie to c. So when i writing a small game demo, i face a really strange problem.

 void testC()
 {
     float a = 825300160;
     float b = a + 0.1;
     assert(a != b);
 }

The above assert statement can't passed. Very strange.
My environment is mac os ml. gcc 4.2.1

like image 407
Frank Cheng Avatar asked Nov 26 '12 00:11

Frank Cheng


People also ask

Why do computers mess up floating-point math?

The main cause of the error in floating point division is the division algorithms used to calculate the quotient. Most computer systems calculate division using multiplication by an inverse, mainly in Z=X/Y , Z = X * (1/Y) .

What happens when we add integer to float?

Yes, an integral value can be added to a float value. The basic math operations ( + , - , * , / ), when given an operand of type float and int , the int is converted to float first. So 15.0f + 2 will convert 2 to float (i.e. to 2.0f ) and the result is 17.0f .

How many floats are there between 0 and 1?

So how many “normal” non-zero numbers are there between 0 and 1? The negative exponents range from -1 all the way to -126. In each case, we have 223 distinct floating-point numbers because the mantissa is made of 23 bits. So we have 126 x 223 normal floating-point numbers in [0,1).


3 Answers

The fractional portion of a float consists of 23 bits. You need 30 bits to represent 825300160, so the less significant portion of the number is dropped. Adding .1 does not make a difference - you need to add roughly 32 for the number to change:

float a = 825300160;
float b = a + 31.5;
assert(a != b); // No change is detected
float c = a + 32;
assert(a != c); // Change is detected
like image 172
Sergey Kalinichenko Avatar answered Oct 12 '22 20:10

Sergey Kalinichenko


There's not enough precision in the float type. If you really need to distinguish a 0.1 addition to a number as large as 825300160, use double.

like image 28
Alexey Feldgendler Avatar answered Oct 12 '22 18:10

Alexey Feldgendler


As this site shows, both a and b would be represented as

0 10011100 10001001100010001010011

in the IEEE standard for floats, where the first bit is the sign, the next 8 are the exponent, and the remaining 23 the mantissa. There's just not enough space in those 23 bits to represent the difference, because the exponent is so large.

like image 33
1'' Avatar answered Oct 12 '22 20:10

1''