有些工作幾年的同學(xué)已經(jīng)忘記了大學(xué)學(xué)過(guò)的計(jì)算機(jī)基礎(chǔ)(沒(méi)錯(cuò),說(shuō)的就是我)析藕,于是把一些基礎(chǔ)的東西拎出來(lái)復(fù)習(xí)一下召廷。
原碼、反碼账胧、補(bǔ)碼
首先要知道竞慢,計(jì)算機(jī)使用的是補(bǔ)碼。為什么要用補(bǔ)碼呢治泥?慢慢往下看筹煮。
-
原碼
原碼就是符號(hào)位加上真值的絕對(duì)值, 即用第一位表示符號(hào), 其余位表示值. 比如如果是8位二進(jìn)制:
[+1]原 = 0000 0001
[ -1]原 = 1000 0001
第一位是符號(hào)位,所以8位二進(jìn)制數(shù)的取值范圍是[1111 1111,0111 1111]居夹,即[-127,127]败潦。
-
反碼
正數(shù)的反碼和原碼相同,負(fù)數(shù)的反碼為:符號(hào)位不變准脂,數(shù)據(jù)位取反劫扒。
[+1]反= 0000 0001
[-1]反= 1111 1110
-
補(bǔ)碼
正數(shù)的補(bǔ)碼等于原碼。負(fù)數(shù)的補(bǔ)碼等于反碼+1狸膏。
[+1] = [0000 0001]原 = [0000 0001]反 = [0000 0001]補(bǔ)
[-1] = [1000 0001]原 = [1111 1110]反 = [1111 1111]補(bǔ)
計(jì)算機(jī)為什么使用補(bǔ)碼沟饥?
對(duì)于人來(lái)說(shuō),可以理解符號(hào)位的概念,計(jì)算加減時(shí)會(huì)計(jì)算真值位贤旷。但是計(jì)算機(jī)并不理解符號(hào)位广料,需要設(shè)計(jì)一種符號(hào)位也可以參與加減的方法。同時(shí)減法可以轉(zhuǎn)換成加法幼驶,于是對(duì)于計(jì)算機(jī)來(lái)說(shuō)更簡(jiǎn)單了艾杏。
假設(shè)符號(hào)位參與運(yùn)算,首先來(lái)看原碼:
計(jì)算十進(jìn)制的 1-1=0盅藻;
1 - 1 = 1 + (-1) = [00000001]原 + [10000001]原 = [10000010]原 = -2
很明顯是錯(cuò)的糜颠。
現(xiàn)在用反碼來(lái)運(yùn)算:
1 - 1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原= [0000 0001]反 + [1111 1110]反 = [1111 1111]反 = [1000 0000]原 = -0
從結(jié)果來(lái)看。真值部分是正確的萧求,問(wèn)題出在符號(hào)位其兴。雖然我們知道-0
和0
都是0
,但是這個(gè)-
是沒(méi)有意義的夸政,怎么能干掉它呢?
來(lái)看補(bǔ)碼的運(yùn)算結(jié)果:
1-1 = 1 + (-1) = [0000 0001]原 + [1000 0001]原 = [0000 0001]補(bǔ) + [1111 1111]補(bǔ) = [0000 0000]補(bǔ)=[0000 0000]原
很完美守问,結(jié)果是正確的,也沒(méi)有符號(hào)位問(wèn)題耗帕。
所以,計(jì)算機(jī)就用補(bǔ)碼來(lái)表示數(shù)據(jù)啦体啰。
使用補(bǔ)碼, 不僅僅修復(fù)了0的符號(hào)以及存在兩個(gè)編碼的問(wèn)題, 而且還能夠多表示一個(gè)最低數(shù). 這就是為什么8位二進(jìn)制, 使用原碼或反碼表示的范圍為[-127, +127], 而使用補(bǔ)碼表示的范圍為[-128, 127]嗽仪。
計(jì)算機(jī)用補(bǔ)碼,把符號(hào)位參與運(yùn)算沽翔,這其中有什么數(shù)學(xué)原理呢窿凤?有興趣的同學(xué)可以了解一下同余定理。
位運(yùn)算
Java里保留了二進(jìn)制的位運(yùn)算操作雳殊,日常開(kāi)發(fā)中位運(yùn)算不是很常用,但是巧妙的使用位運(yùn)算可以大量減少運(yùn)行開(kāi)銷威恼,優(yōu)化算法寝并。
&
:按位與。都為1時(shí)為1衬潦,否則為0
|
:按位或。有一個(gè)為1時(shí)就為1弦牡,否則為0
~
:非漂羊。取反
^
:按位異或。相同為0走越,不同為1
<<
:左位移運(yùn)算符。左邊溢出的被丟棄旨指,右邊補(bǔ)0
>>
:帶符號(hào)右位移運(yùn)算符。正數(shù)時(shí)左邊補(bǔ)0谆构,負(fù)數(shù)時(shí)補(bǔ)1
<<<
:無(wú)符號(hào)右移運(yùn)算符。不考慮符號(hào)位呵晨,高位補(bǔ)0,低位溢出時(shí)丟棄
計(jì)算機(jī)怎么計(jì)算加法何荚?
當(dāng)然是用位運(yùn)算實(shí)現(xiàn)的猪杭。
計(jì)算機(jī)計(jì)算二進(jìn)制加法是分三部,第一步為將兩個(gè)加數(shù)轉(zhuǎn)換為二進(jìn)制數(shù)皂吮,計(jì)算兩個(gè)加數(shù)不需要進(jìn)位的和(利用異或運(yùn)算 ^ ),得出的結(jié)果蜂筹。第二部將兩個(gè)加數(shù)進(jìn)行與運(yùn)算(&)。第三部利用與運(yùn)算得到結(jié)果進(jìn)行左移運(yùn)算(<<)(同時(shí)為計(jì)算兩個(gè)加數(shù)需要進(jìn)位的和),得出結(jié)果艺挪。將或異運(yùn)算的結(jié)果和左移運(yùn)算的結(jié)果作為兩個(gè)新的加數(shù),重復(fù)此操作口蝠。直到當(dāng)與運(yùn)算的結(jié)果為0,則異或運(yùn)算的結(jié)果則為兩個(gè)加數(shù)的和所對(duì)應(yīng)的二進(jìn)制數(shù)傲霸。