我正在尝试将Java代码移植到C#,我遇到了与无符号右移运算符相关的奇怪错误>>>通常是代码:
long l = (long) ((ulong) number) >> 2;
相当于Java:
long l = number >>> 2;
但是对于-2147483648L
你可能认为是Integer.MIN_VALUE
的情况,这会返回一个与Java不同的数字,因为转换为ulong
会改变数字的语义,因此我得到不同的结果。
在C#中,这样的事情怎么可能?
我想尽可能保留代码语义,因为它是一个相当复杂的代码体。
答案 0 :(得分:5)
我认为在考虑C#的顺序优先时你的表达式是不正确的。我相信您的代码会将long
转换为ulong
,然后转回long
,然后转换。我假设你的意图是在ulong
上进行转变。
从C# Specification §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);