-1

Possible Duplicate:
Mysterious calculation error when multiply by 100

Here is a strange problem that I am facing. I store a value .6 to a float variable. When I multiply it with 100 I am getting wrong answer as 60.000004.Where does this .000004 come from? Here is my code



NSlog(@"%f",self.dataHandler.correctPercentage * 100);
if (self.obj.percentage >= (self.dataHandler.correctPercentage * 100) )
{
    //Do something
}

My value stored in self.dataHandler.correctPercentage is .6. But when I NSlog it, I am getting 60.000004. My boundary conditions are going wrong due to this.

Why is this happening?

arundevma
  • 933
  • 7
  • 24

3 Answers3

6

This is a rounding error. Numbers are stored in binary, not decimal. The fractions that can be accurately encoded in a finite number of binary digits are not the same as the ones that can be accurately encoded in decimal.

For an example of the problem in decimal, consider 1/3. If I encode 1/3 as 0.333, then (1/3)*3 = 0.999. Binary has the same problem.

If you need decimal numbers to be accurately encoded in their decimal form, then you should use NSDecimalNumber which is designed for this.

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
1

The computer cannot save most float numbers without rounding error. this has several implications especially for equality checking — as floats tend to be not equal, even if the pure math would make you think that.

In math, numbers have infinitive space to be stored, an infinitive numbers of digits can be used. But the computer cannot handle infinity, as it is limited in resources.

You should read What Every Computer Scientist Should Know About Floating-Point Arithmetic (at least the first few paragraphs)

I also reviewed a code that runs into similar problems yesterday: https://codereview.stackexchange.com/questions/14911/is-there-a-better-way-of-showing-an-image-based-on-the-battery-level/14961#14961

Community
  • 1
  • 1
vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
  • I am accepting this answer due to these lines in the above link. " Floating-point representations have a base (which is always assumed to be even) and a precision p. If = 2 and p = 24, then the decimal number 0.1 cannot be represented exactly, but is approximately 1.10011001100110011001101 × 2-4." I solved it by using NSNumber instead of float. – arundevma Aug 23 '12 at 14:44
  • 1
    @gladiator2345: NSNumber still uses floating-point, just with more precision than float. While changing the type may have resolved the single case you examined, floating-point issues will remain with other values. – Eric Postpischil Aug 23 '12 at 15:40
-1

%f, Float variable stores 6 values after point. When computer needs to work with float numbers then it throws those to arithmetic co-processor and there are several implications while working with float number.

To get exact answer please convert it to Int or use explicit round function or float implication solving algorithms. Best one depends on your application.

Regarding Objective-C, you can utilize NSDecimalNumber.

Md Mahbubur Rahman
  • 2,065
  • 1
  • 24
  • 36