jos*_*405 1 double rounding ios swift
我有这个信息。
let params2: [String: AnyObject] = [
"app_token": myapptoken,
"member_access_token": accessToken!,
"pay_process": 0,
"payamount_credit": 9.87 //hardcode
]
Run Code Online (Sandbox Code Playgroud)
打印时params2
结果是
["app_token": myapptoken, "member_access_token": accessToken, "payamount_credit": 9.869999999999999, "pay_process": 0]
现在"payamount_credit": 9.87是"payamount_credit": 9.869999999999999
我已经尝试了周围存在的所有方法,但行为相同。
NSString(format: "%.\2f", 9.87)
Double(round(1000*9.87)/1000)
最奇怪的是,只有这个特定数字(9.87)才会发生这种情况,这是一种神秘的事情。
游乐场屏幕。
不要使用浮点数或双精度数来表示货币,正是出于这个原因(双关语)。请改用 NSDecimalNumber (请参阅我对货币使用哪种 Swift 数据类型)。
NSDecimalNumber 使用起来需要一些努力,但它确实执行以 10 为基数的算术。要正确使用它,您必须阅读一些有关 API 的内容。特别是,要进行舍入,您需要提供一个 NSDecimalNumberHandler (您可以设置一个默认值来使用)。
值得一读的好东西:
我认为Playground 显示了意外的结果,因为它在显示之前将 NSDecimalNumber 的内部值强制为 Double (我欢迎其他或权威的解释,因为我确实觉得这很好奇)。然而,内部表示应该是正确的。
在你的 Playground 中尝试一下:
let myRoundingBehavior = NSDecimalNumberHandler(roundingMode: .RoundBankers,
scale: 2, raiseOnExactness: true, raiseOnOverflow: true, raiseOnUnderflow: true, raiseOnDivideByZero: true)
NSDecimalNumber.setDefaultBehavior(myRoundingBehavior)
let integerPrice = NSDecimalNumber(mantissa: 987, exponent: -2, isNegative: false)
integerPrice // 9.870000000000001
Float(integerPrice) // 9.87
Double(integerPrice) // 9.870000000000001
integerPrice.description // "9.87"
Run Code Online (Sandbox Code Playgroud)
不要认为 Float 是数字的更准确表示,它只是恰好在这里工作得更好。如果您将计算(如税费、折扣、运费等)保留在 NSDecimalNumber 领域中,它们将是准确的。
Swift 3 / Xcode beta 1 奖励:
Playground 行为仍然相同,但更改了 Great API Renaming Rodeo 将上述代码更改为:
let myRoundingBehavior = NSDecimalNumberHandler(roundingMode: .roundBankers,
scale: 2,
raiseOnExactness: true,
raiseOnOverflow: true,
raiseOnUnderflow: true,
raiseOnDivideByZero: true)
Run Code Online (Sandbox Code Playgroud)
这里的变化是全局 NSRoundingMode 枚举消失,并被 NSDecimalNumber 成员枚举 RoundingMode 取代。
问题出在数字精度Double上,简单地说,有些数字不能在不损失精度的情况下定义为 a 。
相反,您应该使用NSDecimalNumber:
let num = NSDecimalNumber(string: "9.87")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2725 次 |
| 最近记录: |