将 char* 数组合并到 uint16_t

Merge char* arrays to uint16_t

我正在尝试将一个 char* 数组合并到一个 uint16_t 中。到目前为止,这是我的代码:

char* arr = new char[2]{0};
arr[0] = 0x0; // Binary: 00000000
arr[1] = 0xBE; // Binary: 10111110

uint16_t merged = (arr[0] << 8) + arr[1]; 
cout << merged << " As Bitset: " << bitset<16>(merged) << endl; 

我原以为 merged0xBE,或者二进制 00000000 10111110

但是应用程序的输出是:

65470 As Bitset: 1111111110111110

在下面的描述中,我从左到右读取位

所以arr[1]在正确的位置,也就是最后8位。 然而,前 8 位被设置为 1,这是不应该的。

此外,如果我将值更改为

arr[0] = 0x1; // Binary: 00000001
arr[1] = 0xBE; // Binary: 10111110

输出为:

0000000010111110

同样,arr[1] 位于正确的位置。但是现在前 8 位是 0,而前 8 位的最后一位应该是 1

基本上我不想做的是将 arr[1] 附加到 arr[0] 并将新数字解释为一个整体。

也许 char 在你的情况下是带符号的类型,而你是 left-shifting 0xBE vhich 被解释为带符号的负值(-66 在可能的情况下 two's complement).

根据标准,这是未定义的行为。在实践中,它通常会导致扩展符号位,因此会导致前导位。

3.9.1 Fundamental types
....

It is implementationdefined whether a char object can hold negative values.


5.8 Shift operators
....

The value of E1 << E2 is E1 left-shifted E2 bit positions; vacated bits are zero-filled. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. Otherwise, if E1 has a signed type and non-negative value, and E1×2E2 is representable in the corresponding unsigned type of the result type, then that value, converted to the result type, is the resulting value; otherwise, the behavior is undefined.

你需要在之前转移到更宽的类型,否则你正在转移你的高位甚至之前点击此处唯一大到足以容纳它们的变量。

uint16_t merged = arr[0];
merged <<= 8;
merged += arr[1];

或者,可以说:

const uint16_t merged = ((uint16_t)arr[0] << 8) + arr[1];

您可能还需要考虑先通过 unsigned char 进行转换,以避免设置高位时出现异常情况。在您的单元测试套件中尝试几个不同的值,看看会发生什么。

好吧,你的程序在这个 out-of-range 转变中有未定义的行为,所以谁知道会发生什么!