stahler
stahler

Reputation: 94

Adding digits of large integers in PowerShell

When adding the digits of a number in PowerShell, all is well with integers that have a length -le 29.

$largeInteger = 11111111111111111111111111111 #29 digits sums correctly
$sumDigits = 0
$largeInteger
while ($largeInteger -ne 0)
{
    $sumDigits += $largeInteger  % 10
    $largeInteger  = [MATH]::Floor($largeInteger /10)   
}

$sumDigits

Things get interesting when the length of the number -gt 29. In the case where the length is 30, the sum = 77.

Any ideas?

Upvotes: 0

Views: 1911

Answers (4)

Mohit Chakraborty
Mohit Chakraborty

Reputation: 1263

Changing largeInteger from 29 1's to 30 1's changes the type of the variable from Decimal to Double. Use $largeInteger.GetType() to see that.

The math in the algorithm does not work so fine on doubles. Run the 2 lines in the loop repeatedly on the prompt to see the values in each step.

Once largeInteger goes from decimal to double, the arithmetic is not precise any more. That is why I suggested runnning the 2 lines on the prompt.

Here is the output -

PS C:\> $largeInteger  % [double]10<br/>
8<br/>
PS C:\> $largeInteger  % [double]100<br/>
88<br/>
PS C:\> $largeInteger  % [double]1000000000000000000<br/>
1.11105501764518E+17<br/>
PS C:\> $largeInteger  % [double]1000000000000000000000<br/>
1.11111105501765E+20<br/>
PS C:\> $largeInteger  % [double]1000000000000000000000000000<br/>
1.11111111111104E+26<br/>
PS C:\> $largeInteger  % [double]100000000000000000000000000000<br/>
1.11111111111111E+28<br/>
PS C:\> $largeInteger  % [double]1000000000000000000000000000000<br/>
1.11111111111111E+29<br/>

You can see the distortion that occurs due to the internal imprecise representation of the double which cannot be accurately represented in binary. As the divisor increases the accuracy of the increasing remainder also improves.

Upvotes: 0

Ravikumar B
Ravikumar B

Reputation: 892

This should help ($largeInteger -split '' | measure -sum).Sum

Upvotes: 0

dan-gph
dan-gph

Reputation: 16909

You will have to install a bignum library. There are some pointers here. Either that or use a platform that has bignums built in.

Upvotes: 2

Dustin Venegas
Dustin Venegas

Reputation: 759

You have an over flown double that is being handled as a special case by Powershell. You might try $largeInteger = [float]111111111111111111111111111111. You will still lose some precision using a float.

For more information, see float (C# Reference)

Upvotes: 0

Related Questions