I'm working on an embedded platform (ARM) and have to be careful when dealing with bit patterns. Let's pretend this line is beyond my influence:

uint8_t foo = 0xCE;          // 0b11001110

Interpreted as unsigned this would be 206. But actually it's signed, thus resembling -50. How can I continue using this value as signed?

int8_t bar = foo;            // doesn't work

neither do (resulting in 0x10 or 0x00 for all input values)

int8_t bar = static_cast<int8_t>(foo);
int8_t bar = reinterpret_cast<int8_t&>(foo);

I just want the bits to remain untouched, ie. (bar == 0xCE)

Vice versa I'd be interested how to get bit-patters, representing negative numbers, into unsigned variables without messing the bit-pattern. I'm using GCC.

有帮助吗?

解决方案

The following works fine for me, as it should though as the comments say, this is implementation-defined:

int x = (signed char)(foo);

In C++, you can also say:

int x = static_cast<signed char>(foo);

Note that promotion always tries to preserve the value before reinterpreting bit patterns. Thus you first have to cast to the signed type of the same size as your unsigned type to force the signed reinterpretation.

(I usually face the opposite problem when trying to print chars as pairs of hex digits.)

其他提示

uint8_t foo = 0xCE;          // 0b11001110
int8_t bar;
memcpy( &bar, &foo, 1 );

It even has the added bonus that 99% of compilers will completely optimise out the call to memcpy ...

Something ugly along the lines of this?

int8_t bar = (foo > 127) ? ((int)foo - 256) : foo;

Doesn't rely on a conversion whose behaviour is undefined.

With GCC chances are that unsigned values are two's complement, even on your embedded platform.

Then the 8-bit number 0xCE represents 0xCE-256.

Because two's complement is really just modulo 2n, where n is the number of bits in the representation.

EDIT: hm, for rep's sake I'd better give a concrete example:

int8_t toInt8( uint8_t x )
{
    return (x >= 128? x - 256 : x);
}

EDIT 2: I didn't see the final question about how to get a bit pattern into an unsigned variable. That's extremely easy: just assign. The result is guaranteed by the C++ standard, namely that the value stored is congruent (on-the-clock-face equal) to the value assigned, modulo 2n.

Cheers & hth.,

You can access the representation of a value using a pointer. By reinterpreting the pointer type, not the value type, you should be able to replicate the representation.

uint8_t foo = 0xCE;          
int8_t bar = *reinterpret_cast<int8_t*>(&foo);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top