使用C++从6个字节或更多字节创建一个整数

Cha*_*ala 2 c++ integer byte-shifting

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

我已经实现了相同的功能,4 bytes并且它正在工作

我的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);
Run Code Online (Sandbox Code Playgroud)

使用此代码的值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);
Run Code Online (Sandbox Code Playgroud)

产值value82a163c2这是不对的,我需要的42a082a12122.所以任何人都可以告诉我如何获得预期的输出以及6 Byte代码有什么问题.

提前致谢.

Max*_*hof 5

在移位之前,只需将每个字节转换为足够大的无符号类型.即使在整体促销(to 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;
}
Run Code Online (Sandbox Code Playgroud)

简单来说:

班次操作员将int/ 他们的操作数unsigned int自动地提升.这就是你的四字节版本有效的原因:unsigned int足够大,适合所有轮班.但是,(在您的实现中,与大多数常见的一样)它只能保存32位,如果您移位超过32位,编译器将不会自动选择64位类型(编译器无法知道) .

如果对移位操作数使用足够大的整数类型,则移位将具有更大的类型作为结果,并且移位将按预期执行.

如果你打开警告,你的编译器可能也会抱怨你正在移动比类型更多的位,因此总是变为零(参见演示).

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


最后一点:以双下划线(__)或下划线+大写字母开头的类型是为实现保留的 - 使用它们在技术上并不"安全".Modern C++为您提供uint64_t了应该具有指定位数的类型 - 而不是使用它们.