在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。
有什么想法吗?
答案 0 :(得分:2)
您必须安装bignum库。有some pointers here。或者使用内置bignums的平台。
答案 1 :(得分:0)
将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个
您可以看到由于双精度的内部不精确表示而发生的失真,无法用二进制精确表示。随着除数的增加,增加的余数的准确性也会提高。
答案 2 :(得分:0)
你有一个过度飞行的双人被Powershell作为特例处理。您可以尝试$largeInteger = [float]111111111111111111111111111111
。使用浮点数仍然会失去一些精度。
有关详细信息,请参阅float (C# Reference)
答案 3 :(得分:0)
这应该有助于($largeInteger -split '' | measure -sum).Sum