可包含整数值的最小字节数

给定一个整数值,我需要一些方法来找出存储该值所需的最小字节数。 该值可以是有符号或无符号的,最多为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, bool signed)或两个方法int (long value) (用于signed)和int (ulong value) (用于unsigned)。

让我试一试自己的问题。 据我所知,这是一个正确的解决方案,但它在速度,简洁方面可能不是最佳的:

 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; } 
 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)); } 

我可能没有完全正确的签名代码,但这是一般的想法。