如何在Java 1.8中实现与C#结果一致的无符号整数左移位操作
C#无符号整数位运算Java转译方案
问题根因
- C# 中
uint为32位无符号整数,左移操作产生的溢出高位会被直接舍弃,最终结果仅保留低32位的无符号数值。 - 直接使用Java 64位
long类型执行左移时,32位以上的高位不会被自动截断,所以会得到完整的64位运算结果,和C#的32位截断结果不一致。
正确实现代码
只需要在移位运算后增加32位截断操作即可,代码如下:
int shiftAmount = 2; long[] tbl = { 1023326899L, 1265601397L, 3234840308L, 1673932182L }; long[] tblShift = new long[4]; for (int x = 0; x < tbl.length; ++x) { // 左移后和0xFFFFFFFFL按位与,截断保留低32位,完全模拟C# uint溢出截断逻辑 tblShift[x] = (tbl[x] << shiftAmount) & 0xFFFFFFFFL; }
运行上述代码得到的结果和C#的预期输出完全一致:
0 = 4093307596 1 = 767438292 2 = 54459344 3 = 2400761432
无符号整数转译通用规则
- 所有32位无符号整数运算,都可以用Java
long类型存储中间值,每次运算完成后执行& 0xFFFFFFFFL截断到低32位,即可模拟C#uint的运算效果。 - 如果涉及右移操作时,需要使用Java无符号右移运算符
>>>代替算术右移运算符>>,避免符号位扩展影响结果。
无符号位运算逻辑简单,无需依赖第三方库即可自行封装实现。
内容的提问来源于stack exchange,提问作者Nicholas DiPiazza
相关产品推荐
相关产品推荐

