NSDecimalNumber的数学完整性
我使用的数字除以10 ^ 30
我可能会添加存储在NSDecimalNumber
的值1000000000000000和5000000000000000。
我担心的是,我认为我已经看过几次,当添加或减去这些值时,不正确的数学运算。
这是一种可能性还是NSDecimalNumbers
在数学的完整性方面非常合理。
在回答你的问题时, Decimal
/ NSDecimalNumber
提供的数学是合理的,问题可能在于:
-
计算可能超过这些十进制格式的容量(如rob mayoff所述)。 例如,这是有效的,因为我们在38位数的尾数内:
let x = Decimal(sign: .plus, exponent: 60, significand: 1) let y = Decimal(sign: .plus, exponent: 30, significand: 1) let z = x + y
1,000,000,000,000,000,000,000,000,000,001,000,000,000,000,000,000,000,000,000,000
但这不会:
let x = Decimal(sign: .plus, exponent: 60, significand: 1) let y = Decimal(sign: .plus, exponent: 10, significand: 1) let z = x + y
1,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000
-
或者,它可能只是你如何实例化这些十进制值,例如提供浮点数而不是使用
Decimal(sign:exponent:significand:)
或NSDecimalNumber(mantissa:exponent:isNegative:)
初始值设定项:例如,这很好用:
let formatter = NumberFormatter() formatter.numberStyle = .decimal let x = Decimal(sign: .plus, exponent: 30, significand: 1) print(formatter.string(for: x)!)
这导致:
1,000,000,000,000,000,000,000,000,000,000
但是这些不会,因为你提供的浮点数在精度上有较低的限制:
let y = Decimal(1.0e30) print(formatter.string(for: y)!) let z = Decimal(1_000_000_000_000_000_000_000_000_000_000.0) print(formatter.string(for: z)!)
这些都导致:
1,000,000,000,000,000,409,600,000,000,000
有关浮点运算的更多信息(以及为什么在浮点类型中无法完美捕获十进制数),请参阅浮点运算 。
在你的另一个问题中 ,你问为什么以下:
let foo = NSDecimalNumber(value: 334.99999).multiplying(byPowerOf10: 30)
制作:
334999990000000051200000000000000
这与我在上面第2点中概述的基本问题相同。浮点数不能准确地表示某些十进制值。
请注意,您的问题与以下Decimal
表达式相同:
let adjustment = Decimal(sign: .plus, exponent: 30, significand: 1) let foo = Decimal(334.99999) * adjustment
这也产生:
334999990000000051200000000000000
但是,如果提供字符串或指数以及尾数/ NSDecimalNumber
您将得到所需的结果,因为这些将准确地表示为Decimal
/ NSDecimalNumber
:
let bar = Decimal(string: "334.99999")! * adjustment let baz = Decimal(sign: .plus, exponent: -5, significand: 33499999) * adjustment
这些都产生:
334999990000000000000000000000000
底线,不要将浮点数提供给Decimal
或NSDecimalNumber
。 使用字符串表示或使用指数和尾数/有效数表示,使用浮点数时不会看到这些奇怪的偏差。
我使用的数字除以1 ^ 30
好消息,因为1 ^ 30 = 1.也许你的意思是10 ^ 30?
无论如何,根据NSDecimalNumber
类引用 :
实例可以表示可以表示为尾数x 10 ^指数的任何数字,其中尾数是长度为38位的十进制整数,指数是-128到127的整数。