2013-07-05 212 views
12

我使用~操作進行位操作,我只是想知道Java如何計算負數?Java如何計算負數?

我檢查了Java文檔:

「的一元按位求補運算符‘〜’反轉的位模式;它可以被應用到任何的整數類型的,使每一個‘0’的‘1’的並且每個「1」爲「0」,例如,一個字節包含8位;將該操作符應用於位模式爲「00000000」的值將其模式改變爲「11111111」。

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

問題是,Java如何計算負數以便1100 0011 = -61?計算1100 0011的唯一方法是-61

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

但是這對我沒有意義。

+3

你'在正確的軌道上,最高位是符號位。請參閱[二補](http://en.wikipedia.org/wiki/Two's_complement)。 – rgettman

+0

有符號位用於double和float,這意味着你有0.0和-0.0,整數不是這樣完成的,'char'是無符號的。 –

回答

12

假設最高位是簡單符號位錯誤。 Java以及大多數現代編程語言(和硬件體系結構)都使用所謂的two's complement表示法來表示數字。 (這個位本身巧合地確實表示了符號,但並不像你期望的那樣,即150和-150比它們表示中的符號位有更多的差異。)

這種表示看起來可能像一個奇怪的選擇,但它實際上使諸如爲負數(或其變體)添加正數的操作自動工作,而不使處理器必須檢查特殊情況。

根據the relevant Wikipedia article

該系統在簡化算法對計算機硬件的實施非常有用。起初添加0011(3)到1111(-1)似乎給出了10010的錯誤答案。但是,硬件可以簡單地忽略最左邊的位以給出0010(2)的正確答案。溢出檢查仍然必須存在以執行諸如求和0100和0100之類的操作。 因此,系統允許在沒有減法電路和檢測數字符號的電路的情況下添加負操作數。此外,該加法電路還可以通過取一個數字的二進制補碼來執行減法(見下文),這隻需要一個附加週期或其自己的加法器電路。爲了執行該操作,電路僅僅假裝存在一個額外的最左邊的位。

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

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.