I have these definitions:
int data = uartBaseAddress[UART_DATA_REGISTER / 4]; // data coming from UART RX port
char message; // array of 20 chars
Now when I try to do this:
message = (char) data;
It prints (for example):
"ffffff9c". Of course I want only the last 8 bits ("9c") and I don't understand how to properly do the conversion from
EDIT: I mean: i have to populate the array like this:
data = 0xFFFFFF9c;
message = data & 0xFF; -- it has to contain only 9c
data = 0xFFFFFFde;
message = data & 0xFF; -- it has to contain only de
Best How To :
The conversion is correct. It's the
printf that's the problem.
char is signed on your system (it can be either signed or unsigned).
I'm going to guess that the value printed was
ffffff9c (8 digits), not
ffffffff9c (10 digits); please verify that.
The value of
data was probably
-100. Converting that value from
char would yield
-100, since that value is within the range of type
%x format specifier requires an argument of type
unsigned int, not
int. The value of
message is promoted to
int when it's passed to
printf, because of the format string, assumes that the argument is of type
Strictly speaking, the behavior is undefined, but most likely
printf will simply take the
int value passed to it and treat it as if it were an
(unsigned int)0xffffff9c have the same representation.
There is no
printf format specifier to print a signed value in hexadecimal. If you change the format from
%d, you'll at least see the correct value.
But you should step back an decide just what you're trying to accomplish. If you want to extract the low-order 8 bits of
data, you can do so by masking it, as unwind's answer suggests. Or you can convert it to
unsigned char rather than plain
char to guarantee that you'll get an unsigned value.
unsigned char value is still promoted to
int when passed to
printf, so to be fully correct you should explicitly convert it to
int data = ...;
unsigned char message; // change to unsigned char
message = data; // no cast needed, the value is implicitly converted
printf("%x", (unsigned int)message);
Strictly speaking, the
(unsigned int) isn't necessary.
message is an
unsigned char, so it will be converted to a non-negative
int value, and there's a special-case rule that says
unsigned int arguments with the same value are interchangeable as function arguments. Still, my own preference is to use the cast because it's clearer, and because adding the cast is easier (particularly for anyone reading the code) than following the line of reasoning that says it's not necessary.