我正在尝试将 Java 代码移植到 C#,但我遇到了与无符号右移运算符相关的奇怪错误,>>>通常代码:
long l = (long) ((ulong) number) >> 2;
相当于Java的:
long l = number >>> 2;
但是,对于您可能认为Integer.MIN_VALUE
-2147483648L
的情况,这将返回与 Java 中的数字不同的数字,因为 ulong
的强制转换会更改数字的语义,因此我得到不同的结果。
这样的事情在 C# 中怎么可能?
我想尽可能保留代码语义,因为它是一个非常复杂的代码体。
在考虑 C# 的顺序优先级时您的表达式是不正确的。我相信您的代码正在将您的long
转换为ulong
,然后返回long
,然后转移。我假设您的意图是在ulong
上执行班次.
从 C# 规范 §7.2.1 开始,一元(或在您的例子中,转换操作)优先于移位。因此,您的代码:
long l = (long) ((ulong) number) >> 2;
将被解释为:
ulong ulongNumber = (ulong)number;
long longNumber = (long)ulongNumber;
long shiftedlongNumber = longNumber >> 2;
给定number
作为-2147483648L
,这会产生536870912
。
通过将转换括起来并在括号中移位:
long l = (long) (((ulong) number) >> 2);
生成可重写为的逻辑:
ulong ulongNumber = (ulong)number;
ulong shiftedulongNumber = ulongNumber >> 2;
long longShiftedNumber = (long)shiftedulongNumber;
给定number
为-2147483648L
,这会产生4611686017890516992
。
编辑:请注意,鉴于这些排序规则,我的答案中有一组额外的括号是不必要的。正确的表达式可以写成:
long l = (long) ((ulong) number >> 2);