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

  • 相关阅读:
    在日本被禁止的コンプガチャ設計
    Starling常见问题解决办法
    Flixel引擎学习笔记
    SQLSERVER中修复状态为Suspect的数据库
    T4 (Text Template Transformation Toolkit)实现简单实体代码生成
    创建Linking Server in SQL SERVER 2008
    Linq to Sql 与Linq to Entities 生成的SQL Script与分页实现
    Linq to Entity 的T4 模板生成代码
    在VisualStudio2008 SP1中调试.net framework 源代码
    使用HttpModules实现Asp.net离线应用程序
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/10494425.html
Copyright © 2011-2022 走看看