加法
十進制的加法運算
例子:5 + 17 = 22
- 只做各位相加不進位,結(jié)果為 12(個位數(shù) 5 和 7 相加不進位是 2,十位數(shù) 0 和 1 相加結(jié)果為1);
- 做進位葛躏,5 + 7 中有進位,進位的值是 10悠菜;
- 把前面兩個結(jié)果加起來舰攒, 12 + 10 的結(jié)果是 22,剛好 5 + 12 = 22悔醋;
二進制的加法運算
例子: 5 + 17 = 22(5 的二進制是 101摩窃,17 的二進制是 10001)
- 各位相加不進位,結(jié)果是 10100芬骄;
- 記下進位猾愿,只在最后一位相加時產(chǎn)生一個進位,結(jié)果是二進制的 10账阻;
- 把前兩步的結(jié)果相加蒂秘,結(jié)果是 10110,換算成十進制是 22淘太;
位運算代替加法運算
- 不考慮進位材彪,對每一位相加。0 加 0 與 1 加 1 的結(jié)果都是 0琴儿, 0 和 1 與 1 和 0 的結(jié)果都是 1,這和異或的結(jié)果是一樣的嘁捷;
- 進位造成,對 0 加 0、 0 加 1雄嚣、 1 加0 而言晒屎,都不會產(chǎn)生進位i喘蟆,只有 1 加 1時,會向前產(chǎn)生一個進位鼓鲁,把兩個數(shù)做與運算蕴轨,然后再向左移動一位;
- 把兩邊步驟的結(jié)果相加骇吭,就相當(dāng)于輸入前兩部的結(jié)果來遞歸調(diào)用自己橙弱;
代碼
int AddWithoutArithmetic(int num1, int num2)
{
if(num2 == 0)
return num1;
int sum = num1 ^ num2;
int carry = (num1 & num2) << 1;
return AddWithoutArithmetic(sum, carry);
}
減法
- 減法相當(dāng)于加法加上減數(shù)的相反數(shù);
- 二進制的相反數(shù)就是取反加 1燥狰;
代碼
//減法:這個和加法一樣了棘脐,首先取減數(shù)的補碼,然后相加龙致。
int negative(int a)//取補碼
{
return add(~a,1);
}
int sub(int a,int b)
{
return add(a,negative(b));
}
乘法
例子:a × b = ab
- 各位上的數(shù)如果為 1蛀缝,則加上 a,如果不為 1目代,則不加屈梁;
- b 右移一位,a 左移一位榛了;
代碼
//正數(shù)乘法運算
int Pos_Multiply(int a,int b)
{
int ans = 0;
while(b)
{
if(b&1) //b最后一位是否為1
ans = Add(ans, a);
a = (a<<1);
b = (b>>1);
}
return ans;
}
除法
除法就是由乘法的過程逆推在讶,依次減掉(如果x夠減的)y(231),y(230),...y8,y4,y2,y1。減掉相應(yīng)數(shù)量的y就在結(jié)果加上相應(yīng)的數(shù)量忽冻。
代碼
//除法就是由乘法的過程逆推真朗,依次減掉(如果x夠減的)y^(2^31),y^(2^30),...y^8,y^4,y^2,y^1。減掉相應(yīng)數(shù)量的y就在結(jié)果加上相應(yīng)的數(shù)量僧诚。
int Pos_div(int x,int y)
{
int ans=0;
for(int i=31;i>=0;i--)
{
// //比較x是否大于y的(1<<i)次方遮婶,避免將x與(y<<i)比較,因為不確定y的(1<<i)次方是否溢出
if( (x>>i) >=y )
{
ans+=(1<<i);
x-= (y<<i);
}
}
return ans;
}