Ajout de chiffres de grands nombres entiers dans PowerShell
-
03-07-2019 - |
Question
Lors de l'ajout des chiffres d'un nombre dans PowerShell, tout va bien pour les entiers dont la longueur est égale à 29.
$largeInteger = 11111111111111111111111111111 #29 digits sums correctly $sumDigits = 0 $largeInteger while ($largeInteger -ne 0) { $sumDigits += $largeInteger % 10 $largeInteger = [MATH]::Floor($largeInteger /10) } $sumDigits
Ça devient intéressant quand la longueur du nombre -gt 29. Dans le cas où la longueur est 30, la somme = 77.
Des idées?
La solution
Vous devrez installer une bibliothèque bignum. Il existe des pointeurs ici . Soit ça, soit utilisez une plate-forme intégrant des bignums.
Autres conseils
Vous avez un doublé survolé qui est traité comme un cas spécial par Powershell. Vous pouvez essayer $ largeInteger = [float] 11111111111111111111111111111111
. Vous perdrez encore un peu de précision avec un float.
Pour plus d'informations, voir float (référence C #)
La modification de largeInteger de 29 1 à 30 1 modifie le type de la variable de décimale à double. Utilisez $ largeInteger.GetType () pour voir cela.
Les maths de l'algorithme ne fonctionnent pas si bien sur les doubles. Exécutez les 2 lignes de la boucle à plusieurs reprises sur l'invite pour afficher les valeurs de chaque étape.
Une fois que largeInteger est passé de décimal à double, l’arithmétique n’est plus précise. C'est pourquoi j'ai suggéré d'exécuter les 2 lignes de l'invite.
Voici la sortie -
PS C: > $ largeInteger% [double] 10
8
PS C: > $ largeInteger% [double] 100
88
PS C: > $ largeInteger% [double] 1000000000000000000
1.11105501764518E + 17
PS C: > $ largeInteger% [double] 1000000000000000000000000
1.11111105501765E + 20
PS C: > $ largeInteger% [double] 1000000000000000000000000000000
1.11111111111104E + 26
PS C: > $ largeInteger% [double] 100000000000000000000000000000000
1.11111111111111E + 28
PS C: > $ largeInteger% [double] 10000000000000000000000000000000000
1.11111111111111E + 29
Vous pouvez voir la distorsion résultant de la représentation imprécise interne du double qui ne peut pas être représentée avec précision en binaire. Au fur et à mesure que le diviseur augmente, la précision du reste augmente également.