I have two char
's and I want to "stitch" them bitwise together.
For example:
char c1 = 11; // 0000 1011
char c2 = 5; // 0000 0101
short int si = stitch(c1, c2); // 0000 1011 0000 0101
So, what I first tried was with bitwise operators:
short int stitch(char c1, char c2)
{
return (c1 << 8) | c2;
}
But this doesn't work: I'm getting a short
equals to c2
... (1) Why?
(But: c1
and c2
are negative numbers in my real app... maybe this is a part of the problem?)
So, my second solution was to use a union
:
union stUnion
{
struct
{
char c1;
char c2;
}
short int si;
}
short int stitch(char c1, char c2)
{
stUnion u;
u.c1 = c1;
u.c2 = c2;
return u.si;
}
This works like I want... I think
(2) What is the best/fastest way?
Thanks!
The union
method is implementation-defined at best (in practice, it will pretty reliably work but the format of si
depends on the endianness of the platform).
The problem with the bitwise way is, as you suspect, the negative numbers. A negative number is represented by a chain of leading 1's. So -5 for example is
1111 1011
If you cast this to int
or even unsigned int
, it becomes
1111 1111 1111 … 1111 1011
and all those 1's will drown out the left-shifted data when OR is applied.
To solve the problem, cast the char
s to unsigned char
and then to int
(to prevent overflow, or even the appearance of the possibility of overflow) before shifting:
short int stitch(char c1, char c2)
{
return ( (int) (unsigned char) c1 << 8) | (unsigned char) c2;
}
or, if you are free to change the types of the arguments and you can include <cstdint>
,
uint16_t stitch( uint8_t c1, uint8_t c2)
{
return ( (int) c1 << 8 ) | c2;
}
$5.8/1 states- "The operands shall be of integral or enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or reater than or equal to the length in bits of the promoted left operand."
So try to typecast c1 to unsigned int and then bitwise OR with C2. Also return the output as unsigned int. chars are promoted to int but we want to be 'unsigned int'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With