Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BigInteger Log Issue on large numbers

The code below takes a BigInteger n and finds a number less than n that is also a power of 2. It works fine with small numbers but the first branch of the if statement does not work for int.MaxValue and above. Apparently subtracting 1 (BigInteger.Log(n - 1)) is not enough for larger numbers.

How can I calculate a number to subtract that is large enough to make a difference and yet work on smaller numbers too?

public BigInteger FindNearestPowerOfTwo (BigInteger n)
{
    double number = 0;
    BigInteger big = 0;

    if (n.IsPowerOfTwo)
    {
        number = BigInteger.Log(n - 1) / BigInteger.Log(2);
    }
    else
    {
        number = BigInteger.Log(n) / BigInteger.Log(2);
    }

    number = Math.Floor(number);

    big = BigInteger.Pow(2, (int) number);

    return (big);
}
like image 334
Raheel Khan Avatar asked May 30 '26 11:05

Raheel Khan


1 Answers

You can use ToByteArray to get an explicit representation, then clear all bits but the highest one.

public BigInteger FindNearestPowerOfTwo (BigInteger n) {
    Byte[] a = n.ToByteArray();
    int len = a.Length;
    if (a[len - 1] == 0) len--; // leading zero to maintain sign
    for (int i = 0; i < len - 1; i++) a[i] = 0;
    int x = a[len - 1] & 255;
    int y = 1;
    while (x > 1) {
      x >>= 1;
      y <<= 1;
    }
    a[len - 1] = y;
    return new BigInteger(a);
}
like image 174
Keith Randall Avatar answered May 31 '26 23:05

Keith Randall



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!