NSDecimalNumber的数学完整性

我使用的数字除以10 ^ 30

我可能会添加存储在NSDecimalNumber的值1000000000000000和5000000000000000。

我担心的是,我认为我已经看过几次,当添加或减去这些值时,不正确的数学运算。

这是一种可能性还是NSDecimalNumbers在数学的完整性方面非常合理。

在回答你的问题时, Decimal / NSDecimalNumber提供的数学是合理的,问题可能在于:

  1. 计算可能超过这些十进制格式的容量(如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

  2. 或者,它可能只是你如何实例化这些十进制值,例如提供浮点数而不是使用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

底线,不要将浮点数提供给DecimalNSDecimalNumber 。 使用字符串表示或使用指数和尾数/有效数表示,使用浮点数时不会看到这些奇怪的偏差。

我使用的数字除以1 ^ 30

好消息,因为1 ^ 30 = 1.也许你的意思是10 ^ 30?

无论如何,根据NSDecimalNumber类引用 :

实例可以表示可以表示为尾数x 10 ^指数的任何数字,其中尾数是长度为38位的十进制整数,指数是-128到127的整数。