1

Possible Duplicate:
Why can't decimal numbers be represented exactly in binary?

i get very odd behaviour from simple float maths. eg.

//create a float with value of 1.0
float f = 1.0;
//take 0.1 from its value
f -=0.1;

for the first few times when i minus 0.1 it returns 0.9, 0.8, 0.7...... then for some reason it will return 0.699999999999, 0.59999999999 and so on. to say this is unexpected is an understatement.

so to fix this i either need to know why it would do this or a math function similar to Round(float) where it will round the number from 0.5999999 to 0.6.

thank you

edit, ok sorry for asking lol any fix available? like Round(float) kinda thing?

other edit: for the next person to ask about this heres a fix

final DecimalFormat myFormat = new DecimalFormat("#.#");
myFormat.format(myFloatValue)

this will change myFloatValue 0.599999 into 0.6

Community
  • 1
  • 1
user1033558
  • 157
  • 1
  • 4
  • 16
  • 8
    This is probably the single most-often asked question on all of StackOverflow, across all programming languages. – Sven Marnach Nov 16 '11 at 13:49
  • 2
    A short answer: http://floating-point-gui.de/. The long answer: http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html. – skynet Nov 16 '11 at 13:50
  • 1
    ..and yet again.. This is entirely expected behaviour. We get about one a day of these. Not all decimal numbers can be exactly represented in floating-point binary - 'Computer Science 101'. – Martin James Nov 16 '11 at 13:58
  • so a Round(float) equivalent exists or not? any way to show 0.6 instead of 0.5999999? – user1033558 Nov 16 '11 at 14:15
  • And this is the reason why its often a bad idea to compare floats like *if ( f == 23.52f ) {...}*. – JimmyB Nov 16 '11 at 14:17
  • Generally if you run into this problem and need correct handling then you should store all your fractional values in integers (multiplied with 10^4 for example), or use java.math.BigDecimal – ron Nov 16 '11 at 16:41

2 Answers2

1

This is due to a fundamental limitation of the floating point representation. Certain numbers, such as 0.1, are not exactly representable using base-2 arithmetic with finite precision.

Andrew Marshall
  • 1,469
  • 13
  • 14
1

A computer is a finite device, so it stores floating point numbers with a finite precision. And it stores them as binary floating point numbers -- that is relative to base 2 instead of base 10. A number with a finite representation as a decimal fraction doesn't necessarily have a finite representation as a binary number, so it must be rounded to be stored in a finite computer. In this example, 0.1 will be rounded to

0.1000000000000000055511151231257827021181583404541015625

when stored as a double precision floating point number, so you actually subtract a bit more than 0.1 in each step.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841
  • ok sorry for being the guy that asks this today :s so any chance of a fix? – user1033558 Nov 16 '11 at 14:00
  • @user1033558: There is nothing broken, so you can't fix it. What's your actual problem? – Sven Marnach Nov 16 '11 at 14:06
  • the problem is that i display this number, 0.599999999999 looks rubbish. 0.6 would be preferable. – user1033558 Nov 16 '11 at 14:12
  • Try something like this to format your floating point number `format("%.1f", 123.456f)` to a single decimal place. You can read more about formats [here](http://developer.android.com/reference/java/util/Formatter.html) – theisenp Nov 16 '11 at 14:17