将 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;
我原以为 merged
是 0xBE
,或者二进制 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 × 2
E2
, 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×2
E2
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 转变中有未定义的行为,所以谁知道会发生什么!
我正在尝试将一个 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;
我原以为 merged
是 0xBE
,或者二进制 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
isE1
left-shiftedE2
bit positions; vacated bits are zero-filled. IfE1
has an unsigned type, the value of the result isE1 × 2
E2
, reduced modulo one more than the maximum value representable in the result type. Otherwise, ifE1
has a signed type and non-negative value, andE1×2
E2
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 转变中有未定义的行为,所以谁知道会发生什么!