C#/Java 等高级语言屏蔽位移计数操作数的原因是什么?

发布于 2024-08-23 01:16:50 字数 746 浏览 7 评论 0原文

这更多的是一个语言设计而不是一个编程问题。

以下是 JLS 15.19 移位运算符

如果左侧操作数的提升类型为int,则仅使用右侧操作数的最低 5 位作为移位距离。

如果左侧操作数的提升类型为long,则仅使用右侧操作数的最低 6 位作为移位距离。

此行为也在 C# 中指定,并且虽然我不确定它是否在 Javascript 的官方规范中(如果有的话),但至少根据我自己的测试,它也是正确的。

结果是,以下内容是正确的:

(1 << 32) == 1

我知道该规范可能是受到以下事实的“启发”:底层硬件在移位 32 位值时仅占用 5 位计数操作数(对于 64 位值移位 6 位),例如,我可以理解在 JVM 级别指定的此类行为,但为什么 C# 和 Java 等高级语言会保留这种相当低级的行为?难道它们不应该提供超越硬件实现的更抽象的视图并且表现得更直观吗? (如果他们可以用负数来表示向另一个方向移动,那就更好了!)

This is more of a language design rather than a programming question.

The following is an excerpt from JLS 15.19 Shift Operators:

If the promoted type of the left-hand operand is int, only the five lowest-order bits of the right-hand operand are used as the shift distance.

If the promoted type of the left-hand operand is long, then only the six lowest-order bits of the right-hand operand are used as the shift distance.

This behavior is also specified in C#, and while I'm not sure if it's in the official spec for Javascript (if there's one), it's also true based on my own test at least.

The consequence is that the following is true:

(1 << 32) == 1

I understand that this specification is probably "inspired" by the fact that the underlying hardware only takes 5 bits for the count operand when shifting 32-bit values (and 6 bits for 64-bit), and I can understand such behavior specified at the JVM level for example, but why would high level languages such as C# and Java retain this rather low-level behavior? Shouldn't they provide a more abstract view beyond the hardware implementation and behave more intuitively? (Even better if they can take a negative count to mean to shift in the OTHER direction!)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

违心° 2024-08-30 01:16:50

Java 和 C# 并不完全“高级”。他们非常努力地希望能够被编译成高效的代码,以便在微基准测试中脱颖而出。这就是为什么它们具有诸如 int 之类的“值类型”,而不是具有默认整数类型的真整数,真整数本身就是对象,并且不限于固定范围。

因此,他们模仿硬件的功能。他们稍微修剪了一下,因为他们强制屏蔽,而C只允许它。尽管如此,Java 和 C# 仍然是“中级”语言。

Java and C# are not fully "high-level". They try real hard to be such that they can be compiled into efficient code, in order to shine in micro-benchmarks. This is why they have the "value types" such as int instead of having, as default integer type, true integers, which would be objects in their own right, and not limited to a fixed range.

Hence, they mimic what the hardware does. They trim it a bit, in that they mandate masking, whereas C only allows it. Still, Java and C# are "medium-level" languages.

歌枕肩 2024-08-30 01:16:50

因为在大多数编程环境中整数只有 32 位。所以 5 位(足以表示 32 个值)已经足以移位整个整数。对于 64 位长也存在类似的推理:完全移位整个值只需要 6 位。

我可以理解部分混乱:如果您的右侧操作数是最终值大于 32 的计算结果,您可能会期望它只是移动所有位而不是应用掩码。

Because in most programming environments an integer is only 32 bits. So then 5 bits (which is enough to express 32 values) is already enough to shift the entire integer. A similar reasoning exists for a 64bit long: 6 bits is all you need to completely shift the entire value.

I can understand part of the confusion: if your right-hand operand is the result of a calculation that ends up with a value greater than 32, you might expect it to just shift all the bits rather than apply a mask.

∞琼窗梦回ˉ 2024-08-30 01:16:50

C# 和 Java 将移位定义为仅使用移位计数的低位,因为 sparc 和 x86 移位指令都是这样做的。 Java 最初由 Sun 在 sparc 处理器上实现,C# 最初由 Microsoft 在 x86 上实现。

相反,如果移位计数不在 0..31 范围内(对于 32 位 int),C/C++ 会将移位指令的行为保留为未定义,从而允许任何行为。这是因为当 C 第一次实现时,不同的软件对这些的处理方式不同。例如,在 VAX 上,移动负量会向另一个方向移动。因此,对于 C,编译器可以只使用硬件移位指令并执行它所做的任何操作。

C# and Java define shifting as using only the low-order bits of the shift count as that's what both sparc and x86 shift instructions do. Java was originally implemented by Sun on sparc processors, and C# by Microsoft on x86.

In contrast, C/C++ leave as undefined the behavior of shift instructions if the shift count is not in the range 0..31 (for a 32 bit int), allowing any behavior. That's because when C was first implemented, different handware handled these differently. For example, on a VAX, shifting by a negative amount shifts the other direction. So with C, the compiler can just use the hardware shift instruction and do whatever it does.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文