根据文档 here , Swift 3/4 Decimal 类型是桥接到 NSDecimalNumber 的以 10 为基数的表示。但是,我遇到了使用 NSDecimalNumber 时不会重现的精度问题。
let dec24 = Decimal(integerLiteral: 24)
let dec1 = Decimal(integerLiteral: 1)
let decResult = dec1/dec24*dec24
// prints 0.99999999999999999999999999999999999984
let dn24 = NSDecimalNumber(value: 24)
let dn1 = NSDecimalNumber(value: 1)
let dnResult = dn1.dividing(by: dn24).multiplying(by: dn24)
// prints 1
Decimal 结构不应该是准确的,还是我误解了什么?
最佳答案
NSDecimalNumber
(及其覆盖类型 Decimal
)can represent
... any number that can be expressed as
mantissa x 10^exponent
wheremantissa
is a decimal integer up to 38 digits long, andexponent
is an integer from –128 through 127.
因此小数(最多 38 位小数)可以表示
确切地说,但不是任意数字。特别是 1/24 = 0.416666666...
有无限多个小数位(repeating decimal)并且不能
完全表示为 Decimal
。
Decimal
和 NSDecimalNumber
之间也没有精度差异。如果我们打印差异,那将变得很明显
实际结果与“理论结果”之间:
let dec24 = Decimal(integerLiteral: 24)
let dec1 = Decimal(integerLiteral: 1)
let decResult = dec1/dec24*dec24
print(decResult - dec1)
// -0.00000000000000000000000000000000000016
let dn24 = NSDecimalNumber(value: 24)
let dn1 = NSDecimalNumber(value: 1)
let dnResult = dn1.dividing(by: dn24).multiplying(by: dn24)
print(dnResult.subtracting(dn1))
// -0.00000000000000000000000000000000000016
关于Swift 的小数精度问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47328916/