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

这更像是一种语言设计,而不是编程问题。

以下是JLS 15.19 Shift Operators的摘录

如果左手操作数的升级类型是 ,则只使用右手操作数的五个最低阶位作为移位距离。int

如果左手操作数的提升类型是 ,则仅使用右手操作数的六个最低阶位作为移位距离。long

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

结果是以下情况属实:

(1 << 32) == 1

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


答案 1

Java和C#并不完全是“高级”的。他们非常努力地做到可以将它们编译成高效的代码,以便在微基准测试中大放异彩。这就是为什么它们具有“值类型”的原因,例如,作为默认整数类型,而不是具有真整数类型,这本身就是对象,而不限于固定范围。int

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


答案 2

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

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


推荐