位运算实现整数运算

不准用+,-,*,/ 运算操作符来实现四则运算。

1、整数加法

https://leetcode.com/problems/sum-of-two-integers/

int add(int a, int b) {
        int ans = a;
        while (b) {//直到没有进位
            ans = a ^ b; //不进位加法
            b = ((a & b) << 1); //所有a,b都为1的位,都存在进位,记录该进位,下一次循环加上
            a = ans;
        }
        return ans;
    }

链接的题目需要处理下溢出的问题:

class Solution {
public:
    int getSum(int a, int b) {
        int ans = a;
        while (b) {
            ans = a ^ b;
            b = ((unsigned)a & b) << 1;//(其实没什么意义,返回值又不是unsigned int,但不这样写,会Runtime Error)
            a = ans;
        }
        return ans;
    }
};

2、整数减法

计算机内部的减法运算,就是通过加上被减数相反数的补码实现的。

即: a - b 和  a + (~b + 1) 是等价的。

int sub(int a, int b) {
    b = add(~b, 1);//取b的补码
    return add(a, b);
}

3、整数乘法

快速幂的思想,溢出风险比较大,改用long long了。

long long Multi(long long a, long long b){
    long long ans = 0;
    while (b){
        if (b & 1)
            ans = add(ans, a);//将add的两个形参也改为long long
        a <<= 1;
        b >>= 1;
    }
    return ans;
}

4、整数除法

//依次减掉(如果x够减的)y^(2^31),y^(2^30),...y^8,y^4,y^2,y^1。减掉相应数量的y就在结果加上相应的数量。
int Div(int x, int y){
    int ans = 0;
    for (int i = 31; i >= 0; i--){
        //比较x是否大于y的(1<<i)次方,避免将x与(y<<i)比较,因为不确定y的(1<<i)次方是否溢出
        if ((x >> i) >= y){
            ans += (1 << i);
            x -= (y << i);
        }
    }
    return ans;
}

原文地址:https://www.cnblogs.com/czc1999/p/10678160.html

时间: 2024-08-30 18:20:16

位运算实现整数运算的相关文章

位运算————两整数之和

在位运算操作中,异或的一个重要特性是无进位加法. a = 5 = 0101 b = 4 = 0100 a ^ b 如下: 0 1 0 1 0 1 0 0 ------- 0 0 0 1 得到了一个无进位加法结果,如果要得到 a + b 的最终值,我们还要找到进位的数,把这二者相加.在位运算中,我们可以使用与操作获得进位: a = 5 = 0101 b = 4 = 0100 a & b 如下: 0 1 0 1 0 1 0 0 ------- 0 1 0 0 由计算结果可见,0100 并不是我们想要

大整数运算

对于A,B的范围在int范围内,求解A与B的加减乘除运算我相信大家很快就可以写出程序来,但是如果A,B是有着1000个数位的整数呢?恐怕就没有已有的数据类型来表示了,这时候只能老实的模拟加减乘除运算的过程.模拟加减乘除的运算的过程,原理就是小学的. 大整数又称为高精度整数,其含义就是用基本的数据类型无法存储其精度的整数.大整数运算即高精度运算. 首先,介绍大整数的存储. 很简单,用数组即可.例如,int型数组d[1000]:如将123456存储到数组中,则有d[0]=6,d[1]=5......

shell学习笔记之四(整数运算)

算数运算符 shell只支持整数运算 常见的算数运算大多结合shell的内建命令let来使用. + - * / % **(幂运算) += -= *= /= %= 位运算 >> << & | ^ ~ 自增自减 ++ -- 例: let "b=3" let "a=(++b)" 其他算数运算 简单的算数运算过程中,如果有一个值是字符的,那么解析为0 如R+2=2 1.使用$[]作运算 1.到目前看到的$这样的形式有:${}(数组) $[](

linux平台学x86汇编(十):整数运算

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途] 这一节介绍如何在编语言中上使用整数运算,包括加法.减法.乘法和除法. 加法指令 add指令用于把两个整数想加.格式如下: add src, dest 其中src可以是立即数值.内存地址.寄存器.dest可以是寄存器或内存中的值,不能同时使用内存地址作为源和目标.结果存放在dest中.和其他GNU汇编指令一样,需要在add结尾添加b.w.l来指定操作数长度.如果没有使用整个寄存

第12章 整数运算

12.1 二进制补码运算Java虚拟机所支持的所有的整数类型-byte, short.int和long,它们都是带符号的二进制补码数.二进制补码方案既能够描述正整数,也能够描述负整数.在一个二进制补码数中,最重要的位就是它的符号位.符号位为1,表示负整数:符号位为0,表示正整数和数字0. 能够被二进制补码方案表示的数的范围为:2的总位数次幂.例如,在Java中,short类型是16位带符号的二进制补码整数.能够惟一表示的整数数为:216或者65536.short类型值范围的一半被用来表示0和正整

大整数运算模板总结

大整数运算模板总结. 大整数结构体表示 整型数组从低位到高位顺序存储每一位数字,另外需要存储数字的长度. struct bign { int d[1000]; int len; bign(){ memset(d, 0, sizeof(d)); len = 0; } }; 大整数输入 一般通过字符串输入. bign Change(string str)//输入字符串转大整数 { bign a; a.len = str.length(); for (int i = 0; i < a.len; i++

C++ 出现bug :二位数组的操作运算,求非对角线的元素的和

编写一个通用程序,求出二位数组(行数和列数必须相等)的非对角线的元素之和,试建立类MATRIX完成上述功能 #include<iostream> using namespace std; class MATRIX { public: void mATRIX(); void MATRIX_sum(); void MATRIX_display(); static int fact_len;//定义静态变量 private: int sum; int a[40][40]; }; int MATRIX

算术运算符——整数运算

shell中进行整数运算需要借助一些辅助工具,如:expr.declare.let.((  )).$[  ] 1.expr有很多不完善之处,此处不写. 2.declare: declare -i 命令定义整形变量,当使用此命令对变量赋值后,变量便可进行算术运算. 需要注意的是: 如果给整形变量赋值的是一个字符串值,则bash会将变量赋值为0. 使用declare -i命令生成的变量执行算术运算时,各变量之间不能有空格. [email protected]:~$ declare -i m n [e

《深入Java虚拟机学习笔记》- 第12章 整数运算

Java虚拟机提供几种进行整数算术运算的操作码,他们执行基于int和long类型的运算.当byte.short和char类型值参与算术运算时,首先会将它们转换为int类型.这些操作码都不会抛出异常,溢出在这里通常可以被忽略. 整数加法 操作码 操作数 说明 iadd (无) 从栈中弹出两个int类型数,相加,然后将所得int类型结果压回栈 ladd (无) 从栈中弹出两个long类型数,相加,然后将所得long类型结果压回栈 将一个常量与局部变量相加 操作码 操作数 说明 iinc vindex