Standard casts from BigInteger
to fixed-size integer all throw OverflowException
if the number is too large (and unchecked
doesn't work).
How can I get unchecked
-like conversion behavior?
CodePudding user response:
You can truncate a BigInteger
by masking off the higher bits. For example, given a BigInteger big
:
- Convert to
uint
with(uint)(big & uint.MaxValue)
- Convert to
ulong
with(ulong)(big & ulong.MaxValue)
- Convert to
int
withunchecked((int)(uint)(big & uint.MaxValue))
- Convert to
long
withunchecked((long)(ulong)(big & ulong.MaxValue))
This technique is not efficient; it requires two memory allocations (one to convert e.g. uint.MaxValue
to BigInteger
, and another to hold the result of the &
operation). But I don't see any other way. Memory allocations are avoided, however, when the mask is smaller than 32 bits (e.g. converting to ushort
with (ushort)(big & ushort.MaxValue)
should not allocate memory) because BigInteger
does not allocate memory for numbers that are 31 bits or smaller.
CodePudding user response:
A faster approach:
public static int ToInt(this BigInteger big) {
return BitConverter.ToInt32(big.ToByteArray().AsSpan(0, 4)); }
Solutions for long
, uint
, etc. are straightforward.