Reputation: 315
I am feeling confused with the | operator in C++. I have code to transfer the data which read from a MCU. The high 8 bits are seperated from low 8 bits. And the data(the BUF in code) store the complement number. So I use (BUF[1] << 8) | BUF[0]
to get my raw data. However, the result is a bit strange. For example, the now code get d1=-84
. As the pic shows, why doesn't the |
operator get results as I want?
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include<iostream>
int main() {
signed char BUF[2];
BUF[0] = -84;
BUF[1] = -2;
short d1;
d1 = (BUF[1] << 8) | BUF[0]; // | operator
std::cout << d1 << std::endl;
std::cin.get();
}
Upvotes: 0
Views: 114
Reputation: 234715
The behaviour on left shifting a negative number is undefined, and prior to C++14 you are vulnerable to different complementing schemes for a signed char
. (From C++14 signed char
and char
if it's signed
must be 2's complement.)
For an easy life, write merely
BUF[1] * 256 + BUF[0]
noting that the type of this expression is an int
.
Upvotes: 3
Reputation: 213862
You cannot left-shift negative numbers, doing so invokes undefined behavior: anything can happen. Similarly, right-shifting negative numbers is also a bad idea, since that can result in either arithmetic or logical right shift.
You have to cast the variable to unsigned type, shift, then convert back. For example:
d1 = ((uint32_t)BUF[1] << 8) ...
Upvotes: 5