计算表示有符号整数所需的最小字节数

Counting Minimum Number of Bytes Required to Represent a Signed Integer

本文关键字:字节数 表示 符号 整数 计算      更新时间:2023-10-16

我的任务看起来很简单,我需要计算表示变量整数所需的最小字节数(例如,如果整数是 5,那么我想返回 1;如果整数是 300,我想返回 2(。不是指数据类型 int,正如注释中指出的那样,它总是只是 sizeof(int(,我指的是一个数学整数。 我几乎有一个解决方案。这是我的代码:

int i;
cin >> i;
int length = 0;
while (i != 0) {
    i >>= 8;
    length++;
}

问题是这不适用于任何负数(我无法确定原因(或一些正数,其中最高有效位是 0(因为符号位是使其大一点的位(......在如何解释这些案件方面,我能得到任何提示或建议吗?

存储为单个字节,
正数在 0x000x7F
的范围内负数在 0x800xFF
的范围内

作为 2 个字节,
正数在 0x00000x7FFF
的范围内负数在 0x80000xFFFF
的范围内

作为 4 字节,
正数在 0x000000000x7FFFFFFF
的范围内负数在 0x800000000xFFFFFFFF
的范围内

可以使用如下所示的函数来获取最小大小:

int getmin(int64_t i)
{
    if(i == (int8_t)(i & 0xFF))
        return 1;
    if(i == (int16_t)(i & 0xFFFF))
        return 2;
    if(i == (int32_t)(i & 0xFFFFFFFF))
        return 4;
    return 8;
}

然后例如,当您看到 0x80 时,将其转换为 -128 。当7F被翻译成127时,0x801应该被翻译成正数。

请注意,这将是非常困难且毫无意义的,应该避免。这不允许以三重字节存储数字,为此,您必须制定自己的格式。

在 2 的补码中 可以存储在 x 字节中的有符号数字的范围是 -2^(8*x-1( 到 2^(8*x-1(-1。例如,1 字节可以存储从 -128 到 127 的有符号整数。您的示例会错误地计算只需要 1 个字节来表示 128(如果我们谈论的是有符号数字(,因为右移 8 等于零,但需要最后一个字节才能知道这不是负数。

为了处理负数,将其转换为正数并减去一个(因为负数可以存储额外的值(将允许您右移。

int i;
cin >> i;
unsigned bytes = 1;
unsigned max = 128;
if (i < 0) {
    i = ~i; //-1*i - 1
}
while(max <= i) {    
    i >>= 8;
    bytes++;
}
cout << bytes;

另一种选择是使用 __builtin_clz() 如果您使用的是 gcc。这将返回前导零,然后您可以使用这些零来确定最小字节数。