10

What is the best way to combine two uints into a ulong in c#, setting the high/low uints.

I know bitshifting can do it, but I don't know the syntax, or there maybe other APIs to help like BitConverter, but I don't see a method that does what I want.

Jon Seigel
  • 12,251
  • 8
  • 58
  • 92
Jason Coyne
  • 6,509
  • 8
  • 40
  • 70

4 Answers4

22
ulong mixed = (ulong)high << 32 | low;

The cast is very important. If you omit the cast, considering the fact that high is of type uint (which is 32 bits), you'll be shifting a 32 bit value 32 bits to the left. Shift operators on 32 bit variables will use shift stuff by right-hand-side mod 32. Effectively, shifting a uint 32 bits to the left is a no-op. Casting to ulong prevents this.

Verifying this fact is easy:

uint test = 1u;
Console.WriteLine(test << 32); // prints 1
Console.WriteLine((ulong)test << 32); // prints (ulong)uint.MaxValue + 1
Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
  • Just out of curiosity, why is the cast needed? – LiraNuna Jul 30 '09 at 21:42
  • If high is just an int, then high<<32 will be all zeros, because you just shifted all of the ones completely out of the variable. You need it to be a 64-bit integer *before* you start shifting it. – Aric TenEyck Jul 30 '09 at 21:43
  • Aric: "you just shifted all of the ones completely out of the variable" this is not completely true. Read my updated answer. – Mehrdad Afshari Jul 30 '09 at 21:45
2
ulong output = (ulong)highUInt << 32 + lowUInt

The << and >> operators bitshift to the left (higher) and right (lower), respectively. highUInt << 32 is functionally the same as highUInt * Math.Pow(2, 32), but may be faster and is (IMO) simpler syntax.

Adam Robinson
  • 182,639
  • 35
  • 285
  • 343
1

You have to convert the highInt to a ulong before you bitshift:

ulong output = highInt;
output = output << 32;
output += lowInt;
Aric TenEyck
  • 8,002
  • 1
  • 34
  • 48
1

Encoding:

ulong mixed = (ulong)hi << 32 | lo;

Decoding:

uint lo = (uint)(mixed & uint.MaxValue);
uint hi = (uint)(mixed >> 32);
Paul van Brenk
  • 7,450
  • 2
  • 33
  • 38