2

我是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);

使用此代码的值value82a12122但是当我尝试做 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);

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

提前致谢。

4

2 回答 2

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;
}

简单来说:

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

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

如果您打开警告,您的编译器可能还会向您抱怨您移动的位数超过了类型的位数,因此总是为零(参见演示)。

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


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

于 2018-08-07T15:42:14.170 回答
2

您的班次溢出字节,并且您没有正确打印整数。

此代码正在运行:(注意打印格式以及如何进行转换uint64_t

#include <stdio.h>
#include <cstdint>

int main()
{
    const unsigned char *command = (const unsigned char *)"\x42\xa0\x82\xa1\x21\x22";
    uint64_t value=0;
    for (int i=0; i<6; i++)
    {
        value <<= 8;
        value += command[i];
    }
    printf("%x  %x  %x  %x  %x  %x  %llx",
             command[0], command[1], command[2], command[3], command[4], command[5], value);
}
于 2018-08-07T15:54:32.047 回答