题
在PowerShell中添加数字的数字时,对于长度为-le 29的整数,一切都很好。
$largeInteger = 11111111111111111111111111111 #29 digits sums correctly $sumDigits = 0 $largeInteger while ($largeInteger -ne 0) { $sumDigits += $largeInteger % 10 $largeInteger = [MATH]::Floor($largeInteger /10) } $sumDigits
当数字长度为-gt 29时,事情变得有趣。在长度为30的情况下,总和= 77。
有什么想法吗?
解决方案
您必须安装bignum库。有这里的一些指示。或者使用内置bignums的平台。
其他提示
你有一个过度飞行的双人被Powershell作为特例处理。您可以尝试 $ largeInteger = [float] 111111111111111111111111111111
。使用浮点数仍然会失去一些精度。
有关详细信息,请参阅 float(C#参考)
将largeInteger从29 1更改为30 1将变量的类型从Decimal更改为Double。 使用$ largeInteger.GetType()来查看。
算法中的数学运算在双精度数上不起作用。在提示符中重复运行循环中的2行,以查看每个步骤中的值。
一旦largeInteger从十进制变为双精度,算术就不再精确了。这就是为什么我建议在提示符上运行2行。
这是输出 -
PS C:> $ largeInteger%[double] 10
8点击
PS C:> $ largeInteger%[double] 100
88个结果
PS C:> $ largeInteger%[double] 1000000000000000000
1.11105501764518E + 17点击
PS C:> $ largeInteger%[double] 1000000000000000000000
1.11111105501765E + 20点击
PS C:> $ largeInteger%[double] 1000000000000000000000000000
1.11111111111104E + 26点击
PS C:> $ largeInteger%[double] 100000000000000000000000000000
1.11111111111111E + 28点击
PS C:> $ largeInteger%[double] 1000000000000000000000000000000
1.11111111111111E + 29,点击
您可以看到由于双精度的内部不精确表示而发生的失真,无法用二进制精确表示。随着除数的增加,增加的余数的准确性也会提高。