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

问题描述 投票:0回答:3

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

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

问题在于,这不适用于任何负数(我无法确定原因)或某些最高有效位为 0 的正数(因为符号位是使其变大一位的位) )...关于如何解释这些情况,我可以获得任何提示或建议吗?

c++ bit-manipulation bitwise-operators
3个回答
1
投票

存储为单个字节,
正数的范围是

0x00
0x7F

负数的范围是
0x80
0xFF

作为 2 字节,
正数的范围是

0x0000
0x7FFF

负数的范围是
0x8000
0xFFFF

作为 4 字节,
正数的范围是

0x00000000
0x7FFFFFFF

负数的范围是
0x80000000
0xFFFFFFFF

您可以使用如下函数来获取最小尺寸:

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
应翻译为正数。

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


0
投票

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

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

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;

如果您使用 gcc,另一种选择是使用

__builtin_clz()
。这将返回前导零,然后您可以使用它来确定最小字节数。


0
投票
#include <algorithm>
#include <bit>

constexpr unsigned int
byte_width(const size_t x)
{
    // std::bit_width(0) returns 0, but we want it to be 1
    const unsigned int w = std::max(std::bit_width(x), 1);
    return (w / 8) + (w % 8 != 0);
}
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.