给定一个整数值,我需要一些方法来找出存储该值所需的最小字节数。该值可以是有符号或无符号,最多为64位。还要将符号位考虑为有符号整数。
例如:
8 requires 1 byte at minimum
unsigned 255 requires 1 byte at minimum
signed 255 requires 2 bytes at minimum
4351 requires 2 bytes at minimum
-4294967296 requires 5 bytes at minimum
unsigned 0xFFFFFFFFFFFFFFFF requires 8 bytes at minimum
我可以想到一种快速而肮脏的方法来解决这个问题,使用许多if语句,但可能有更好的方法(例如更简单,更聪明,更快)。您可以假定使用签名int (long value, bool signed)
的方法或两种方法int (long value)
(用于签名)和int (ulong value)
(用于无符号)。
答案 0 :(得分:2)
让我试一试自己的问题。据我所知,这是一个正确的解决方案,但它在速度,简洁方面可能不是最佳的:
public static int GetMinByteSize(long value, bool signed)
{
ulong v = (ulong)value;
// Invert the value when it is negative.
if (signed && value < 0)
v = ~v;
// The minimum length is 1.
int length = 1;
// Is there any bit set in the upper half?
// Move them to the lower half and try again.
if ((v & 0xFFFFFFFF00000000) != 0)
{
length += 4;
v >>= 32;
}
if ((v & 0xFFFF0000) != 0)
{
length += 2;
v >>= 16;
}
if ((v & 0xFF00) != 0)
{
length += 1;
v >>= 8;
}
// We have at most 8 bits left.
// Is the most significant bit set (or cleared for a negative number),
// then we need an extra byte for the sign bit.
if (signed && (v & 0x80) != 0)
length++;
return length;
}
答案 1 :(得分:1)
static int BytesForNum(long value, bool signed)
{
if (value == 0)
return 1;
if (signed)
{
if (value < 0)
return CalcBytes(2 * (-1-value));
else
return CalcBytes(2 * value);
}
else
{
if (value < 0)
throw new ArgumentException("Can't represent a negative unsigned number", "value");
return CalcBytes(value);
}
}
//should only be called with positive numbers
private static int CalcBytes(long value)
{
int bitLength = 0;
while (value > 0)
{
bitLength++;
value >>= 1;
}
return (int)(Math.Ceiling(bitLength * 1.0 / 8));
}
我可能没有完全正确的签名代码,但这是一般的想法。