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);
}
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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With