• 位操作实现加减乘除四则运算


    1. 题目描写叙述

    怎样使用位操作分别实现整数的加减乘除四种运算?

    2. 解决方式
    须要熟练掌握一些常见功能的位操作实现,详细为:

    <1> 经常使用的等式:-n = ~(n-1) = ~n+1

    <2> 获取整数n的二进制中最后一个1:n&(-n) 或者 n&~(n-1)。如:n=010100。则-n=101100,n&(-n)=000100

    <3> 去掉整数n的二进制中最后一个1:n&(n-1),如:n=010100,n-1=010011,n&(n-1)=010000

    (1) 加法实现

    能够非常easy地用“异或”和“或”操作实现整数加法运算:相应位数的“异或操作”可得到该位的数值,相应位的“与操作”可得到该位产生的高位进位,如:a=010010,b=100111。计算过程例如以下:

    第一轮:a^b=110101。(a&b)<<1=000100。 因为进位(000100)大于0。则进入下一轮计算。a=110101,b=000100,a^b=110001,(a&b)<<1=001000,因为进位大于0,则进入下一轮计算:a=110001。b=001000。a^b=111001,(a&b)<<1=0,进位为0。终止。计算结果为:111001。

    代码例如以下:

    int add(int a, int b) {
    int carry, add;
    do {
    add = a ^ b;
    carry = (a & b) << 1;
    a = add;
    b = carry;
    } while(carry != 0);
    return add;
    }

    (2) 减法实现

    减法可非常easy地转化为加法:a - b = a + (-b) = a + (~b + 1 )

    代码例如以下:

    int subtract(int a, int b) {
    return add(a, add(~b, 1));
    }

    (3) 乘法实现

    先看一个实例:

    1011*1010:1011
    * 1010
    ----------
    10110 < 左移一位,乘以0010
    + 1011000 < 左移3位,乘以1000
    ----------
    1101110因而乘法能够通过系列移位和加法完毕。最后一个1可通过b&~(b-1)求得。可通过b& (b-1)去掉。为了高效地得到左移的位数。可提前计算一个map,代码例如以下:int multiply(int a, int b) {
    bool neg = (b < 0);
    if(b < 0)
    b = -b;
    int sum = 0;
    map<int, int> bit_map;
    for(int i = 0; i < 32; i++)
    bit_map.insert(pair<int, int>(1 << i, i));
    while(b > 0) {
    int last_bit = bit_map[b & ~(b - 1)];
    sum += (a << last_bit);
    b &= b - 1;
    }
    if(neg)
    sum = -sum;
    return sum;
    }

    (4)除法实现

    乘法可非常easy转化为减法操作,主要思想与乘法实现类似。代码例如以下:int divide(int a, int b) {
    bool neg = (a > 0) ^ (b > 0);
    if(a < 0)
    a = -a;
    if(b < 0)
    b = -b;
    if(a < b)
    return 0;
    int msb = 0;
    for(msb = 0; msb < 32; msb++) {
    if((b << msb) >= a)
    break;
    }
    int q = 0;
    for(int i = msb; i >= 0; i--) {
    if((b << i) > a)
    continue;
    q |= (1 << i);
    a -= (b << i);
    }
    if(neg)
    return -q;
    return q;
    }


  • 相关阅读:
    [转]windows下mysql配置文件my.ini的位置
    [转]Oracle 11g不能导出空表的多种解决方法
    [转]ORACLE WITH AS 用法(相当于查询开始前构造临时表,提高效率)
    [转]基于WordPress的微信小程序支付功能开发
    从数据库优化到治病(2)治好心悸过程
    算命三十多年的资深命理师的人生感悟!
    从高维度看世界
    鸾书精华
    实用QPS和TPS高的高效分析方法
    windows 安装 mysql
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5351824.html
Copyright © 2020-2023  润新知