剑指 Offer 65. 不用加减乘除做加法(位运算,计组原理:补码、加法器)

在这里插入图片描述

一、基础知识

做这题需要用到计算机组成原理的基础知识:二进制的表示以及加法器。

简要提下知识点,最好再去研究下来龙去脉,加深理解。

(1)二进制加法

ab非进位和s进位c
0000
0110
1010
1101

对于非进位和,满足异或运算。
s = a ⨁ b s=a \bigoplus b s=ab
对于进位,满足运算。
c = a & b c=a \& b c=a&b

(2)二进制补码

对于有符号整数来说,首位是符号位,符号位是0表示正数,符号位为1表示负数,其余31位表示数值部分。
但,不论正数还是负数,在计算机中都是用二进制补码来存储的
对于正数,补码、反码和其原码相同。
对于负数 ,补码等于其原码的反码再加1。

例:3,数值部分为11,符号位为0。
原码:00000000 00000000 00000000 00000011
反码:00000000 00000000 00000000 00000011
补码:00000000 00000000 00000000 00000011

例:-2,数值部分为10,符号为1.
原码:100000000 00000000 00000000 00000010
反码:1111111111 111111111 111111111 111111101
补码:1111111111 111111111 111111111 111111110

二进制的补码使得减法运算也能通过加法来实现
例:-2 + 3 = 1

二、代码实现

C代码参考自评论区,相当简洁(不好理解):

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

解释:两数相加的二进制加法模拟,
(1)通过与运算得到进位的值。有符号整数进行移位操作时,符号位没有移动,移位不能改变符号位的值。而在补码运算中,符号位要参与运算,所以在移位前要强转,将其当做无符号数来处理。进位比当前位要高1位,所以整体左移1位。
(2)通过异或运算得到非进位和。
(3)进位的值要和进位所在位进行相加,这就又回到了前面的步骤(1)(2),直到进位值为0。

时间复杂度 O ( 1 ) O(1) O(1),空间复杂度 O ( 1 ) O(1) O(1)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值