3

I have

_int8 arr[0] = 0;
_int8 arr[1] = 0;
_int8 arr[2] = 14;
_int8 arr[3] = 16;

I need to convert it to one _int32 using as arr[0] as first part <..> and arr[3] as last. In the end it should be

_int32 back = 3600;

Should I use bit shifts or smth like that to achieve this?

gemexas
  • 203
  • 2
  • 5
  • 10

3 Answers3

8

Cast them all to int then use:

(arr[0] << 24) | (arr[1] << 16) | (arr[2] << 8) | arr[3]

Alternatively:

_int32 back = 0;
for (int i = 0; i < 4; ++i)
    back = (back << 8) | arr[i];
Peter Alexander
  • 53,344
  • 14
  • 119
  • 168
  • 3
    You might want or need to convert to uint to avoid problems with sign bit extension. – hardmath Jan 16 '11 at 17:54
  • @hardmath: True, I guess it depends what he wants. – Peter Alexander Jan 16 '11 at 17:55
  • @hardmath Actually I do not follow. Where does signedness intervene when using left shifts? If there had been right shifts in Peter's answer I would have understood, but here I feel like I'm missing something. – Pascal Cuoq Jan 16 '11 at 18:01
  • 1
    @Pascal Cuoq: Signedness intervenes before the shifts, when you do the conversions. If I have a signed byte int8 and covert to int32, I expect "negative" values to be sign extended to negative values. Perhaps gemaxas's question is open to interpretation, but the way I read it means just placing the bytes in the correct order. Using a bitwise OR to do that (as Peter suggested) would require suppressing any sign extension. Nick's solution (aliasing the same piece of memory) is maybe a little cleaner because it avoids the issue. – hardmath Jan 16 '11 at 18:33
  • I never understand why bit shifting is even considered when unions are available. – David Heffernan Jan 16 '11 at 19:56
4

If you know the byte ordering (i.e. big endian or little endian, check it out on wikipedia), and the array is set up in the right order you can just do:

back = *(_int32 *)arr;

That'll just interpret your array of 4 bytes as a buffer holding a single 32-bit integer. In your example though, I think you've got it set up for big endian and x86 isn't. So you'd need to swap some bytes.

For instance:

_int32 back = arr[0] << 24 | arr[1] << 16 | arr[2] << 8 | arr[3];

or something like that.

Nick Gerner
  • 1,849
  • 1
  • 15
  • 9
1

It's probably my SCO compiler but I think I've had problems if I didn't use (arr[0]&0xff) and so forth for doing the shifts. Certainly doesn't hurt anything.

Walt
  • 312
  • 3
  • 7