加法
在二进制下,有异或操作、与操作、进位操作。异或操作是指两个数对应位置相同取0,不同取1;与操作是同为1取1,否则取0;进位就是各位置上的1或0左移若干位。
根据这些操作特性,加法可以分解成这样的过程,先是两个数异或,相当于得到了两个数没有进位的相加结果,然后两个数相与,相当于只有两个位置都是1的情况下该位置才能为1,再进一位,就等效了加法的进位操作,然后将这个无进位的相加结果与进位的结果进行相加,就等于一个完成的加法过程了。需要注意的是,无进位的相加结果和进位的结果的加法过程又可以分解,于是得到了一个递归过程。
1 2 3 4 5 6 7 8 int a = 13 ;int b = 42 ;while (b != 0 ) { int temp = a ^ b; b = (a & b) << 1 ; a = temp; } cout << a;
减法
学习四则运算的时候我们就知道,减去一个数等于加上这个数的相反数,二进制中相反数可以这样表示-x = ~x + 1
,也就是取反加1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 int a = 13 ;int b = 42 ;int c = ~b;b = 1 ; while (b != 0 ) { int tmp = c ^ b; b = (c & b) << 1 ; c = tmp; } while (c != 0 ) { int tmp = a ^ c; c = (a & c) << 1 ; a = tmp; } cout << a;
乘法
乘法运算就像是列一个二进制的乘法竖式一样。假设x
是乘数,y
是被乘数,那么如果x
的当前位是1,就把y
直接加到结果中,否则就下一轮操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 int a = 13 ;int b = 42 ;int res = 0 ;while (b != 0 ) { if ((b & 1 ) != 0 ) { int tmp_a = a; while ( tmp != 0 ) { int tmp = tmp_a ^ res; tmp_a = (res & tmp_a) << 1 ; res = tmp; } } a <<= 1 ; b >>= 1 ; } cout << res;
除法
除法就是乘法的逆运算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 int a = 42 , b = 4 ;int quotient = 0 ; int remain = a; for (int i = 31 ; i > -1 ; i--) { if ((remain >> i) >= b) { int temp = 1 << i; int temp2; while (temp != 0 ) { temp2 = quotient ^ temp; temp = (quotient & temp) << 1 ; quotient = temp2; } temp = ~(b << i); temp2 = 1 ; int temp3; while (temp2 != 0 ) { temp3 = temp ^ temp2; temp2 = (temp & temp2) << 1 ; temp = temp3; } while (temp != 0 ) { temp2 = remain ^ temp; temp = (remain & temp) << 1 ; remain = temp2; } } } cout << "位运算结果: " << quotient << endl;