• Leetcode#29 Divide Two Integers


    原题地址

    不用除运算和模运算的除法就退化成最基本的减法

    如果除数是1,被除数超大,这做减法还不得累死,所以,用位运算加快速度。

    对于被除数和除数都是正数的情况,除法流程为:用位运算生成小于等于当前被除数一半的数字,然后一口气减掉,如此循环往复,直到被除数小于除数。

    对于其他被除数和除数当中有负数的情况,为了简便处理可以先将他们求绝对值转化成正数,最后算出结果后再添加符号。

    最重要的是考虑溢出问题,32位有符号数字的表示范围是[INT_MIN, INT_MAX]=[-2^32, 2^32-1]=[-2147483648, 2147483647],注意:INT_MAX比INT_MIN的绝对值少1

    如果数字超过这个范围,就会发生溢出。上面的除法算法涉及到两处溢出的地方:

    1. 相除的结果恰好是2147483648,发生溢出。

    好在这种溢出的情况只有当被除数=INT_MIN,除数=-1的情况下才会发生,所以可以在运算之前通过条件判断直接处理。

      2. 被除数或除数=INT_MIN,且将他们转化成正数,发生溢出。

    同样地,应尽可能通过条件判断处理这种特殊情况。

    如果除数=INT_MIN,只要被除数不等于INT_MIN,相除结果就是0,否则结果是1

    如果被除数=INT_MIN,可以先减一个除数,之后再转化成正数就不会溢出了

     

    代码:

     1 int divide(int dividend, int divisor) {
     2         if (dividend == INT_MIN) {
     3             if (divisor == 1 || divisor == -1)
     4                 return divisor < 0 ? INT_MAX : INT_MIN;
     5             if (divisor == INT_MIN)
     6                 return 1;
     7         }
     8         else if (divisor == INT_MIN)
     9             return 0;
    10           
    11         int quotient = 0;
    12         int degree = 1;  
    13         bool negative = (dividend >> 31) ^ (divisor >> 31);
    14         if (dividend == INT_MIN) {
    15             dividend += divisor > 0 ? divisor : -divisor;
    16             quotient = 1;
    17         }
    18         dividend = dividend > 0 ? dividend : -dividend;
    19         divisor = divisor > 0 ? divisor : -divisor;
    20         int nextDivisor = divisor;
    21         
    22         for (int d = divisor << 1; d > nextDivisor && d <= dividend; d <<= 1) {
    23             nextDivisor = d;
    24             degree <<= 1;
    25         }
    26             
    27         while (dividend >= divisor) {
    28             if (dividend >= nextDivisor) {
    29                 dividend -= nextDivisor;
    30                 quotient += degree;
    31             }
    32             else {
    33                 nextDivisor >>= 1;
    34                 degree >>= 1;
    35             }
    36         }
    37         
    38         return negative ? -quotient : quotient;
    39 }
  • 相关阅读:
    博客重构 / Blog Refactoring
    Microsoft Ajax Beta1 边学边用边补充 (Part 2 DragDropList)
    深入理解 ViewState
    十分钟内学会:无刷新的页面间导航
    从 ASP 到 ASP.NET (Part 1 学习什么)
    Microsoft Ajax Beta1 边学边用边补充 (Part 1 Debug)
    深入理解 ASP.NET 动态控件 (Part 1 感性认识)
    Microsoft Ajax Beta1 边学边用边补充 (Part 3 ITemplate)
    Blog Refactoring (Volume 2)
    从 ASP 到 ASP.NET (Part 3 后记)
  • 原文地址:https://www.cnblogs.com/boring09/p/4259024.html
Copyright © 2020-2023  润新知