当前位置: 首页 > 面试题库 >

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

龚征
2023-03-14
问题内容

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

以下是JLS
15.19移位运算符
的摘录:

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

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

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

结果是以下事实是正确的:

(1 << 32) == 1

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


问题答案:

Java和C#并非完全“高级”。他们尽力将它们编译成有效的代码,以彰显微基准。这就是为什么它们具有“值类型”,int而不是拥有真正的整数作为默认整数类型的原因,这些整数本身就是对象,并且不限于固定范围。

因此,它们模仿硬件的功能。他们对它进行了一些微调,因为它们 要求 屏蔽,而C仅允许它。Java和C#仍然是“中级”语言。



 类似资料:
  • 本文向大家介绍java<<、>>、>>>移位操作方法,包括了java<<、>>、>>>移位操作方法的使用技巧和注意事项,需要的朋友参考一下 <<,有符号左移位,将运算数的二进制整体左移指定位数,低位用0补齐。 以上是正整数,运算结果如下。 接下来看看将负数进行左移2位操作是什么情况,运算结果如下。 为什么会-10的二进制会出现这么多的1呢?仔细数一下刚好有32位。首先需要了解的是Java负数存储是

  • 主要内容:位域的存储,无名位域有些数据在存储时并不需要占用一个完整的字节,只需要占用一个或几个二进制位即可。例如开关只有通电和断电两种状态,用 0 和 1 表示足以,也就是用一个二进位。正是基于这种考虑,C语言又提供了一种叫做位域的 数据结构。 在结构体定义时,我们可以指定某个成员变量所占用的二进制位数(Bit),这就是位域。请看下面的例子: 后面的数字用来限定成员变量占用的位数。成员 m 没有限制,根据数据类型即可推算出它占

  • 下面是一个程序,它应该计算小数点后的双倍值中的位数。在输入一些双值时,程序倾向于开始一个无限循环(可能是由于浮点不精确)。我不想使用任何包装器方法(包括String类)。有人可能为某些输入的无休止循环提供解释并提供解决方案吗?

  • 本文向大家介绍高级语言和低级语言之间的区别,包括了高级语言和低级语言之间的区别的使用技巧和注意事项,需要的朋友参考一下 让我们首先了解高级和低级语言- 高级语言 与低级语言相比,它易于解释和编译。 它可以被认为是程序员友好的语言。 很容易理解。 这很容易调试。 在维护方面很简单。 它要求将编译器/解释器翻译成机器代码。 它可以在不同的平台上运行。 它可以从一个位置移植到另一位置。 i.e与低级语言

  • 主要内容:按位与运算(&),按位或运算(|),按位异或运算(^),取反运算(~),左移运算(<<),右移运算(>>)所谓 位运算,就是对一个比特(Bit)位进行操作。在《 数据在内存中的存储》一节中讲到,比特(Bit)是一个电子元器件,8个比特构成一个字节(Byte),它已经是粒度最小的可操作单元了。 C语言提供了六种位运算符: 运算符 & | ^ ~ << >> 说明 按位与 按位或 按位异或 取反 左移 右移 按位与运算(&) 一个比特(Bit)位只有 0 和 1 两个取值,只有参与 运算的

  • 问题内容: 据我了解,java将数据存储在二进制补码中,表示-1 = 11111111(根据Wikipedia)。 同样,从java docs中:“位模式由左侧操作数给出,要移位的位置数由右侧操作数给出。无符号的右移运算符“ >>>”将零移位到最左边位置,而“ ”之后的最左侧位置取决于符号扩展名。” 这意味着>>>每次都会将0移到最左侧。所以我希望这段代码是 迭代:x的位表示 0:11111111