C++-int類型整數超出范圍后的處理


最近做了一道題目:

Given a 32-bit signed integer, reverse digits of an integer.

Example 1:

Input: 123
Output: 321

Example 2:

Input: -123
Output: -321

Example 3:

Input: 120
Output: 21

Note:
Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231,  231 − 1]. For the purpose of this problem, assume that your function returns 0 when the reversed integer overflows.

來源:https://leetcode.com/problems/reverse-integer/

先貼上自己丑陋的代碼:

 1 class Solution {
 2 public:
 3     int reverse(int x) {
 4         bool isNegative=false;
 5         if(x==0||x<-1*pow(2,31)+1||x>pow(2,31)-1)
 6             return 0;
 7         if(x<0){
 8             isNegative=true;
 9             x=-1*x;
10         }
11         while(x%10==0)
12             x=x/10;
13          int ans=0,temp;
14         temp=x-(x/10)*10;
15         while(x>=1&&ans<pow(2,31)/10){
16             ans=ans*10;
17             ans+=temp;
18             x=x/10;
19             temp=x-(x/10)*10;
20         }
21         if(x>=1)
22             return 0;
23         if(isNegative)
24             ans=ans*(-1);
25         return ans;
26     }
27 };

(單從速度角度來看,好像還可以?).

但是看到了討論區一個意大利大佬的代碼,確實是short and element:

 1  public int reverse(int x) {
 2         int prevRev = 0 , rev= 0;
 3         while( x != 0){
 4             rev= rev*10 + x % 10;
 5             if((rev - x % 10) / 10 != prevRev){
 6                 return 0;
 7             }
 8             prevRev = rev;
 9             x= x/10;
10         }
11         return rev;
12     }

不像我傻傻地用pow判斷溢出,這段代碼的判定語句很特別:

if((rev - x % 10) / 10 != prevRev){
                return 0;
我放到vs里測試了一下,打印了結果出來。
測試代碼:
cout << rev << endl;
        rev = rev * 10 + x % 10;
        cout << "afterchange:" << rev << endl;

結果:

關鍵是最后一行,應該是9646324351的結果變成了1056389759.這應該就是Int溢出的結果。

通過查找網絡資料,看到有一個答案說的是對的(https://zhidao.baidu.com/question/1899917410883143460.html?qbl=relate_question_0&word=C%2B%2B%20Int%D4%CB%CB%E3%B3%AC%B3%F6%B7%B6%CE%A7)

C語言int占4個字節,一共32位,范圍是-2147483648 ~ 2147483647。

如果超出這個范圍,就會加上或減去4294967296,使得值還落在這個范圍內。
比如定義int變量a的值為2147483647,再加1就是2147483648,超出范圍,因此需要減掉4294967296,最后打印的值就是-2147483648

實際上,1056389759就是9646324351-2*4294967296.也就是減去了兩倍的“模長”。
不像一開始就輸入一個超出Int范圍的整數時的情況,編譯器不會發現超出范圍、不會報錯(因為這更像一個邏輯錯誤,是運行中產生的),只會在運行的過程中通過“減模長”的形式使其在范圍內。
所以,之后判斷Int超出時,可以使用一個整數來配合檢查,其的作用是保存變換之前的整數,以此和變換后的整數通過變換公式來檢查變換是否正確,如果變換發生了異常,則說明超出了范圍。
當然,也可以通過一個Long來保存正確結果,通過和這個Long的數值比較來確定有沒有出現問題。但是這樣的話好像就沒有太大意義了(笑~)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM