c++ - 使用 C++ 从 6 个字节或更多字节生成一个整数

标签 c++ integer byte-shifting

我是 C++ 编程新手。我正在尝试实现一个代码,通过它我可以从 6 或更多 individual bytes 中生成单个整数值。

我已经为 4 个字节 实现了同样的功能,并且它正在工作

我的 4 字节代码:

char *command = "\x42\xa0\x82\xa1\x21\x22";
__int64 value;
value = (__int64)(((unsigned char)command[2] << 24) + ((unsigned char)command[3] << 16) + ((unsigned char)command[4] << 8) + (unsigned char)command[5]);
printf("%x  %x  %x  %x  %x",command[2], command[3], command[4], command[5], value);

使用此代码,value 的值是 82a12122 但是当我尝试对 6 字节执行操作时,结果是错误的。

6 字节代码:

char *command = "\x42\xa0\x82\xa1\x21\x22";
__int64 value;
value = (__int64)(((unsigned char)command[0] << 40) + ((unsigned char)command[1] << 32) + ((unsigned char)command[2] << 24) + ((unsigned char)command[3] << 16) + ((unsigned char)command[4] << 8) + (unsigned char)command[5]);
printf("%x  %x  %x  %x  %x  %x  %x", command[0], command[1], command[2], command[3], command[4], command[5], value);

value的输出值为82a163c2,这是错误的,我需要42a082a12122。 那么谁能告诉我如何获得预期的输出以及 6 Byte 代码有什么问题。

提前致谢。

最佳答案

在移位之前,只需将每个字节转换为足够大的无符号类型。即使经过整数提升(到 unsigned int),该类型也不足以移动超过 32 个字节(在通常情况下,这似乎适用于您)。

演示请看这里:https://godbolt.org/g/x855XH

unsigned long long large_ok(char x)
{
    return ((unsigned long long)x) << 63;
}

unsigned long long large_incorrect(char x)
{
    return ((unsigned long long)x) << 64;
}


unsigned long long still_ok(char x)
{
    return ((unsigned char)x) << 31;
}

unsigned long long incorrect(char x)
{
    return ((unsigned char)x) << 32;
}

简单来说:

移位运算符自动将其操作数提升为 int/unsigned int。这就是您的四字节版本有效的原因:unsigned int 足够大,适合您的所有类次。但是,(在您的实现中,与最常见的实现一样)它只能容纳 32 位,如果您移动超过 32 位,编译器将不会自动选择 64 位类型(编译器不可能知道) .

如果您为移位操作数使用足够大的整数类型,则移位将具有较大的类型作为结果,并且移位将按照您的预期进行。

如果您打开警告,您的编译器可能还会向您提示您移动的位数多于类型的位数,因此总是得到零(参见演示)。

(提到的位数当然是实现定义的。)


最后一点:以双下划线 (__) 或下划线 + 大写字母开头的类型保留用于实现 - 使用它们在技术上并不“安全”。现代 C++ 为您提供了诸如 uint64_t 之类的类型,它们应该具有规定的位数 - 请改用这些类型。

关于c++ - 使用 C++ 从 6 个字节或更多字节生成一个整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51730450/

相关文章:

c++ - 搜索链表和数组时有什么区别?

ios - 使用 Swift 将字符串转换为 Int

assembly - MIPS - 按数值移位寄存器值

c++ - 将 Lua 文件添加到 C++ 程序

c++ - 如何将项目从 boost::variant 移动到 multimap ?

c++ - 使用 C++ WinAPI 在 Windows 10 上设置亮度

java - 卡住一个整数

python - 计算python中的最大公分母

将 24 位 RGB 转换为 ARGB16

endianness - stm32 微 Controller 上的字节顺序函数