【问题标题】:Arithmetic with byte in JavaJava中的字节算术
【发布时间】:2018-08-15 11:47:22
【问题描述】:

我知道byteshort 数据类型在Java 中没有给予2's complement 处理。我的这个陈述的意思在下面的例子中得到了证明:

byte b1 = 0xFF;    //error, 255 is outside the range of byte
byte b2 = 0b1100;    //12 is stored, and not -4

现在,举个例子:

byte b3 = 0;
b3 += 0xFF;
System.out.println(b3);    //prints -1 on the console

上面例子中的第2行是否应该抛出错误,单个0xFF255并且在byte范围之外?

另外,byteshort 是什么不公平的游戏?我的意思是,为什么不使用2's complement system 来解释它们,就像intlong 一样?

【问题讨论】:

  • 没有给出 2 的补码 哈?你知道吗?听说过溢出吗?
  • 为什么b2 会是-4?你认为一个字节是多少位?
  • 哦,哦,我错了。它读作 0000_1100,不是吗?因此,它存储了 12 个。该死的,多么幼稚。

标签: java binary


【解决方案1】:

它们是 2 的补码 - 不知道你从哪里得到的(但这是错误的)。这个:

byte b1 = 0xFF;

不起作用,因为它确实超出了byte 的范围。但是:

byte b3 = 0;
b3 += 0xFF;

因为+= 是在更大范围的int 上完成的,所以您将它分配给byte,它占用最后8 位,恰好是-1

【讨论】:

  • 可能是我表述错误。意思是假设 int i = 0xFFFFFFFF。这不应该引发错误吗,因为它超出了 int 的范围?
  • 是的,他们可以。但是 32 个 1 = 2 的补码中的 -1,对吧?因此,它不会引发错误。为什么然后将 8 个(如果是字节)解释为 255 而不是 -1?
  • @PrashantPandey 因为0xFF 是一个常量 并且没有byte 常量,对于int
  • 哦,这就是问题所在。非常感谢您抽出宝贵时间,请原谅我的幼稚问题。
【解决方案2】:

您应该阅读 Java 语言规范,而不是试图通过逻辑推理来解决这个问题:

第 1 点。byteshort 是有符号类型。

"整数类型的值是以下范围内的整数:

  • 对于 byte,从 -128 到 127(含)
  • 对于 short,从 -32768 到 32767,含”源 JLS 4.2.1

第 2 点。有符号整数类型是 2 的补码。

"整数类型为byteshortintlong,其值分别为8位、16位、32位和64位有符号二进制补码整数和char,其值是代表 UTF-16 代码单元的 16 位无符号整数(第 3.1 节)。”来源JLS 4.2

第 3 点。您不能将 int 变量分配给 byte 变量。

如果右侧操作数的类型与变量类型 (§5.2) 的赋值不兼容,则会发生编译时错误。来源JLS 15.26.1

第 4 点。您可以将 int 编译时常量表达式分配给 byte 变量假设表达式的值在 byte 的范围内。

“另外,如果表达式是byteshortcharint类型的常量表达式(§15.28):

  • 如果变量的类型为byteshortchar,则可以使用缩小原语转换,并且常量表达式的值可以在变量的类型中表示。" 来源JLS 5.2

第 5 点。b3 += 0xFF 等价于 b3 = (byte)(b3 + 0xFF)

来源JLS 15.26.2

第 6 点。没有 byteshort 文字。

来源JLS 3.10.1

【讨论】:

  • 实际上,我刚刚读到Java中没有字节和短文本(JVM不知道字节和短)。这就是问题所在。
  • 不正确。 JVM 确实知道byteshort。它比你想象的要复杂。
  • 哦,是这样吗?我是从stackoverflow.com/a/317861/6714426 那里得到的。此外,我可以在某处读到关于此的内容吗?
  • 参考JVM spec 2.3.1。复杂之处在于在byte/short/char 上没有用于进行算术、按位或比较的操作码。但是有一些操作码可以与这些类型相互转换。例如,i2bbaload
  • 我已经评论了stackoverflow.com/a/317861/6714426。不准确。
【解决方案3】:

如果你想转换 -minus 值,java 8 自带实用方法来支持无符号操作

byte b1 = (byte) 0xFF;
Byte.toUnsignedInt(b1); // this method will return 255

【讨论】:

    猜你喜欢
    • 2016-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多