Java如何计算负数?

时间:2013-07-05 20:17:49

标签: java bit

我使用~操作进行位操作,我只是想知道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
  3. 但这对我没有意义。

2 个答案:

答案 0 :(得分:12)

最高位是简单符号位的假设错误。 Java以及大多数现代编程语言(和硬件体系结构)都使用所谓的two's complement表示数字。 (巧合的是,这个位确实表示符号,但不是你所期望的那样,即150和-150的差异比它们表示中的符号位更多。)

这种表示首先看起来似乎是一个奇怪的选择,但它实际上使得诸如向负数(或其变体)添加正数的操作自动地起作用,而不会使处理器必须检查特殊情况。 / p>

根据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.

答案 1 :(得分:3)

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.