I found that making operand in Decimal can reduce numeric error in Swift
0.1 0.2 = 0.30000000000000004
Decimal(0.1) Decimal(0.2) = 0.3
So I tried to make a function that calculate calculation String in Decimal like this:
func calculate(expression: String) -> Decimal {
let expression = NSExpression(format: expression)
let value = expression.expressionValue(with: nil, context: nil) as? Decimal
return value ?? 0.0
}
But value property keep getting nil value and function always returning 0.0. Can I get some any help on this?
Thanks
CodePudding user response:
The Decimal type does not reduce numeric error. It just computes values in decimal. That can increase or decrease error, depending on the calculation. 1/10 happens to be bad in binary for the same reason that 1/3 is bad in decimal. Your code doesn't actually compute anything in Decimal. It's just trying to convert the final Double value to Decimal at the end, which introduces binary-to-decimal rounding (making it less accurate).
That said, expressionValue(with:context:)
returns an NSNumber. You can't convert that to Decimal with as?
. You need to use .decimalValue
:
let number = expression.expressionValue(with: nil, context: nil) as? NSNumber
let value = number?.decimalValue
This will compute the value in Double and then round it to a Decimal.
But if you want to do calculations in Decimal, I don't believe that NSExpression can do that.