I’m trying to port some code from C# to Java and I’m stuck on some low-level bit operations.
Here is an example snippet that I’m trying to figure out how to translate from C# to Java:
int shiftAmount = 2; uint[] tbl = { 1023326899, 1265601397, 3234840308, 1673932182 }; uint[] tblShift = new uint[4]; for (int x = 0; x < tbl.Length; ++x) { tblShift[x] = tbl[x] << shiftAmount; Console.WriteLine(tblShift[x]); }
Result:
[0] 4093307596 uint [1] 767438292 uint [2] 54459344 uint [3] 2400761432 uint
So far so good.
How do you convert this same thing to Java?
So in Java, I naively just tried turning all the uint
to long, it’s not correct for all the values:
long[] tbl = { 1023326899L, 1265601397L, 3234840308L, 1673932182L }; long[] tblShift = new long[4]; for (int x = 0; x < tbl.length; ++x) { tblShift[x] = tbl[x] << shiftAmount; }
You get:
0 = 4093307596 1 = 5062405588 2 = 12939361232 3 = 6695728728
I’m guessing I have to make an additional shift operation to account for the extra bits in the long
integer. And probably also have to account for the signed-ness of the integer as well when doing bit operations. But everything I’ve tried seems to come up wrong.
Does anyone have a guide on how to translate common C++/C# unsigned integer operations to work in Java?
UPDATE: I found a library on Maven central https://github.com/jOOQ/jOOU and it does have some nice unsigned int support, but lacks the bitwise operation libraries. Perhaps I should keep digging looking for an unsigned-bit-operation library.
Advertisement
Answer
The reason is that long
in Java can hold a larger number than uint
in C# can. uint
is limited to 4,294,967,295 (0xFFFFFFFF) whereas Java’s long
can hold up to 9,223,372,036,854,775,807.
Taking your example of 1265601397L << 2
:
- The C# result is
767438292
- The Java result is
5062405588
(0x12DBE2DD4) - If we use a mask of
0xFFFFFFFF
, then we get0x2DBE2DD4
, which equals767438292
Therefore the solution is to use the bitwise AND operator (&
) to apply the mask and get the C# int-equivalent value:
int shiftAmount = 2; long[] tbl = { 1023326899L, 1265601397L, 3234840308L, 1673932182L }; long[] tblShift = new long[4]; for (int x = 0; x < tbl.length; ++x) { tblShift[x] = (tbl[x] << shiftAmount) & 0xFFFFFFFFL; }
Results:
Input | C# output | Java output |
---|---|---|
1023326899 | 4093307596 | 4093307596 |
1265601397 | 767438292 | 767438292 |
3234840308 | 54459344 | 54459344 |
1673932182 | 2400761432 | 2400761432 |