Home > front end >  How to truncate a BigInteger to int/long/uint/ulong?
How to truncate a BigInteger to int/long/uint/ulong?

Time:01-03

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 with unchecked((int)(uint)(big & uint.MaxValue))
  • Convert to long with unchecked((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.

  • Related