查找特定整数的最大位数

Finding the maximum number of bits for a specific integer

好的伙计们,我完全陷入了这个我花了几个小时试图研究和弄清楚的小问题。基本上我所要做的就是找到一个整数的最大位数(使用一个字节作为限制)。我正在尝试做的一个例子是:int 5 会显示为 8,因为在一个字节中它被存储为 0000 0101。所有大于等于 255 并包括 255 的都应该输出 8。一旦达到 256,它应该输出16 因为它将存储为 0001 0000 0000 。我可以使用 if 语句,但是有没有更简单的方法使用日志来做到这一点?

目前我只有:

    int x = 5;
    int len = (Integer.toString(x)).length();
    double bits = Math.ceil(len*(Math.log(10)/Math.log(2)));
    System.out.println(bits);

试试这个:

int bytesNeeded(int x) {
    int bytes = 0;
    for (; x != 0; bytes++) {
        x >>>= 8; // Shift 8 bits (1 byte) right
        bytes++; // Count 1 more byte
    }
    return bytes;
}

x >>> y,会将x右移y个字节,并在左侧插入0。例如,0b00000001 >>> 1 => 0b000000000b11110000 >>> 2 => 0b00111100。此函数将 x 向下移动,一次移动 1 个字节,直到没有剩余的 1。它必须移动的次数就是它需要表示多少字节。

编辑:切换到 >>> 运算符来处理负数。

一个非常简单的方法:

final double DIVISOR = Math.log(256);

int x = 5;
double bytes = Math.log(x) / DIVISOR;
int bits = (int) Math.ceil(bytes) * 8;

这通过计算 base 256 中的位数来计算数字的字节数(包括部分字节)。这使用了两个技巧:

  • 基数 n 中的数字 x 的位数由 logn[=31= 给出](x).
  • logn(x) 等价于logm(x)/logm(n) 对于任何 m.

然后将结果四舍五入(以处理任何部分字节),并乘以 8 得到位数。

但是请注意,这不一定是一种非常有效的方法。有可能使用位操作的更有效的方法,但可能更难理解。至少,此方法看起来与您已经尝试过的类似。

也可以使用递归:

int getNumberOfBytes(int number) {
    if((int)(number / 256) == 0) {
        return 1;
    }

    return getNumberOfBytes(number / 256) + 1;
}