Java使用位运算进行int的加减乘除运算

通过位运算计算int的加减乘除:

加法原理:a+b

位的异或运算求'和'的结果一致:

异或 1^1=0 1^0=1 0^0=0

求和 1+1=0 1+0=1 0+0=0

位的与运算求'进位‘的结果一致:

位与 1&1=1 1&0=0 0&0=0

进位 1+1=1 1+0=0 0+0=0

所以a+b = (a^b)+((a&b)<<1)

减法原理:a-b

减去一个正数等于加上这个负数的补码.一个正数的补码是它的原码.一个负数的补码等于它的反码+1.即 -b = ~b+1.所以a-b = a+(-b) = a+ ~b+1.

补码的规定如下:

对正数来说,最高位为0,其余各位代表数值本身(以二进制表示),如+42的补码为00101010。
对负数而言,把该数绝对值的补码按位取反,然后对整个数加1,即得该数的补码。如-42的补码为11010110(00101010按位取反11010101+1即11010110)

【例1】对 5 进行取反。

假设为16位。

5转换为二进制数为: 0000 0000 0000 0101得到二进制数

每一位取反: 1111 1111 1111 1010得到最终结果的补码

取补码: 1000 0000 0000 0110得到最终结果的原码

转换为十进制数:-6

则 5 取反为 -6 .

【例2】对 -5 进行取反。

假设为16位。

-5 转换为二进制数为: 1000 0000 0000 0101得到二进制数

取补码: 1111 1111 1111 1011得到二进制数的补码

每一位取反: 0000 0000 0000 0100 得到最终结果的补码

取补码: 0000 0000 0000 0100得到最终结果的原码

转换为十进制数:4

则 -5 取反为 4 .

如果用适合人类运算的计算方法:

如对 a 按位取反,则得到的结果为 -(a+1) .

此条运算方式对正数负数和零都适用。

所以~(b-1)=-b可得a-b=a+(-b)=a+(~(b-1))。把减法转化为加法即可。

乘法原理:a*b

1.用循环加法替代乘法。a*b,就是把a累加b次。时间复杂度为O(N)。

2.在二进制数上做乘法.就是根据乘数的每一位为0或1时,将被乘数错位的加在积上。时间复杂度为O(logN)

除法原理:a/b

1.从被除数上减去除数,看能减多少次之后变得不够减。时间复杂度为O(N)。

2.采用类似二分法的思路,从除数*最大倍数开始测试,如果比被除数小,则要减去。下一回让除数的倍数减少为上一次倍数的一半,这样的直到倍数为1时,就能把被除数中所有的除数减去,并得到商。时间复杂度降低到O(logN)。

/**
     * 加法
     * @param a
     * @param b
     * @return
     */
    public static int add(int a,int b) {
        int res=a;
        int xor=a^b;//得到原位和
        int forward=(a&b)<<1;//得到进位和
        if(forward!=0){//若进位和不为0,则递归求原位和+进位和
            res=add(xor, forward);
        }else{
            res=xor;//若进位和为0,则此时原位和为所求和
        }
        return res;
    }

    /**
     * 减法
     * @param a
     * @param b
     * @return
     */
    public static int minus(int a,int b) {
        int B=~(b-1);
        return add(a, B);
    }

    /**
     * 乘法
     * @param a
     * @param b
     * @return
     */
    public static int multi(int a,int b){
        int i=0;
        int res=0;
        while(b!=0){//乘数为0则结束
            //处理乘数当前位
            if((b&1)==1){
                res+=(a<<i);
                b=b>>1;
                ++i;//i记录当前位是第几位
            }else{
                b=b>>1;
                ++i;
            }
        }
        return res;
    }

    /**
     * 除法
     * @param a
     * @param b
     * @return
     */
    public static int sub(int a,int b) {
        int res=-1;
        if(a<b){
            return 0;
        }else{
            res=sub(minus(a, b), b)+1;
        }
        return res;
    }
    public static void main(String[] args) {
        //加法运算
        int result1 = add(90,323);
        System.out.println(result1);

        //减法运算
        int result2 = minus(413,323);
        System.out.println(result2);

        int result3 = multi(90,2);
        System.out.println(result3);

        int result4 = sub(90,2);
        System.out.println(result4);
    }

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞翔的咩咩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值