【问题标题】:How does Java calculate negative numbers?Java如何计算负数?
【发布时间】:2013-07-03 23:51:47
【问题描述】:

我使用~ 操作进行位操作,我只是想知道Java 是如何计算负数的?

我查看了 Java 文档:

“一元按位补码运算符“~”反转位模式;它可以应用于任何整数类型,使每个“0”成为“1”,每个“1”成为“0”。例如,一个字节包含 8 位;将此运算符应用于位模式为“00000000”的值会将其模式更改为“11111111”。”

所以如果int a = 60 (0011 1100),那么int c = ~a (1100 0011)

问题是,Java 如何计算负数使得1100 0011 = -611100 0011 计算 -61 的唯一方法是

  1. 最高位是符号位。
  2. -2^6 + 2^1 + 2^0 = -61

但这对我来说毫无意义。

【问题讨论】:

  • 您在正确的轨道上,最高位是符号位。请参阅Two's complement
  • 有符号位用于双精度和浮点数,这意味着您有 0.0 和 -0.0,整数不是这样完成的,char 是无符号的。

标签: java bit


【解决方案1】:

最高位是一个简单的符号位的假设是错误的。 Java 以及大多数现代编程语言(和硬件架构)使用所谓的two's complement 表示数字。 (巧合的是,位本身确实指示符号,但不是您期望的那样,即 150 和 -150 在其表示中的差异不仅仅是符号位。)

这种表示方式乍一看似乎是个奇怪的选择,但它实际上使诸如将正数加到负数(或其变体)之类的操作自动工作,而无需让处理器检查特殊情况。

根据the relevant Wikipedia article

该系统可用于简化计算机硬件上的算术实现。起初,将 0011 (3) 添加到 1111 (-1) 似乎给出了 10010 的错误答案。但是,硬件可以简单地忽略最左边的位以给出 0010 (2) 的正确答案。仍然必须存在溢出检查以捕获诸如求和 0100 和 0100 之类的操作。 因此,该系统允许在没有减法电路和检测数字符号的电路的情况下添加负操作数。此外,该加法电路还可以通过取一个数字的二进制补码来执行减法(见下文),这只需要一个额外的周期或它自己的加法器电路。为了实现这一点,电路只是假设存在一个额外的最左边的位 1。

See this related answer for an even more in-depth explanation with lots of nice, easy to understand examples.

【讨论】:

    【解决方案2】:

    Java 的 primitive numeral data types - intlongbyteshorttwo's complement 表示。这意味着什么:

    • 最高值是所有位设置为 1 的结果,除了 MSB。
      • 示例:0111 1111 = 127
    • MSB 设置为 1,所有其他位设置为 0 是 最低 值。
      • 示例:1000 0000 = -128

    这里唯一的负值是 MSB,所以如果我们把它分解成这个表示,我们会​​得到 -61:

    |-128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 |
    |  1  |  1 | 0  |  0 | 0 | 0 | 1 | 1 |
    
    -128 + 64 + 2 + 1 = -61.
    

    【讨论】:

      猜你喜欢
      • 2014-01-23
      • 2023-04-07
      • 1970-01-01
      • 2013-03-19
      • 1970-01-01
      • 2013-06-28
      • 1970-01-01
      • 2018-02-26
      • 1970-01-01
      相关资源
      最近更新 更多