剑指 Offer 65. 不用加减乘除做加法

题目描述:

写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。

示例:

输入: a = 1, b = 1
输出: 2
 

提示:

a, b 均可能是负数或 0
结果不会溢出 32 位整数


来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析:我真的觉得这道题不应该作为简单题出现。。。

熟悉位运算一眼就会,不熟悉的死活做不出来。我个人的理解只能想到无进位和通过异或得出,进位通过与运算得出。但是如何处理连环进位的问题我就不知道了。

只好去看了题解,真的再一次叹服于大佬的智慧。

 剑指 Offer 65. 不用加减乘除做加法_第1张图片

来源:leetcode用户 Krahets

https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/solution/mian-shi-ti-65-bu-yong-jia-jian-cheng-chu-zuo-ji-7/

主要是那个循环求n和c, 一般情况下真的想不到。。。。

以及负数的问题,这篇文章并没有提到,一输入负数就报错,看了看评论区,把其中一句改成:

            int c=(unsigned int)(a&b)<<1;

即可,具体原因稍后分析。

代码附上:

class Solution {
public:
    int add(int a, int b) {
        
        while(b!=0)
        {
            int c=(unsigned int)(a&b)<<1;
            a=a^b;
            b=c;
        }
        return a|b;
    }
};

要探讨加上unsigned int这个问题,又必须要去讨论数值在计算机中的原码,反码和补码的问题了。

这篇文章讨论的很好https://www.dotcpp.com/wp/221.html,这里我就不再赘述了。

然后是为什么要加上unsigned int呢

我们先看看,如果不加unsigned int,每次循环的进位和无进位和是多少

jinwei is 2 he is -2

jinwei is 4 he is -4

jinwei is 8 he is -8

jinwei is 16 he is -16

jinwei is 32 he is -32

jinwei is 64 he is -64

jinwei is 128 he is -128

jinwei is 256 he is -256

jinwei is 512 he is -512

jinwei is 1024 he is -1024

jinwei is 2048 he is -2048

jinwei is 4096 he is -4096

jinwei is 8192 he is -8192

jinwei is 16384 he is -16384

jinwei is 32768 he is -32768

jinwei is 65536 he is -65536

jinwei is 131072 he is -131072

jinwei is 262144 he is -262144

jinwei is 524288 he is -524288

jinwei is 1048576 he is -1048576

jinwei is 2097152 he is -2097152

jinwei is 4194304 he is -4194304

jinwei is 8388608 he is -8388608

jinwei is 16777216 he is -16777216

jinwei is 33554432 he is -33554432

jinwei is 67108864 he is -67108864

jinwei is 134217728 he is -134217728

jinwei is 268435456 he is -268435456

jinwei is 536870912 he is -536870912

jinwei is 1073741824 he is -1073741824

jinwei is -2147483648 he is -2147483648

当进位为 -2147483648的时候,下一步进行左移操作,就会导致进位溢出,报错,然后无法继续。

而无符号整数是不存在溢出这个问题的,详见这篇文章:https://blog.csdn.net/gongchangwangqi/article/details/47210447

故当使用unsigned int时,  -2147483648左移一位,变为了0,并且不会报溢出错误。因此,循环结束,可以计算出结果。

当加上unsigned int之后的结果:

jinwei is 2 he is -2

jinwei is 4 he is -4

jinwei is 8 he is -8

jinwei is 16 he is -16

jinwei is 32 he is -32

jinwei is 64 he is -64

jinwei is 128 he is -128

jinwei is 256 he is -256

jinwei is 512 he is -512

jinwei is 1024 he is -1024

jinwei is 2048 he is -2048

jinwei is 4096 he is -4096

jinwei is 8192 he is -8192

jinwei is 16384 he is -16384

jinwei is 32768 he is -32768

jinwei is 65536 he is -65536

jinwei is 131072 he is -131072

jinwei is 262144 he is -262144

jinwei is 524288 he is -524288

jinwei is 1048576 he is -1048576

jinwei is 2097152 he is -2097152

jinwei is 4194304 he is -4194304

jinwei is 8388608 he is -8388608

jinwei is 16777216 he is -16777216

jinwei is 33554432 he is -33554432

jinwei is 67108864 he is -67108864

jinwei is 134217728 he is -134217728

jinwei is 268435456 he is -268435456

jinwei is 536870912 he is -536870912

jinwei is 1073741824 he is -1073741824

jinwei is -2147483648 he is -2147483648

jinwei is 0 he is 0

你可能感兴趣的:(leetcode,p2p,网络协议,网络)