Convert four bytes to Integer using C++
Your buffer
contains signed characters. So, actually, buffer[0] == -29
, which upon conversion to int
gets sign-extended to 0xffffffe3
, and in turn (0x3e << 8) | 0xffffffe3 == 0xffffffe3
.
You need ensure your individual buffer
bytes are interpreted unsigned
, either by declaring buffer
as unsigned char *
, or by explicitly casting:
int a = int((unsigned char)(buffer[0]) << 24 |
(unsigned char)(buffer[1]) << 16 |
(unsigned char)(buffer[2]) << 8 |
(unsigned char)(buffer[3]));
In the expression buffer[0] << 24
the value 24 is an int
, so buffer[0]
will also be converted to an int
before the shift is performed.
On your system a char
is apparently signed, and will then be sign extended when converted to int
.
I think this could be also done with use of memcpy
:
int buffToInteger(char* buffer)
{
int a;
memcpy( &a, buffer, sizeof( int ) );
return a;
}
This is much faster than the example mentioned in the original post, because it just treats all bytes "as is" and there is no need to do any operations such as bit shift etc. It also doesn't cause any signed-unsigned issues.
There's a implict promotion to a signed int in your shifts. That's because char is (apparently) signed on your platform (the common thing) and << promotes to integers implicitly. In fact none of this would work otherwise because << 8 (and higher) would scrub all your bits!
If you're stuck with using a buffer of signed chars this will give you what you want:
#include <iostream>
#include <iomanip>
int buffToInteger(char * buffer)
{
int a = static_cast<int>(static_cast<unsigned char>(buffer[0]) << 24 |
static_cast<unsigned char>(buffer[1]) << 16 |
static_cast<unsigned char>(buffer[2]) << 8 |
static_cast<unsigned char>(buffer[3]));
return a;
}
int main(void) {
char buff[4]={0x0,0x0,0x3e,static_cast<char>(0xe3)};
int a=buffToInteger(buff);
std::cout<<std::hex<<a<<std::endl;
// your code goes here
return 0;
}
Be careful about bit shifting on signed values. Promotions don't just add bytes but may convert values.
For example a gotcha here is that you can't use static_cast<unsigned int>(buffer[1])
(etc.) directly because that converts the signed char value to a signed int and then reinterprets that value as an unsigned.
If anyone asks me all implicit numeric conversions are bad. No program should have so many that they would become a chore. It's a softness in the C++ inherited from C that causes all sorts of problems that far exceed their value. It's even worse in C++ because they make the already confusing overloading rules even more confusing.