6

I want to covert a string to double and keep the same value:

let myStr = "2.40"
let numberFormatter = NSNumberFormatter()
numberFormatter.locale = NSLocale(localeIdentifier: "fr_FR")
let myDouble = numberFormatter.numberFromString(myStr)?.doubleValue ?? 0.0

myDouble is now

Double? 2.3999999999999999

So how to convert "2.40" to exact be 2.40 as Double ??

Update:

Even rounding after conversion does not seem to work

I don't want to print, I want to calculate and it's important that the number should be correct, it's Money calculation and rates

Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
iOSGeek
  • 5,115
  • 9
  • 46
  • 74

1 Answers1

8

First off: you don't! What you encountered here is called floating point inaccuracy. Computers cannot store every number precisely. 2.4 cannot be stored lossless within a floating point type.

Secondly: Since floating point is always an issue and you are dealing with money here (I guess you are trying to store 2.4 franc) your number one solution is: don't use floating point numbers. Use the NSNumber you get from the numberFromString and do not try to get a Double out of it.
Alternatively shift the comma by multiplying and store it as Int.

The first solutions might look something like:

if let num = myDouble {
    let value = NSDecimalNumber(decimal: num.decimalValue)
    let output = value.decimalNumberByMultiplyingBy(NSDecimalNumber(integer: 10))
}
luk2302
  • 55,258
  • 23
  • 97
  • 137
  • interesting answer, basically I will multiply the converted numbers by each other and sum them then I will display the number with 2 float precision, how to do that with NSNumber ? – iOSGeek Apr 29 '16 at 11:16
  • 1
    @iOSGeek sorry for the delayed response: I slightly edited my answer to include a little code snipper which demonstrates some calculation. Displaying the value is completely uncoupled from the floating point accuracy problem. For displaying the value you can round the values or let the `NSNumber` take care of the display which will *hopefully* display the number correctly. – luk2302 May 01 '16 at 14:09