Добавление цифр больших целых чисел в PowerShell
-
03-07-2019 - |
Вопрос
При добавлении цифр числа в 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
Все становится интереснее, когда длина числа равна 29.В случае, когда длина равна 30, сумма = 77.
Есть идеи?
Решение
Вам придется установить библиотеку bignum.Есть некоторые указатели здесь.Либо так, либо используйте платформу со встроенными bignums.
Другие советы
У вас есть перелетный дубль, который Powershell обрабатывает как особый случай.Вы можете попробовать $largeInteger = [float]111111111111111111111111111111
.Вы все равно потеряете некоторую точность, используя число с плавающей запятой.
Для получения дополнительной информации см. float (Справочник по C#)
Изменение bigInteger с 29 единиц на 30 единиц изменяет тип переменной с Decimal на Double.Используйте $largeInteger.GetType(), чтобы увидеть это.
Математические расчеты в алгоритме не так хорошо работают с двойными числами.Повторите две строки цикла в командной строке, чтобы увидеть значения на каждом шаге.
Как только значение bigInteger переходит из десятичного числа в двойное, арифметика перестает быть точной.Вот почему я предложил запустить две строки в командной строке.
Вот результат -
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
Вы можете увидеть искажение, возникающее из-за внутреннего неточного представления двойника, который невозможно точно представить в двоичном формате.По мере увеличения делителя точность возрастающего остатка также улучшается.