不使用加减乘除符号的四则运算

加法

回忆一下小学一年级学过的加法,两个数相加,各位相加,大于10就向前进1,二进制中也是一样的,只不过由“满十进一”变成“满二进一”。所以加法的实现思路就是先相加后进位,不能用加减乘除符号,考虑位运算。
发现

1+1=0
1+0=1
0+1=1
0+0=0

两者的关系对应 异或运算
又发现 只有1+1才能产生进位。其他1+0 0+1 0+0 都不产生进位 对应 与运算
故 两数相位与再左移1位 得到数的进位值 将它加上两数异或的值,直到两数相加不再产生进位

int add(int a, int b)
{
    int sum;
    int tmp;
    if (b == 0)					//递归到进位值为0时结束
        return a;
    else
    {
        sum = a ^ b;			//值相加不进位
        tmp = (a & b) << 1;		//进位值
        add(sum, tmp);
    }
}

减法

加法的逆运算

int sub(int a, int b)
{
    return add(a, add(~b, 1));	//a-b=a+(-b)
}

乘法

模拟竖式计算
在这里插入图片描述

int mul(int a, int b)
{
    int sum = 0;
    if (a < 0 && b < 0)//符号处理
    {
        a = sub(0, a);
        b = sub(0, b);
    }
    if (a > 0 && b < 0)
    {
        a = sub(0, a);
        b = sub(0, b);
    }
    int index = 0;
    while (b > 0)
    {
        int tmp = b & 1;	//保留b的最后一位
        if (tmp == 1)		//为1 全保留 左移index 位
        {
            sum = add(sum, a << index);
        }
        index = add(index, 1);//index++
        b = b >> 1;
    }
    return sum;
}

除法

反复减被除数
记录被减的次数
十进制中 如果被除数过大,除数过小,就会出现循环次数过多的问题 所以每次除数减去 被除数*10n ,保证n在减完后不小于0的情况下最大,减的次数+10n

int division(int a, int b)
{
    int flag = 1;//正
    // 处理符号问题
    if (a >> 31 == 1)
    {
        a = add(~a, 1);
        flag = add(~flag, 1);
    }
    if (b >> 31 == 1)
    {
        b = add(~b, 1);
        flag = add(~flag, 1);
    }

    int rcnt = 0;
    while (a >= b)
    {
        int aa = 1, temp = b;
        while (temp < (a >> 1))//保证够减
        {
            temp = temp << 1;
            aa = aa << 1;
        }
        a = sub(a, temp); 
        rcnt = add(rcnt, aa); //减的次数
    }

    return mul(re, flag);
}

基础知识

与运算:
0 & 0 = 0
1 & 0 = 0
0 & 1 = 0
1 & 1 = 1
或运算:
0 | 0 = 0
1 | 0 = 1
0 | 1 = 1
1 | 1 = 1
非运算:
~1 = 0
~0 = 1
异或运算:
0^0 = 0
1^0 = 1
0^1 = 1
1^1 = 0

算术左移 低位补0
算数右移 高位补符号位

补码,原码,反码详解
https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值