zoukankan      html  css  js  c++  java
  • 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的数值比较来确定有没有出现问题。但是这样的话好像就没有太大意义了(笑~)
  • 相关阅读:
    刘若英和她的<<蝴蝶>>
    我的心情日记
    flash鼠标特效
    flash的播放器
    NoSQL数据存储引擎
    分享iphone开发的好网站,希望大家也能提供一些分享下
    创业经验总结
    产品经理之我见
    软件开发报价的计算方法
    Android实现号码归属地查询
  • 原文地址:https://www.cnblogs.com/jiading/p/10422265.html
Copyright © 2011-2022 走看看