码迷,mamicode.com
首页 > 其他好文 > 详细

每日算法之八:String to Integer (atoi) 及溢出分析

时间:2014-05-11 06:56:19      阅读:463      评论:0      收藏:0      [点我收藏+]

标签:溢出 atoi

Implement atoi to convert a string to an integer.  Hint: Carefully consider all possible input cases. If you want a challenge, please do not see below and ask yourself what are the possible input cases.Notes: It is intended for this problem to be specified vaguely (ie, no given input specs). You are responsible to gather all the input requirements up front.

要求就是把字符串转化为整形,按照我们的理解就可以逐字符遍历,转化为整形即可,比如字符串"123454",我们只要取出第零个字符‘1‘-‘0’就可以得到数字1,然后把1乘以10,再加上‘2’-‘0’·····这样依次就可以得到转化之后的整形数字。当然有几个地方需要注意:

1)字符串可能以正负号开始,也可能包含一些其他的非数字型字符,是不能转化为数字的,是忽略还是报错看需求

2)越界,字符串转化到整形数字之后的数字串可能超出表示范围,超出的可以置为INT_MAX或者INT_MIN。

代码参考如下:

class Solution {
public:
    int atoi(const char *str) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
        long long ret = 0;//存储最终转化的数字
        
        const char *p = str;
        
        while(*p == ‘ ‘) p++;//忽略空格
        
        bool valid = true;
        while(valid && *p == ‘+‘) {
            valid = false;
            p++;
        }
        
        while(*p == ‘0‘) p++;
        
        bool minus = false;
        if(*p == ‘-‘){
            minus = true;
            p++;
        }
        
        while(*p != ‘/0‘){
            if(*p >= ‘0‘ && *p <=‘9‘){
                ret = ret * 10 + *p - ‘0‘;
                if(!minus && ret > INT_MAX) return INT_MAX; // positive and overflow
                if(minus && -ret < INT_MIN) return INT_MIN; // negative and overflow
                p++;
            } else {        // no digit then break
                break;
            }
        }
        
        return minus ? -ret : ret;
    }
};
这里需要特别注意的就是怎么预防溢出,如果都是int类型,用ret+1>INT_MAX进行判断是错误的,当ret是INT_MAX时,再进行加一操作是会溢出的,变为最小的负数,对计算机而言对符号性的整数是进行位运算的,即对INT_MAX:0111 1111 1111 1111 1111 1111 1111 1111 进行加1之后就变为

1000 0000 0000 0000 0000 0000 0000 0000也就是INT_MIN。实质上产生的进位到了符号位。上面能AC的原因是使用了long long (8字节)类型的整形存储int(4字节)。所以能够判断大于INT_MAX,现在假定形参也是longlong类型或者不允许使用刚才的方式,那么我们应该怎么做呢?

#include <limits.h>
void f(signed int si_a, signed int si_b) {
signed int sum;
if (((si_b > 0) && (si_a > (INT_MAX - si_b))) ||
((si_b < 0) && (si_a < (INT_MIN - si_b)))) {
/* Handle error */
return;
}
sum = si_a + si_b;
}

我们使用这种方法就可以进行溢出的判断,这是苹果安全编码的建议,应该是可用高效的。

因为溢出导致的异常是常见并且是难以发现的,因此一定要注意。

每日算法之八:String to Integer (atoi) 及溢出分析,布布扣,bubuko.com

每日算法之八:String to Integer (atoi) 及溢出分析

标签:溢出 atoi

原文地址:http://blog.csdn.net/yapian8/article/details/25487733

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!