zoukankan      html  css  js  c++  java
  • 29. Divide Two Integers

    思路:这道题让我们求两数相除,而且规定我们不能用乘法,除法和取余操作,那么我们还可以用另一神器 位操作Bit Operation,思路是,如果被除数大于或等于除数,则进行如下循环,定义变量t等于除数,定义计数p,当t的两倍小于等于被除数时,进行如下循环,t扩大一倍,p扩大一倍,然后更新res和m。这道题的OJ给的一些test case非常的讨厌,因为输入的都是int型,比如被除数是-2147483648,在int范围内,当除数是-1时,结果就超出了int范围,需要返回INT_MAX,所以对于这种情况我们就在开始用if判定,将其和除数为0的情况放一起判定,返回INT_MAX。然后我们还要根据被除数和除数的正负来确定返回值的正负,这里我们采用长整型long来完成所有的计算,最后返回值乘以符号即可。
    用到的知识:左移1位,相当于乘2,右移1位,相当除以2。
    第一次提交

    int divide(int dividend, int divisor)
    {
        int INTMAX = 2147483647;
        int INTMIN = -2147483648;
        if(divisor == 0)
        {
            return INTMAX;
        }
        if(dividend == INTMIN && divisor == -1)
        {
            return INTMAX;
        }
        if(dividend == divisor)
        {
            return 1;
        }
        long long divid = abs((long long)dividend);  //第17行
        long long divis = abs((long long)divisor);
        long res = 0;
        //做符号判断  //判断两个数符号是否相同,可使用按位异或
        int sign = ((dividend < 0) ^ (divisor < 0)) ? -1 : 1;  //同号sign=1,异号sign=0
        if((divisor == 1) || (divisor == -1))
        {
            return sign == 1 ? divid : -divid;
        }
        //做除法
        while(divid > divis)
        {
            long long t = divis ,p =1;
            while(divid >= (t << 1))  //左移1位等价于乘2
            {
                t = t << 1;
                p = p << 1;
            }
            res = res + p;
            divid = divid - t;
        }
        return sign == 1 ? res : -res;
    }
    

    LeEtcode报错

    Line 17: Char 23: runtime error: negation of -2147483648 cannot be represented in type 'int'; cast to an unsigned type to negate this value to itself (solution.c)
    

    abs的返回值overflow,同时我在本地的编译器提示我应该使用llabs()函数,abs()函数和llabs()函数的区别如下

    int abs( int n );
    long labs( long n );
    long long llabs( long long n );
    __int64 _abs64( __int64 n );
    

    也就是abs()函数的返回值是int类型,当abs()函数的输入为INT_MIN时,abs()函数将直接返回INT_MIN,这一点在微软官网上给出了解释。

    我在Qt中做了一个实验

    int main()
    {
        printf("%d",abs(INT_MIN));
        return 0;
    }
    

    运行结果如下:

    第二次提交

    int divide(int dividend, int divisor)
    {
        int INTMAX = 2147483647;
        int INTMIN = -2147483648;
        if(divisor == 0)
        {
            return INTMAX;
        }
        if(dividend == INTMIN && divisor == -1)
        {
            return INTMAX;
        }
        if(dividend == divisor)
        {
            return 1;
        }
        long long divid = llabs((long long)dividend);
        long long divis = llabs((long long)divisor);
        long res = 0;
        //做符号判断  //判断两个数符号是否相同,可使用按位异或
        int sign = ((dividend < 0) ^ (divisor < 0)) ? -1 : 1;  //同号sign=1,异号sign=0
        if((divisor == 1) || (divisor == -1))
        {
            return sign == 1 ? divid : -divid;
        }
        //做除法
        while(divid > divis)
        {
            long long t = divis ,p =1;
            while(divid >= (t << 1))  //左移1位等价于乘2
            {
                t = t << 1;
                p = p << 1;
            }
            res = res + p;
            divid = divid - t;
        }
        return sign == 1 ? res : -res;
    }
    

    参考资料:
    1 abs,labs,llabs函数的说明 https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/abs-labs-llabs-abs64?view=vs-2017
    2 https://www.cnblogs.com/grandyang/p/4431949.html

  • 相关阅读:
    ASP.NET的运行原理与运行机制
    VS2008快捷键
    (五)SubSonic的存储过程操作
    110个Oracle常用函数整理汇总
    ASP.NET中HttpModule和HttpHandler的作用及用法
    报表统计(sql面试题)
    ASP.NET C# 数字格式化输出
    ASP.NET Global.ascx 事件大全
    ASP.NET中GUID
    asp.net 页面转向 Response.Redirect, Server.Transfer, Server.Execute的区别
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/10494425.html
Copyright © 2011-2022 走看看