C# 中的无符号右移 对负数使用 Java 语义



我正在尝试将 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);

最新更新