0

I seem to be getting a more precise version of a double value for certain numbers.

For example, 69.55554, when assigned to a double variable is saved as 69.555539999999993

I have even tried using NSNumber and NSDecimalNumber instead, to no avail. I'm using swift and haven't tested out the same using objective-c.

Any idea on why this occurs and how to fix it (or work around it)? Thanks!

Code Sample where I used NSDecimalNumber

var doubleNumber  : Double  =   69.55554
var decimalNumber           =   NSDecimalNumber(double: doubleNumber)

var label   =   UILabel(frame: CGRectMake(10, 20, 200, 40))
label.text  =   "\(decimalNumber.doubleValue)"
self.view.addSubview(label)
Sparr
  • 361
  • 1
  • 12
  • Can you show us the code sample where you used NSDecimalNumber ? – vib May 29 '15 at 08:41
  • 1
    [What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html). – Martin R May 29 '15 at 09:01
  • NSDecimalNumber should be the way to address this issue though. I guess it was not used properly. – vib May 29 '15 at 09:02
  • @vib I had initialized the NSDecimalNumber with a convenience initializer - NSDecimalNumber(double : doubleNumber) and used decimalNumber.doubleValue to get the value. Is there something i can do here? – Sparr May 29 '15 at 09:43
  • 1
    @Sparr: How do you suppose is that going to help? Double has about 15 significant digits. It cannot represent the number you want it to represent. So doubleNumber isn't and can't be what you want. By moving it to an NSDecimalNumber, you initialise the NSDecimalNumber with the same value that you didn't want in the first place. Even if you somehow managed to get the exact value that you want into the NSDecimalNumber, by calling doubleValue all that work would be undone. – gnasher729 May 29 '15 at 10:50
  • @gnasher729 I clearly am not well versed with this. I tried multiple variations in using NSDecimalNumber. I posted the code that resulted in the anomaly - or at least i thought it was. I tried initializing NSDecimalNumber with a string and the result seemed fine. But I'm not sure if that is the right way to go about doing it. Could you suggest something on this? – Sparr May 29 '15 at 11:02
  • @Sparr if you want to keep precision you should indeed initialize the NSDecimalNumber from a string. As soon as you use double you take the risk of loosing precision - something you will never recover afterwards. – vib May 29 '15 at 11:14
  • Thanks a lot. Did help me quite a bit – Sparr Jun 01 '15 at 13:27

1 Answers1

0

It is correct. It occurs due to machine precision of floating-point values.

Values are not exact, but closest possible.

0x4051638DF7A4E7AB = 69.555539999999993483470461797 < 69.55554 < 69.555540000000007694325176999 = 0x4051638DF7A4E7AC

Andrey Kuznetsov
  • 843
  • 1
  • 18
  • 29