将char *数组合并到uint16_t

时间:2015-12-29 21:26:28

标签: c++ arrays binary bitwise-operators

我试图将char * -array合并到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]

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

基本上我要做的就是将arr[0]追加到{{1}}并将新号码解释为整体。

2 个答案:

答案 0 :(得分:1)

在您的情况下,char可能是签名类型,而且左移0xBE vhich被解释为带符号的负值(-66可能是two's complement )。

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

  

3.9.1基本类型
....

     

它是实现定义的   char对象是否可以保存负值。

           

5.8转换运算符
....

     

E1 << E2的值为E1左移E2位位置;空位是零填充的。如果E1有未签名的   类型,结果的值是E1 × 2 E2 ,减去模数比最大值可表示的   在结果类型中。否则,如果E1具有签名类型且非负值,则E1×2 E2 可表示   在结果类型的相应无符号类型中,那么转换为结果类型的值是   结果价值;否则,行为未定义。

答案 1 :(得分:1)

你需要在移位之前分配更广泛的类型,否则你会在你的高位之前移开,然后它们才能在这里找到足够大的唯一变量抱着他们。

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

或者,可以说:

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

您还可以考虑先通过unsigned char进行转换,以避免设置高位的奇怪现象。在单元测试套件中尝试一些不同的值,看看会发生什么。

那么,你的程序在这个超出范围的转变中有未定义的行为,所以谁知道会发生什么呢!