每日一题 No.21 a/b(位操作符)【正整数】

来源:互联网 发布:js 字符串转时间戳 编辑:程序博客网 时间:2024/06/06 05:39

本题要求:

昨天写了2个数相乘,今天让我们来用位操作符写2个正整数相除吧,给定2个数a,b,计算a/b,并输出商和余数

输入格式:

a b

输出格式:

a/b的商 a/b的余数

输入样例:

155 152

输出样例:

1 3

解题思路 :

具体的看这里,我觉得写得特别好,反正我是看这个写出来的~
计算机数值中的乘法除法
以下是我个人对上面这个链接的理解,并根据理解写出的代码。
我们算二个数相除的时候,就拿最简单的5/3来说
5比3大,那我们怎么现实中是怎么得出5/3得1,余2的?
是不是因为5-3 = 2
2 < 3 所以,我们只减了一次,那么商就是1,余数就是2。
根据这个原理,我们可以算53/3
我们先得出5/3 是不是得1,余2
接着得出23(2*10+3),相应的,我们也要得到商10(1*10)
我们来算23/3。
是不是减去7个3,余2。
那么商就是10+7 ,余2
我们最后得到商17,余2;
在位运算里,当前位与相邻位只相差2倍,如果前面的比它后面的一位大,那么肯定就是商1,余x
我们在将商*2,余数*2,加起来。
就是将10进制的除法,转为了2进制。
根据以上原理来写,就很简单了~

代码 :

#include <iostream>using namespace std;  int add(int a, int b) {    if (b == 0) {        return a;    }    int s = a ^ b;    int c = (a & b) << 1;    return add(s, c);}int del(int a, int b) {    return add(a, add(~b, 1));}int getBitSize(int a) {    int i = 0;    int c = a;    while (c) {        c >>= 1;        i++;    }    return i;}bool getLeftBit(int a, int size, int n) {    int i = 0;    int c = a;    i = size - n;    while (i-- > 0) {        a >>= 1;    }    return a & 1;}pair<int, int> divide(int a, int b) {    int now = 0;    pair<int, int> p(0, 0);    int i = 1;    int size = getBitSize(a);     while (i <= size) {        p.second <<= 1;        p.second |= getLeftBit(a, size, i);        p.first <<= 1;         if (p.second >= b) {            p.second = del(p.second, b);            p.first |= 1;        }        i++;    }    return p;} int main() {    int a, b;    cin >> a >> b;    pair<int, int> h;    h = divide(a, b);    cout << h.first << " " << h.second << endl;    return 0;  }  
0 0