I need a single variable which can store a 128-bit, unsigned integer. The largest type that Powershell recognizes, however, is UInt64. Is it possible to define a UInt128, or even UInt256 variable?
For context, I'm using Powershell 7.2.0.
CodePudding user response:
From your comments:
I want to find prime numbers within the Fibonacci sequence, which is why I need such a large integer size
For this, [bigint]
(type accelerator for the System.Numerics.BigInteger
type) is what you want - it doesn't have any upper boundary and is designed specifically for doing integer aritmetic with large values - exactly the kind of thing you need when hunting for primes!
[...] most Powershell functions, especially those in [Math], aren't made for BigInteger.
The good news is the [bigint]
brings its own!
Here's how you could implement a simple (and slow) recursive Fibonacci generator with [bigint]
:
function Get-FibonacciTerm {
param(
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[int]$N
)
process {
if($N -lt 1){ return [bigint]::Zero }
if($N -lt 3){ return [bigint]::One }
return (Get-FibonacciTerm -N ($N-1)) (Get-FibonacciTerm -N ($N-2))
}
}
PS ~> 1..12 |Get-FibonacciTerm
1
1
2
3
5
8
13
21
34
55
89
144
As you might have noticed, basic arithmetic operators like
is overloaded by [bigint]
and therefore works exactly as you'd expect "out of the box".
In addition, [bigint]
provides a set of static helper methods to provide cognates to most of the static [math]
functions. Here's a simple (and again, fairly slow/inefficient) Prime generator/tester using some of them:
function Get-PrimeNumber {
param(
[bigint]$Below = 1000
)
for($i = [bigint]::Zero; $i -lt $Below; $i = [bigint]::Add($i, [bigint]::One)){
if($i -le 1){ continue }
if([bigint]::Remainder($i, 2) -eq 0){
if($i -eq 2){ $i }
continue
}
$foundFactor = $false
for($j = 3; $j -lt $i; $j = [bigint]::Add($j, 2)){
if([bigint]::Remainder($i, $j) -eq 0){
$foundFactor = $true
break
}
}
if(-not $foundFactor){ $i }
}
}
PS ~> Get-PrimeNumber -Below 100
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
Now, the first optimization you might want to make here is to only search up until the root of $i
in the inner loop. This is where [bigint]
starts to diverge from [math]
- there's no built-in Sqrt()
function!
Luckily, you can roll your own :)
In conclusion:
- For large integer arithmetic,
[bigint]
is definitely your friend - It doesn't quite have complete feature parity with builtin integral types, but supports basic arithmetic operations
I see now that a scripting language may not be the best bet for a use case such as this
I wouldn't be so quick to dismiss the entire category of "scripting languages" - PowerShell is not necessarily a good fit for this use case, because optimization of large integer math has never been a major priority in neither PowerShell nor .NET - but there are other languages out there better suited because they've been optimized for it.
Python (>=3.x) natively supports unbounded numbers and is generally much faster for arithmetic operations than PowerShell. JavaScript also has support for a BigInt
type similar to [bigint]
for numbers >2^53, also surprisingly fast.