Alex Rivera | Logout

How to combine two 32-bit integers into one 64-bit integer?

Asked 2010-05-04T20:49:28.857
33

I have a count register, which is made up of two 32-bit unsigned integers, one for the higher 32 bits of the value (most significant word), and other for the lower 32 bits of the value (least significant word).

What is the best way in C to combine these two 32-bit unsigned integers and then display as a large number?

In specific:

leastSignificantWord = 4294967295; //2^32-1

printf("Counter: %u%u", mostSignificantWord,leastSignificantWord);

This would print fine.

When the number is incremented to 4294967296, I have it so the leastSignificantWord wipes to 0, and mostSignificantWord (0 initially) is now 1. The whole counter should now read 4294967296, but right now it just reads 10, because I'm just concatenating 1 from mostSignificantWord and 0 from leastSignificantWord.

How should I make it display 4294967296 instead of 10?

Edit
Report

3 Answers

82

It might be advantageous to use unsigned integers with explicit sizes in this case:

#include <stdio.h>
#include <inttypes.h>

int main(void) {
  uint32_t leastSignificantWord = 0;
  uint32_t mostSignificantWord = 1;
  uint64_t i = (uint64_t) mostSignificantWord << 32 | leastSignificantWord;
  printf("%" PRIu64 "\n", i);

  return 0;
}
Output

4294967296

Break down of (uint64_t) mostSignificantWord << 32 | leastSignificantWord

  • (typename) does typecasting in C. It changes value data type to typename.

    (uint64_t) 0x00000001 -> 0x0000000000000001

  • << does left shift. In C left shift on unsigned integers performs logical shift.

    0x0000000000000001 << 32 -> 0x0000000100000000

left logical shift

  • | does 'bitwise or' (logical OR on bits of the operands).

    0b0101 | 0b1001 -> 0b1101

answered 2010-05-04T23:17:11.103
1

This code works when both upper32 and lower32 is negative:

data64 = ((LONGLONG)upper32<< 32) | ((LONGLONG)lower32& 0xffffffff);
answered 2012-04-12T10:11:56.927
-1

You could do it by writing the 32-bit values to the right locations in memory:

unsigned long int data64;
data64=lowerword
*(&((unsigned int)data64)+1)=upperword;

This is machine-dependent however, for example it won't work correctly on big-endian processors.

answered 2012-10-19T11:00:00.917

Your Answer