[转]C++二进制完成加减乘除
?
首先介紹計(jì)算機(jī)的二進(jìn)制碼
二進(jìn)制常用的有原碼,反碼和補(bǔ)碼,他們都是由最左邊的一個(gè)符號(hào)位和右邊的數(shù)值位構(gòu)成。在計(jì)算機(jī)中為了更低成本的計(jì)算,數(shù)據(jù)都是用補(bǔ)碼來(lái)存儲(chǔ)和運(yùn)算的。
原碼
最高位表示符號(hào)位(0代表正數(shù),1代表負(fù)數(shù))。剩下的位數(shù),是這個(gè)數(shù)的絕對(duì)值的二進(jìn)制。
比如 一個(gè)int變量大小為4字節(jié),在32位的編譯器中的二進(jìn)制表示就是00000000 00000000 00000000 00000000
那么10 的原碼就是00000000 00000000 00000000 00001010
?10的原碼就是 10000000 00000000 00000000 00001010
反碼
正數(shù)的反碼和其原碼是一樣的
負(fù)數(shù)的反碼就是在其原碼的基礎(chǔ)上 符號(hào)位不變 其他位取反。
10的反碼就是00000000 00000000 00000000 00001010 和原碼一樣
?10的反碼就是11111111 11111111 11111111 11110101
補(bǔ)碼
正數(shù)的補(bǔ)碼就是其原碼
負(fù)數(shù)的補(bǔ)碼就是在其反碼的基礎(chǔ)上+1
10的補(bǔ)碼就是00000000 00000000 00000000 00001010
?10的補(bǔ)碼就是 11111111 11111111 11111111 11111011
總結(jié)一下
計(jì)算機(jī)系統(tǒng)中,數(shù)值一律用補(bǔ)碼來(lái)表示:因?yàn)檠a(bǔ)碼可以使符號(hào)位和數(shù)值位統(tǒng)一處理,同時(shí)可以使減法按照加法來(lái)處理。
二進(jìn)制編碼:數(shù)值編碼分為原碼,反碼,補(bǔ)碼,符號(hào)位均為0正1負(fù)。
原碼 -> 補(bǔ)碼: 數(shù)值位取反加1
補(bǔ)碼 -> 原碼: 對(duì)該補(bǔ)碼的數(shù)值位繼續(xù) 取反加1
補(bǔ)碼 的絕對(duì)值(稱為真值):正數(shù)的真值就是本身,負(fù)數(shù)的真值是各位(包括符號(hào)位)取反加1(即變成原碼并把符號(hào)位取反).
介紹基本的位操作
^:按位異或;&:按位與; | :按位或
b -> -b : 各位(包括符號(hào)位)取反加1
用位操作實(shí)現(xiàn)加法運(yùn)算
我們先不考慮進(jìn)位,在1位數(shù)的加法上,如下
1. 1+1=0
2. 1+0=1
3. 0+1=1
4. 0+0=0
很明顯上面幾個(gè)表達(dá)式我們可以用異或進(jìn)行統(tǒng)一
1. 1^1=0
2. 1^0=1
3. 0^1=1
4. 0^0=0
這樣我們就完成了最基礎(chǔ)的一位數(shù)的加法,但是怎么計(jì)算二位以上的加法呢?我們發(fā)現(xiàn)現(xiàn)在方法的問(wèn)題在于不能夠獲取進(jìn)位,于是我們通過(guò)觀察一位數(shù)的加法的式子,發(fā)現(xiàn)只有兩個(gè)數(shù)位都是1的時(shí)候才會(huì)有進(jìn)位,其他都不進(jìn)位,這不是和&很像嗎? 我們通過(guò)把+換成&得到下式
1. 1&1=0 不進(jìn)位
2. 1&0=1 不進(jìn)位
3. 0&1=1 不進(jìn)位
4. 0&0=0 進(jìn)位
那么我們把所有位進(jìn)行&操作,然后<<左移一位,不就可以當(dāng)作加數(shù)當(dāng)前的進(jìn)位嗎?
到這里我們就完整解決了二進(jìn)制相加問(wèn)題中,對(duì)應(yīng)位的相加和進(jìn)位的問(wèn)題
1. x^y 加法
2. (x&y)<<1 進(jìn)位操作
那么總結(jié)一下:
定理1:設(shè)a,b為兩個(gè)二進(jìn)制數(shù),則a+b=a^b+(a&b)<<1。
證明:
a^b是不考慮進(jìn)位時(shí)加法結(jié)果。當(dāng)二進(jìn)制位同時(shí)為1時(shí),才有進(jìn)位,因此 (a&b)<<1是進(jìn)位產(chǎn)生的值,稱為進(jìn)位補(bǔ)償。將兩者相加便是完整加法結(jié)果。
定理2:使用定理1可以實(shí)現(xiàn)只用位運(yùn)算進(jìn)行加法運(yùn)算。
證明:
利用定理1中的等式不停對(duì)自身進(jìn)行迭代。每迭代一次,進(jìn)位補(bǔ)償右邊就多一位0,因此最多需要加數(shù)二進(jìn)制位長(zhǎng)度次迭代,進(jìn)位補(bǔ)償就變?yōu)?,這時(shí)運(yùn)算結(jié)束。
那么我們可以根據(jù)上面的定理得到實(shí)際的C++代碼如下
int add(int a, int b){int re = a;while(b){int tmp = a;a = a^b;b = (tmp&b)<<1;re = a;}return re; }用位操作實(shí)現(xiàn)減法
減法和加法原理相同,減去一個(gè)數(shù)相當(dāng)于加上這個(gè)數(shù)的相反數(shù),所以完全可以利用加法操作,唯一需要做的就是求出被減數(shù)的相反數(shù)。
求相反數(shù)的方法:每一位取反,末位加一。
代碼如下:
用位操作實(shí)現(xiàn)乘法
二進(jìn)制的乘法同十進(jìn)制的乘法并無(wú)什么不一樣,對(duì)于a?b每次只需要將a左移對(duì)應(yīng)的位,然后同上一次的結(jié)果相加即可
當(dāng)b的對(duì)應(yīng)位為1的時(shí)候,對(duì)a左移一位相加即可
當(dāng)b的對(duì)應(yīng)位位0的時(shí)候,對(duì)a左移一位,但是不相加
注意到我們上面的操作都是不包括符號(hào)位的,因此我們單獨(dú)考慮符號(hào)位。
代碼如下
二進(jìn)制除法
同乘法一樣,除法一樣可以用減法來(lái)代替,當(dāng)a≥b才可以上商,在每次上一個(gè)商(也就是商值加1)之后,a=a?b
代碼如下
---------------------
作者:harry_128
來(lái)源:CSDN
原文:https://blog.csdn.net/harry_128/article/details/80150502
版權(quán)聲明:本文為作者原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!
內(nèi)容解析By:CSDN,CNBLOG博客文章一鍵轉(zhuǎn)載插件
總結(jié)
以上是生活随笔為你收集整理的[转]C++二进制完成加减乘除的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: [转]IntelliJ IDEA 202
- 下一篇: [转]Webpack5(从入门到精通)