Reputation: 2210
Can someone tell me why this happening?
let formatter = NumberFormatter.init()
formatter.numberStyle = .decimal
formatter.usesGroupingSeparator = false
formatter.roundingMode = .floor
formatter.minimumFractionDigits = 2
formatter.maximumFractionDigits = 2
let v = 36
let scale = 10
let float = formatter.string(from: NSNumber(value: Float(v) / Float(scale)))!
let double = formatter.string(from: NSNumber(value: Double(v) / Double(scale)))!
print(float) // 3.59
print(double) // 3.60
When I use Float
the result is 3.59 (wrong result in my opinion) and when I use Double
the result is 3.60.
I know it is something related to .floor
roundingMode, but i don't fully understand the reason.
Upvotes: 0
Views: 497
Reputation: 236360
If you would like to preserve your fraction digits precision it is better to use Swift native Decimal type. That's what it is. You can use the Decimal init(sign: FloatingPointSign, exponent: Int, significand: Decimal)
initializer and use your scale exponent and your value significand. Just make sure to negate its value:
extension SignedInteger {
var negated: Self { self * -1 }
}
let v = 36
let scale = 10
let sign: FloatingPointSign = v >= 0 ? .plus : .minus
let exponent = Decimal(scale).exponent.negated
let significand = Decimal(v).significand
let decimal = Decimal.init(sign: sign, exponent: exponent, significand: significand)
let formatted = formatter.string(for: decimal) // "3.60"
Upvotes: 1