有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

位操作Java的位移位操作符是如何工作的?

我没有研究它,直到最近才发现bit shiftstwo's complement的申请。那么,你能不能用简单的英语解释一下,假设我对IP地址、位操作和Java数据类型几乎一无所知

今天,我发现了以下代码(缩写):

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

现在,这是IP子网屏蔽。我知道我需要从4块8位(即4字节)开始,所有位都必须“打开”:11111111 11111111 1111111 1111111接下来,零从右边移入,在这种情况下,值为16位;所以我们得到了11111111 11111111 00000000 0000000,面具

但我确实有几个问题:

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

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


共 (2) 个答案

  1. # 1 楼答案

    实际上,您的m变量是long类型是令人困惑的,因为IP地址是32位的,并且对应于int。你的右手边确实是int,只有在完全计算之后,它才扩展到long(64位)。回答您的问题:

    1. 没有,你可以去掉石膏
    2. 结果实际上是int类型,但会被转换为long,因为m类型需要它
    3. 二的补语并没有“适用”于任何东西,真的。数字-1在二的补码中被编码。你需要一些的方法来表示负数,除了位什么都没有。另外,二的补码在这里起到了一个副作用:它大约是-1被编码为所有1位
    4. 这都只是一个32位的块向左移位,零填补了空缺。然后,为了转换为long,在左侧再添加32个1位
  2. # 2 楼答案

    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 ^{}

    来自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).

    这就是它们的存储方式