25

How can I convert two 32 bit integers (int) to one 64 bit long and vice versa?

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
user1293081
  • 331
  • 1
  • 3
  • 12

2 Answers2

51
long c = (long)a << 32 | b & 0xFFFFFFFFL;
int aBack = (int)(c >> 32);
int bBack = (int)c;

In Java, you don't need quite so many parentheses, or any masking on the reverse calculation.

Fuwjax
  • 2,327
  • 20
  • 18
  • 1
    Lessee: `for (long i = Long.MIN_VALUE; i <= Long.MAX_VALUE; i++) {...` – Hot Licks Jun 26 '12 at 20:37
  • 292 years is far far less than it will take. My computer also claims 292 years, as will everyone elses. For me `(stop - start)*2.0/reps*Long.MAX_VALUE)`is 1.207154932183553E22 while Long.MaxValue is 9223372036854775807 so when the cast to `(long)` happens everyone ends up with 9223372036854775807. As thats 1/1308th the true value the time should actually be 382,000 years. (Still +1 though since the actual answer is correct) – Richard Tingle May 09 '15 at 15:07
  • Haha, very nice Richard. I'm in the habit of never doing the millis-to-something-else conversion manually, but I also rarely try to get millisecond resolution on hundreds (or hundreds of thousands) of years. As I am no longer a teacher, I'll just edit out the whole "exercise" bit. The answer doesn't need to be so long. – Fuwjax May 10 '15 at 01:49
  • Sorry if this is clear to everyone. Can someone explain this please. I understand the first part that we are vacating the last 32 bits. What is the second part doing. What will AND with all 1's give? I tried this with ((long)a << 32) + b and it gives the same out put and thats why I am wondering what the mask is in place for. – Ashwin Sep 08 '15 at 18:45
  • (long)a << 32 + b only works when b is positive. In Java, ints are signed, so you have to appropriately deal with the sign. We aren't ANDing with all 1's, the mask is a long (64 bits) with the lower 32 bits as 1's, this effectively treats b as an unsigned int when we are storing it in a long. – Fuwjax Sep 09 '15 at 19:27
2

Ints to longs:

long c = ((long)a << 32) | ((long)b & 0xFFFFFFFFL);

I'll leave it as an exercise for the reader to perform the reverse calculation. But the hint is; use more bit-shifts and bit-masks.

(Edited as per comment by T. Murdock)

Dan
  • 736
  • 8
  • 12
Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • I think b is may well already be assumed to be valid, given the circumstances. – Tharwen May 21 '12 at 13:31
  • 4
    This answer is subtly wrong: it will fail for `b = 0x1FFFFFFF`, on account of containing (as of this comment) seven Fs in the mask, not eight. That means it fails not only for all negative values of b (as the answer with no mask would fail), but also for large positive values of b. – Theodore Murdock Nov 24 '15 at 22:42