zoukankan      html  css  js  c++  java
  • 【C++】位运算实现加减乘除

      1 #include<iostream>
      2 #include<assert.h>
      3 using namespace std;
      4 
      5 // 位运算实现加减乘除
      6 
      7 int myAdd(int num1, int num2)
      8 {
      9     if (num2 == 0)    return num1;
     10     int sum = 0, carry = 0;
     11     sum = num1 ^ num2;    // 按位抑或
     12     carry = (num1 & num2) << 1;
     13     return myAdd(sum, carry);
     14 }
     15 
     16 int myAddIter(int num1, int num2)
     17 {
     18     int ret = 0;
     19     while (num2)
     20     {
     21         ret = num1 ^ num2;
     22         num2 = (num1 & num2) << 1;
     23         num1 = ret;
     24     }
     25     return ret;
     26 }
     27 
     28 int myNeg(int num1)
     29 {
     30     // 正数到负数的补码表示: 取反加1
     31     return myAdd(~num1, 1);
     32 }
     33 
     34 int myMinus(int num1, int num2)
     35 {
     36     return myAdd(num1, myNeg(num2));
     37 }
     38 
     39 // (2^0)*k0 + (2^1)*k1 + (2 ^2)*k2 + ... + (2^31)*k31
     40 int myPosMulti(int num1, int num2)
     41 {
     42     int ret = 0;
     43     while (num2)
     44     {
     45         if (num2 & 1)    // 对应当前num2的最低位是1
     46             ret = myAdd(ret, num1);
     47         num1 <<= 1;    // num1 = num1 * 2
     48         num2 >>= 1;    // num2的当前位用过了就右移
     49     }
     50     return ret;
     51 }
     52 
     53 int myMultiply(int num1, int num2)
     54 {
     55     if (num1 >= 0 && num2 >= 0)
     56         return myPosMulti(num1, num2);
     57     if (num1 < 0 && num2 >= 0)
     58         return myNeg(myPosMulti(myNeg(num1), num2));
     59     if (num1 >= 0 && num2 < 0)
     60         return myNeg(myPosMulti(num1, myNeg(num2)));
     61     if (num1 < 0 && num2 < 0)
     62         return myPosMulti(myNeg(num1), myNeg(num2));
     63 }
     64 
     65 // 除法就是由乘法的过程逆推,依次减掉(如果x够减的)y^(2^31),y^(2^30),...y^8,y^4,y^2,y^1。减掉相应数量的y就在结果加上相应的数量。
     66 int myPosDiv(int num1, int num2)
     67 {
     68     num1 = num1 > 0 ? num1 : myNeg(num1);
     69     num2 = num2 > 0 ? num2 : myNeg(num2);
     70     if (num1 < num2)
     71         return 0;
     72     long long op = num2;
     73     int ret = 0;
     74     int flag;
     75     int curBit = 0;
     76     assert(num2 != 0);
     77     while (op <= num1)
     78     {
     79         op <<= 1;
     80         ++curBit;
     81     }
     82     op >>= 1;
     83     --curBit;
     84 
     85     while (op >= num2)
     86     {
     87         if (num1 >= op)
     88         {
     89             num1 -= op;
     90             ret += 1 << curBit;
     91         }
     92         op >>= 1;
     93         --curBit;
     94     }
     95     return ret;
     96 }
     97 
     98 int myPosDivByMinus(int num1, int num2)
     99 {
    100     int ret = 0;
    101     while (num1 >= num2)
    102     {
    103         num1 = myMinus(num1, num2);
    104         ret = myAdd(ret, 1);
    105     }
    106     return ret;
    107 }
    108 
    109 int myPosComp(int num1, int num2)
    110 {
    111     bool isZero(int);
    112     int temp = 1;
    113     num2 = num1 ^ num2;
    114     if (isZero(num2))    return 0;
    115     while (num2 >>= 1)
    116         temp <<= 1;
    117     return temp & num1;
    118 }
    119 
    120 
    121 int myDivide(int num1, int num2)
    122 {
    123     if ((num1 > 0 && num2 > 0) || (num1 < 0 && num2 < 0))
    124         return myPosDiv(num1, num2);
    125     else
    126         return myNeg(myPosDiv(num1,num2));
    127 }
    128 
    129 bool isNeg(int num)
    130 {
    131     return num & 0x8000;
    132 }
    133 
    134 bool isZero(int num)
    135 {
    136     return !(num & 0xFFFF);
    137 }
    138 
    139 bool isPos(int num)
    140 {
    141     return !(num & 0x8000) && (num & 0xFFFF);
    142 }
    143 
    144 //int myMod(int a, int b)
    145 //{
    146 //
    147 //}
    148 
    149 int divide(int dividend, int divisor) {
    150     int ret = 0;
    151     long long curDividend, curDivisor, op;
    152     bool flag;
    153     int curBit = 0; // 记录商的1在哪一位
    154     if (divisor == 0)   return INT_MAX; // 往负数方向溢出咋整
    155     if ((dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0))
    156         flag = 0;   // 负数
    157     else
    158         flag = 1;
    159 
    160     curDividend = abs(dividend);
    161     curDivisor = abs(divisor);
    162 
    163     if (curDividend < curDivisor)   return 0;
    164 
    165     op = curDivisor;
    166     while (op <= curDividend)
    167     {
    168         ++curBit;
    169         op = op << 1;
    170     }
    171     op = op >> 1;
    172     --curBit;
    173 
    174     while (op >= curDivisor)
    175     {
    176         if (curDividend >= op)
    177         {
    178             curDividend -= op;
    179             ret += 1 << curBit;
    180         }
    181         op = op >> 1;
    182         --curBit;
    183     }
    184 
    185     if (flag)
    186         return ret;
    187     return -ret;
    188 }
    189 
    190 int main()
    191 {
    192     //INT_MIN -2147483648 INT_MIN 2147483647
    193     int a = INT_MAX;    // 
    194     int b = -1;
    195     cout << "myAdd: " << myAdd(a, b) << endl;
    196     cout << "myMinus: " << myMinus(a, b) << endl;
    197     cout << "myMultiply: " << myMultiply(a, b) << endl;
    198     cout << "myDivide: " << myDivide(a, b) << endl;
    199     // -1010369383, -2147483648
    200     cout << "Leetcode: " << divide(-1010369383, INT_MIN) << endl;
    201     //cout << "myMod: " << myMod(a, b) << endl;
    202     system("pause");
    203     return 1;
    204 }
  • 相关阅读:
    for 续1
    8 解决多线程对共享数据出错
    7 多线程 全局变量
    6 线程threading
    5 多进程copy文件
    4 进程间通信Queue [kjuː]
    3 进程池
    2 进程multiprocessing [mʌltɪ'prəʊsesɪŋ] time模块
    1 多任务fork Unix/Linux/Mac
    16 pep8 编码规范
  • 原文地址:https://www.cnblogs.com/helloWaston/p/4624607.html
Copyright © 2011-2022 走看看