為什麼-0的補碼是00000000?
都知道負數求補碼的方式是原碼求反碼,再加1,可是加1時符號位參與運算嗎?
以-0為例(也只有這一個例子) -0的原碼是10000000 反碼是11111111 補碼在反碼基礎上+1 如果符號位不參與運算,得到的是10000000(忽略溢出)可是-0的補碼是00000000 是因為符號位參與了運算才導致這樣的嗎很抱歉在知乎問這樣基礎的問題,但是網上有各種說法,很多都說符號位不參與運算,可這樣得到的的確該是10000000吧?
補碼本質是用來構成一個環,以實現一個同餘運算。你可以認為所有定位長的加減乘除都是處於同餘系情況下的:以32位整數為例,你取得的結果永遠是2^32次方的餘數,這與有無符號無關。
你叫加法器算一個1+2,然而加法器其實做的是個同餘加法,即
這樣的作用是無論有符號還是無符號的運算,都可以共用同樣的加法器(乘法器)。然後我們知道,4294967296的餘數總共就4294967296種,分別是0~4294967295。但是我們希望表示一個負數,那怎麼做呢?
於是乎就用4294967295來表示了。考慮到取值範圍,以及為了方便區分,我們定義有一半的數是正數、一半的數是負數,恰恰就是二進位最高位為1則是負數,最高位為0則表示正數範圍,這個就是補碼的本質。至於補碼的計算方法,也就是取反加1,完全是因為:這與『符號位』無關,它的逆運算,其實求解的是所以說到底還是個同餘數論的問題。
所以你看,把x=0代入剛剛的同餘方程,完全成立。負數的補碼形式等於對應的正數的原碼取反加一。
例如-1的補碼形式等於正1的原碼取反加1。以8位為例,正一的原碼為00000001,取反11111110,加一是11111111。
根據這個規律,-0的補碼形式等於對應的正數0的原碼00000000,取反為11111111,加1是00000000,答案仍然是0。
題主你把原碼的概念理解得不準確。應當使用對應的正數求原碼,而並不存在所謂帶符號位的負數原碼。在補碼體系里沒有符號位一說,雖然最高位為一的恰好是負數,但在補碼體系里它不是符號位,而是正常數據的一部分。補碼錶示法里10000000是-128,沒有-0隻有0。
討論補碼就沒有-0這個概念了,補碼的存在意義就是為了消除-0
思考一下為什麼要反碼+1,目的就是為了正負相加值溢出後歸為0啊。比如+3表示為00000011 -3表示為11111100+1=11111101(反碼加1)-3+3就是11111111+1溢出後就直接為0了剛好符合-3+3=0的性質,多精妙的設定。0的反碼只不過把溢出放在+1這個環節了。
除了-0這個特例以外,符號位是否參與運算並不影響結果,而在補碼中把-0剔除了,把10000000變成-128,其補碼是128,溢出了。從最終結果看,可以認為是符號位參與了運算,但是也可以認為是128超出表示範圍,結果未定義。總之,符號是否參與運算對結果沒有影響,可以認為不存在-0。
-0沒有補碼
丟開教科書式的概念,想想為什麼要有補碼這個東西,為什麼符號位會產生。定義:
原碼錶示法是機器數的一種簡單的表示法。其符號位用0表示正號,用:表示負號,數值一般用二進位形式表示。
機器數的反碼可由原碼得到。如果機器數是正數,則該機器數的反碼與原碼一樣;如果機器數是負數,則該機器數的反碼是對它的原碼(符號位除外)各位取反而得到的。
機器數的補碼可由原碼得到。如果機器數是正數,則該機器數的補碼與原碼一樣;如果機器數是負數,則該機器數的補碼是對它的原碼(除符號位外)各位取反,並在未位加1而得到的。
如果是為了考試,死記即可。但我總想搞清楚為什麼計算機裡面的數要這樣子表達?意義何在?-128的補碼為什麼是10000000?為什麼補碼有這麼奇怪的運算規則?計算機算減法的時候都需要從源碼到補碼的計算嗎?
思路
- 計算機裡面,只有加法器,沒有減法器,所有的減法運算,都必須用加法進行。
- 用補數代替原數,可把減法轉變為加法。出現的進位就是模,此時的進位,就應該忽略不計。
- 二進位下,有多少位數參加運算,模就是在 1 的後面加上多少個 0。
- 補碼就是按照這個要求來定義的:正數不變,負數即用模減去絕對值。
補充解釋一下「模」的概念,可以參照離散數學裡面的環:
考慮時鐘上時間的計算,假設現在時針指向數字3,若問「6小時前時針指向的數字是幾」,則可以:1. 將時針逆時針撥動6格。2. 將時針順時針撥動12 - 6 = 6格。兩者的結果是一樣的。這裡稱12為「模」。故有 3時 - 6個小時 = 3時 + (12 - 6個小時),這裡可以看到將減法轉換成加法的過程,即「加上模減去絕對值的差」。所以,假設模是10,有效位數為1,當我們計算 9 - 7 的時候:9 - 7 =&> 9 + (10 - 7) = 12,去掉最高的位後,得到2,這是正確的結果。作者的意思是說,計算機裡面所有數都以補碼形式保存,加減運算都是補碼之間的加法運算。然後作者提出了一個我之前沒聽過的觀點:
補數 和 補碼的定義式 裡面,根本就沒有什麼符號位。這最高位的1、0是自然出現的,並不是由人來規定的。
的確,符號位在補碼運算裡面是「模」,本身並不帶符號的意義。因為計算機將加法轉換成加上一個「負數」,而負數又以補碼的形式表現。補碼比源碼多一位,從這多出來的一位可以推斷出原來數字的正負號,所以成為了符號位。也可以這樣認為,留出一位(不全部佔滿)的原因是要用「模」來表示正負數。
也就是說,不是特意留出一個符號位,用1和0來表示正負號。而是補碼運算可以用最高位來表示正負,所以符號位誕生了。
那麼為什麼-128的補碼是10000000?可以這樣理解。-128是一個負數,所以它的補碼是它的「模」減去它的絕對值,即:
100000000 - 10000000 = 10000000
那麼為什麼負數補碼等於源碼的反碼加一呢?可以這樣推導:
100000000 - 10000000
= (11111111 + 00000001) - 10000000
= 11111111 - 10000000 + 1
= 01111111 + 1 //反碼加一
= 10000000
由此我們得知,在計算機裡面所有的數字都以補碼形式存儲。127存成01111111,-127存成11111111,算減法就變成算加法了,儘管你看到的是「-」號。
可以參考一下這個:原碼、反碼、補碼的產生、應用以及優缺點有哪些?
-0的補碼,按你說是100000000,注意到一件事,這個數字只有8位,所以最高位1其實溢出了,就是00000000…
補碼沒有-0,本身也沒有-0這個數,有的只有0
符號位既可以參與運算,也可以不動,其他位取反加一。
對於負零,按一個位元組,即10000000,符號位不變,其餘取反的結果為11111111,末位加一即變成九位100000000,捨去首位,就變成了00000000。
如果直接取絕對值,那麼10000000,就變成了00000000,按位取反,11111111,加一,捨去首位,得到同樣的結果。
某軟院老師精心授予,現在給你也說說。
x=0011,~x=1100,1=0001;x+~x+1=0011+1100+0001;~x+1 =1100+0001; ~x =1100; ~x-x =1100-0011=1001; -x =11001-1100=1101;-x=1101=~x+1;跟著C大的思路來回正負都驗證了一遍,以防萬一0和非0也各算了一遍,結論一致。
補碼運算不是連符號位都參與的么?考慮上符號位也就是正0的反碼加1,這樣就是00000000了
測試代碼:
if ((-0) == 0) { printf("0x%08x", (-0)); printf("0x%08x
", (-33)); }
結果:
0x00000000 0xffffffdf結論:
-0 == 00在計算機里是按照正數來算的。而正數的原碼等於補碼。手機碼字,不要討論格式問題。有關計算機的很多基礎,一本書就可以比較好的讓你全方位理解。 編碼:隱匿在計算機軟硬體背後的語言。
我嘗試用我粗淺的知識來答一下,
關於補碼的實際性質,我們只考慮4位數的補碼的二進位中的3個數 -1、0、1。他們用二進位補碼錶示為1111=-1(10進位)0000=0(10進位)0001=1(10進位)我們在實際運算中,-1+1=0,0+1=1,當我們用補碼代入的時候,結果依然正確,比如1111+0001=10000(1位溢出於是就是0000),0000+0001=0001。補碼基於這樣一個事實,-1應為負整數中的最大的值。這樣計算機就能用加法器算減法。補碼的計算方式應該是用0減去該負數的絕對值,比如-2,應當為0000-0010=1110(因為0000不夠減,可向前借1,相當於10000-0010).至於為什麼我們能按位取反+1,這是基於這樣一個事實一個數和它的按位取反的結果相加,和一定是1111,即-1,因此x+x1=-1,於是x+x1+1=0即x1+1=0-x=-x。例如0010+1101=1111,0010+1101+0001=(1)0000(溢出),1101+1=10000-0010=1110。另外關於題主的提到大-0的補碼,如果僅僅按照按位取反的定義來的話,-0應當等於1000,但是1000實際上是1001-0001的結果,所以補碼沒有-0,實際值應當是1001-0001=-7-1=-8
因為補碼並不是按位取反+1來定義的,所以當你用按位取反+1來定義-0的時候肯定是錯誤的參考:&<計算機組成與設計 硬體/軟體介面&>實際上,從數學的角度,確實不存在-0。在一個有符號位的系統中,符號位的權值是-2^n。比如一個8位數的有符號數11111111(b) = -2^7+2^6+2^5+2^4.....+2^0 = -1 。所以很容易看不出10000000(b) = -128。
補碼就沒有-0這個東西啊。。。。補碼只有一個0的概念。
如果你學了彙編你就懂了,沒學彙編別人講給你聽,我覺得你還是會很迷茫的。有個好的彙編老師教你,別看小甲魚的。
推薦閱讀:
※如何 硬體 軟體 都精通,或者說 都懂?
※國內DFRobot和Seeed Studio兩家哪家生產的Arduino電路板質量更好???
※友寶售貨機是全部自主研發么?
※雲主機會不會出現硬碟壞掉的問題?
※遊戲悍將的電源都是炸彈嗎?