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

标签 c# java bit-manipulation

我正在尝试将 Java 代码移植到 C#,但我遇到了与无符号右移运算符相关的奇怪错误 >>> 通常是代码:

long l = (long) ((ulong) number) >> 2;

相当于 Java 的:

long l = number >>> 2;

但是,对于 -2147483648L 的情况,您可能将其识别为 Integer.MIN_VALUE,这将返回一个不同于 Java 的数字,因为转换为 ulong 更改了数字的语义,因此我得到了不同的结果。

在 C# 中如何实现这样的事情?

我想尽可能地保留代码语义,因为它是一个相当复杂的代码体。

最佳答案

在考虑 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);

关于c# - C# 中的无符号右移对负数使用 Java 语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21188176/

相关文章:

c# - C#中的文件上传HTTP PUT

c# - TDD 新手 : Are there sample applications with tests to show how to do TDD?

Java 方法无界类型或类返回

c - 如何使用掩码获取几位的值

c# - 使用 LINQ 将 Dictionary<Guid,IList<String>> 转换为 Dictionary<string,IList<Guid>>?

c# - 有没有办法按所需顺序运行 Specflow 场景(C# Selenium)?

java - Glassfish 5 可以与 java 10 一起运行还是仅与 java 8 兼容?

java - 以编程方式连接到 chromecast 路由 : do I need a permission?

c++ - 如何将三个 4 位有符号整数(即 5 位)打包成一个 16 位整数?

c - 如何将32位打包成4x8位?