代码之家  ›  专栏  ›  技术社区  ›  polygenelubricants

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

  •  16
  • polygenelubricants  · 技术社区  · 15 年前

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

    以下是摘自 JLS 15.19 Shift Operators :

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

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

    这种行为也是 specified in C# 虽然我不确定它是否在官方的javascript规范中(如果有),但至少在我自己的测试中也是如此。

    其结果是,以下是正确的:

    (1 << 32) == 1
    

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

    3 回复  |  直到 10 年前
        1
  •  8
  •   Thomas Pornin    15 年前

    Java和C语言不是完全“高级”的。为了在微基准测试中发光,他们非常努力地将它们编译成有效的代码。这就是为什么它们具有“值类型”,例如 int 而不是将真整数作为默认的整数类型,真整数本身就是对象,不限于固定范围。

    因此,它们模拟硬件的功能。他们稍微修剪了一下 授权 掩蔽,而C只允许它。不过,Java和C语言是“中等水平”的语言。

        2
  •  5
  •   Joel Coehoorn    15 年前

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

    我可以理解其中的一部分困惑:如果右边的操作数是一个计算的结果,结果是一个大于32的值,那么您可能希望它只是移动所有的位,而不是应用一个掩码。

        3
  •  5
  •   Chris Dodd    15 年前

    C和Java定义移位只使用移位计数的低阶位,这是SPARC和X86移位指令所做的。Java最初是由Sun在SPARC处理器上实现的,而C是微软在X86上实现的。

    相反,如果移位计数不在0…31(对于32位int),允许任何行为,则C/C++作为移位指令的行为留下未定义的行为。这是因为当C第一次实现时,不同的硬件处理这些问题的方式不同。例如,在VAX上,以负值移动会使另一个方向移动。所以有了C,编译器就可以使用硬件移位指令,做任何它做的事情。