当前位置: 首页 > news >正文

利用位运算实现加减乘除

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

利用位运算实现加减乘除

受《剑指offer》上题目的启发,现在把利用位运算做加、减、乘、除的方法总结一下。 
参考网址:https://blog.csdn.net/sinat_35261315/article/details/72904945

基础知识

数据在计算机内存中是以二进制存储的。 
几种常用的位运算: 
····与运算 &: 对应位均为1时为1,其它为0。 
····或运算 |:对应位均为0时为0,其它为1。 
····异或运算 ^:对应位不相同时为1,相同时为0. 
····按位取反 ~:每一位取反 
····右移 >>:将二进制进行右移,低位丢掉,高位补零。 
····左移 <<:将二进制进行左移,低位补零,高位丢掉。

加法

参考《剑指offer》题目链接:https://blog.csdn.net/Allenlzcoder/article/details/79705597 
代码如下:

int add(int num1, int num2) {
    int res = 0, carry = 0;
    res = num1^num2;
    carry = (num1&num2) << 1;
    while (carry) {
        int tmp = res;
        res = res^carry;
        carry = (tmp&carry) << 1;
    }
    return res;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

减法

减法和加法相同,减去一个数相当于加上这个数的相反数,所以完全可以利用加法操作,唯一需要做的就是求出被减数的相反数。 
求相反数的方法:每一位取反,末位加一。 
代码如下:

//求n的相反数
//~:按位取反
//add:加法操作,末位加一
int negtive(int n) {
    return add(~n, 1);
}

int subtraction(int a, int b) {
    //加上被减数的相反数
    return add(a, negtive(b));
}

乘法

平时在笔算乘法数据都是十进制的,而抛去思维定势,把数看成是二进制,也可以进行笔算乘法,像这样,A表示0.1101;B表示0.1011. 
这里写图片描述
根据算式可以知道,对于A*B,步骤细分如下: 
1) 将A左移1位(<< 1或者 *2); 
2) 将1)的结果乘上B的对应位数字(0 或1); 
3) 把2)的结果和之前的结果相加。 
也就意味着当B的对应位为1时,对A左移一位然后同上一次的结果做加法。 
如果b的对应位为0,只对A左移一位。 
当然,上述这些运算不包括符号位,所以两个操作数都需要先转换成正数,符号需要单独考虑。对于4个字节(32位整数)来说,获取符号位只需要取出第31位的值即可。 
代码如下:

//取出符号位
int getSign(int n) {
    return n >> 31;
} 

//求n的绝对值
int positive(int n) {
    return (getSign(n) & 1) ? negtive(n) : n;
}

int multiply(int a, int b) {
    //如果两个数符号位不相容,则结果为负
    bool isNegtive = false;
    if(getSign(a) ^ getSign(b))
        isNegtive = true;
    a = positive(a);
    b = positive(b);
    int res = 0;
    while (b | 0) {
        //当b的对应位是1时,才需要加a
        if(b & 1)
            res = add(res, a);
        a = a << 1; //a左移
        b = b >> 1; //b右移
    }
    return isNegtive == true ? negtive(res) : res;
}

除法

同乘法一样,除法也可以进行二进制笔算,以a/b为例,只有当a >= b时才可以上商,又因为是二进制,所以商每次只会多1,在每次上1之后a都要减去一次b。代码如下:

int divide(int a, int b) {
    //被除数不能为0
    if (b == 0)
        throw std::runtime_error("Divided can't be zero...");

    bool isNegtive = false;
    if (getSign(a) ^ getSign(b))
        isNegtive = true;

    a = positive(a);
    b = positive(b);

    int res = 0;
    while (a >= b) {
        res = add(res, 1);
        a = subtraction(a, b);
    }
    return beNegtive == true ? negtive(res) : res;
}

转载于:https://my.oschina.net/wangen2009/blog/3004873

相关文章:

  • IT应该自动化的7件事
  • 陕西彬州一男子持刀杀害两名女性 警方发布协查通告
  • 圆方圆:python的错误处理——try语句
  • 洛谷 P1824 【进击的奶牛】
  • 自学自用 = B站(操作系统_清华大学(向勇、陈渝))1
  • Docker下部署自己的LNMP工作环境
  • Docker-01-使用镜像
  • C# 分割字符串
  • LDM和STM指令
  • java B2B2C Springcloud电子商城系统-搭建一个简单的Eureka程序
  • 传闻 Android Q 将支持手机应用版本回滚
  • MD5加密原理解析及OC版原理实现
  • linux环境安装golang
  • 国际乒联2月世界排名:樊振东、丁宁持续领跑
  • 李嘉诚23岁长孙女登场接班!出任地产公司董事,照片曝光气质获赞
  • 【Linux系统编程】快速查找errno错误码信息
  • HTML中设置input等文本框为不可操作
  • JavaScript设计模式系列一:工厂模式
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • mysql中InnoDB引擎中页的概念
  • Spring Cloud(3) - 服务治理: Spring Cloud Eureka
  • Vue官网教程学习过程中值得记录的一些事情
  • 关于Flux,Vuex,Redux的思考
  • 跨域
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 区块链将重新定义世界
  • 深入浅出webpack学习(1)--核心概念
  • 微信公众号开发小记——5.python微信红包
  • 用jquery写贪吃蛇
  • 怎么将电脑中的声音录制成WAV格式
  • 最简单的无缝轮播
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #{} 和 ${}区别
  • #LLM入门|Prompt#2.3_对查询任务进行分类|意图分析_Classification
  • #数学建模# 线性规划问题的Matlab求解
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (二)springcloud实战之config配置中心
  • (二开)Flink 修改源码拓展 SQL 语法
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (九)One-Wire总线-DS18B20
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (转)程序员技术练级攻略
  • .NET 8.0 中有哪些新的变化?
  • .NET MVC第五章、模型绑定获取表单数据
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • @ModelAttribute注解使用
  • []Telit UC864E 拨号上网
  • []使用 Tortoise SVN 创建 Externals 外部引用目录
  • [ACL2022] Text Smoothing: 一种在文本分类任务上的数据增强方法