java - Java 的位移运算符在底层是如何工作的?

标签 java bit-manipulation bit twos-complement domain-masking

我没有学习 IT,直到最近才遇到 bit shiftstwo's complement 的申请.那么,您能否在解释中使用简单的英语并假设我对 IP 地址、位操作和 Java 数据类型几乎一无所知?

今天,我找到了如下一段代码(略):

long m = (-1) << (byte) 16;

现在,这是用于 IP 子网掩码。我知道我需要从 4 个 8 位 block (即 4 个字节)开始,并且所有位都必须“打开”: ,在本例中为 16 位;所以我们得到 11111111 11111111 00000000 0000000,掩码。

但是我有几个问题:

  1. 16 是否必须是 byte 类型才能工作?
  2. 结果是 long 类型。当上面的表达式运行时,-1 被有效地转换为 4x8 位 block 。在应用二进制补码时,Java 如何知道它需要 32 个位置/位(IP 地址的长度),而不是 16 位或 8 位? (我猜这与 long 数据类型有关?)
  3. 为什么开始时将二进制补码应用于 -1? (如果你问 Google -0b1 二进制文件中的 -1 是什么,Google 会给你 -0b1 。我首先认为这可能与溢出有关,但事实并非如此,是吗? ...?)
  4. 真的吗,编译器在运行代码时将它转换成什么数据类型,以使其全部正常工作?

更新: 16 是在运行时由一个方法生成的;我只是在这里放一个常量作为例子。事后看来可能是个坏主意......

最佳答案

Really, what datatypes does the compiler convert this to while it's running the code, to make it all work?

这个

(-1) << (byte) 16;

是一个constant expression .它的值在编译时已知。它是一个 long,值为 -65536(以十进制表示)。

如果表达式不是常量表达式,则在计算表达式时变量的类型无关紧要。只有稍后将其值分配给变量时才有意义。

举个例子

int i = -1;
long m = i << (byte) 16;

上面的表达式涉及一个移位运算符和两个操作数,一个是 int 类型,另一个是 byte 类型。

The JLS states the following concerning shift operators and their operands

Unary numeric promotion (§5.6.1) is performed on each operand separately.

which is

Otherwise, if the operand is of compile-time type byte, short, or char, it is promoted to a value of type int by a widening primitive conversion (§5.1.2).

因此 byte 值被扩展为 int。所以不回答你的第一个问题。

表达式的结果将是 int 类型的值(32 位)。它必须分配给一个 long(64 位)变量,因此该值将是 widened to a long在分配之前。

来自JLS again

The integral types are byte, short, int, and long, whose values are 8-bit, 16-bit, 32-bit and 64-bit signed two's-complement integers, respectively, and char, whose values are 16-bit unsigned integers representing UTF-16 code units (§3.1).

这就是它们的存储方式。

关于java - Java 的位移运算符在底层是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32461745/

相关文章:

java - 如何知道 Java 应用程序是否使用 MVC 设计模式?

assembly - "shift operates on bits individually"是什么意思?

scala - Scala中的位字段

c++ - C++中的整数字节交换

java - 位操作修改位以包含数字

c++ - 如何将两位添加到十六进制

c++ - 有没有一种快速的方法/技巧可以在文件的开头添加一位?

java - mule-domain-config 中的 org.xml.sax.SAXParseException : Failed to read schema document mule-mongo. xsd

java - Spring数据ldap配置

java - 在Java中比较字符串数组中的元素