Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I multiply a float? [duplicate]

Possible Duplicate:
Dealing with accuracy problems in floating-point numbers

I was quite surprised why I tried to multiply a float in C (with GCC 3.2) and that it did not do as I expected.. As a sample:

int main() {
  float nb = 3.11f;
  nb *= 10;
  printf("%f\n", nb);
}

Displays: 31.099998

I am curious regarding the way floats are implemented and why it produces this unexpected behavior?

like image 439
Dpp Avatar asked Jun 13 '10 05:06

Dpp


4 Answers

First off, you can multiply floats. The problem you have is not the multiplication itself, but the original number you've used. Multiplication can lose some precision, but here the original number you've multiplied started with lost precision.

This is actually an expected behavior. floats are implemented using binary representation which means they can't accurately represent decimal values.

See MSDN for more information.

You can also see in the description of float that it has 6-7 significant digits accuracy. In your example if you round 31.099998 to 7 significant digits you will get 31.1 so it still works as expected here.

double type would of course be more accurate, but still has rounding error due to it's binary representation while the number you wrote is decimal.

If you want complete accuracy for decimal numbers, you should use a decimal type. This type exists in languages like C#. http://msdn.microsoft.com/en-us/library/system.decimal.aspx

You can also use rational numbers representation. Using two integers which will give you complete accuracy as long as you can represent the number as a division of two integers.

like image 199
brickner Avatar answered Sep 19 '22 13:09

brickner


This is working as expected. Computers have finite precision, because they're trying to compute floating point values from integers. This leads to floating point inaccuracies.

The Floating point wikipedia page goes into far more detail on the representation and resulting accuracy problems than I could here :)

Interesting real-world side-note: this is partly why a lot of money calculations are done using integers (cents) - don't let the computer lose money with lack of precision! I want my $0.00001!

like image 21
Stephen Avatar answered Sep 21 '22 13:09

Stephen


The number 3.11 cannot be represented in binary. The closest you can get with 24 significant bits is 11.0001110000101000111101, which works out to 3.1099998950958251953125 in decimal.

If your number 3.11 is supposed to represent a monetary amount, then you need to use a decimal representation.

like image 39
dan04 Avatar answered Sep 19 '22 13:09

dan04


In the Python communities we often see people surprised at this, so there are well-tested-and-debugged FAQs and tutorial sections on the issue (of course they're phrased in terms of Python, not C, but since Python delegates float arithmetic to the underlying C and hardware anyway, all the descriptions of float's mechanics still apply).

It's not the multiplication's fault, of course -- remove the statement where you multiply nb and you'll see similar issues anyway.

like image 39
Alex Martelli Avatar answered Sep 19 '22 13:09

Alex Martelli