4

I have four unsigned chars, each containing a byte, that I want to combine together to form a single int32_t, where the bytes come one after another.

       unsigned char x1 = 0b11100111;
       unsigned char x2 = 0b00010101;
       unsigned char x3 = 0b10000110;
       unsigned char x4 = 0b00001111;

With the four chars above the int32_t should have a binary representation of 0b11100111000101011000011000001111.

How can this be done in c?

The chef
  • 85
  • 1
  • 7

2 Answers2

4

You can do this with a series of shifts and bitwise OR operations:

uint32_t x = 0;
x |= (uint32_t)x1 << 24;
x |= (uint32_t)x2 << 16;
x |= (uint32_t)x3 << 8;
x |= (uint32_t)x4;

Since the bytes are unsigned, you should use an uint32_t for the destination, otherwise you run into implementation defined behavior if the high order bit is set.

dbush
  • 205,898
  • 23
  • 218
  • 273
0

You could do it like follows:



    #include <stdint.h>
    #include <stdio.h>

    int main() {
      unsigned char x1 = 0b11100111;
      unsigned char x2 = 0b00010101;
      unsigned char x3 = 0b10000110;
      unsigned char x4 = 0b00001111;
      int32_t x5 = x1;
      x5 <<= 8;
      x5 |= x2;
      x5 <<= 8;
      x5 |= x3;
      x5 <<= 8;
      x5 |= x4;

      printf("%d", x5);

    }

savram
  • 500
  • 4
  • 18
  • The left-most bit is the sign bit when dealing with signed integers, is it not? The OP did not state his intentions. He might want a signed integer after all, why not? – savram Sep 02 '17 at 00:12
  • Left shifting into the sign bit is _undefined behavior_ (C11 §6.5.7 4) , meaning the compiler may make any code and bad thing may happen. Using `uint32_t` avoids that. Assigning a `uint32_t` to a `int32_t` is less problematic - it is "implementation-defined or an implementation-defined signal is raised." §6.3.1.3 3 rarely a problem. – chux - Reinstate Monica Sep 02 '17 at 01:08
  • That's interesting, I didn't know that. It's counter-intuitive and makes no sense though. "If E1 has a signed type and nonnegative value, and E1×2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined". Why would the behavior be undefined when the value is negative? I mean...the signed integer is supposed to hold negative values as well. Go figure. – savram Sep 02 '17 at 01:20
  • Say you are the C King - what behavior would you define for `-1 << 1`, or `INT_MAX << 1` or `INT_MIN << 1`? Would that work well with 2's complement, sign-magnitude, 1's complement integers? Would this behavior make for less efficient code when `x >= 0`? – chux - Reinstate Monica Sep 02 '17 at 01:25
  • Computers use 2's complement right? Then -1 << 1 would result in -1. 1 << 32 would result in -2147483648 etc. Maybe I'm missing something here? – savram Sep 02 '17 at 01:38
  • Computers use 2's complement right? --> certainly _most_ do. `-1 << 1` would result in `-1`??? `1 << 32` --> `-2147483648` ??? I`d recommend testing these with your compiler. – chux - Reinstate Monica Sep 02 '17 at 03:43