如何实现一个健壮的 atoi?

2016-02-24 22:17:42 +08:00
 KyL

处理正负号、非法字符什么的就不说了。
将字符串转换为符号整型的过程中如何处理整型溢出呢?我 google 了一下,没找到什么相关的。

3263 次点击
所在节点    程序员
14 条回复
SoloCompany
2016-02-24 23:06:42 +08:00
其实没多复杂
你每多处理一位(乘以 10 ( radix )再加上数字),就判断一次是否有溢出就是了

因为乘法会溢出,除法不会
所以,一般的做法,是在做乘法之前,估算是否有溢出,
以最常见的 radix=10 ,无符号整数举例,安全值就是 (2^32 - 1)/10 ~ (2^32-10)/10 之间,对应的余数为 0~9
这个安全值是固定的,只需要计算一次
然后在你每次做乘法之前先检查是否小于安全值就知道有没有溢出了
SoloCompany
2016-02-24 23:07:51 +08:00
修正一下,无符号整数距离应该是 2^31 不是 32 ,另外,对于负数,因为区间不一样,安全值要相应修正,但原理是一样的
ChiChou
2016-02-24 23:21:07 +08:00
难道楼主是看了 leetcode 的那题(逃
iProxier
2016-02-24 23:28:11 +08:00
看看 Golang 的源代码
zhjits
2016-02-24 23:32:18 +08:00



《 The Standard C Library 》 by P.J. Plauger
congeec
2016-02-24 23:34:42 +08:00
@zhjits glibc 里的么?
zhjits
2016-02-24 23:36:03 +08:00
@congeec 那本书里面的参考实现。
congeec
2016-02-24 23:45:23 +08:00
@zhjits .....问的就是这本书里的代码哪儿来的....
FUCKEX2
2016-02-24 23:49:40 +08:00
用 boost 中的库 一句话搞定

lexical_cast<double>(string);
bcxx
2016-02-24 23:56:37 +08:00
https://github.com/rofl0r/musl/blob/master/src/stdlib/atoi.c 这样?貌似 manpage 里面也没有说溢出的处理情况吧?
zhjits
2016-02-24 23:58:24 +08:00
@congeec 作者自己写的
bcxx
2016-02-25 00:05:12 +08:00
但其实 glibc 里面的 atoi 是用 strtol 实现的…… 这个就有溢出处理了 http://fossies.org/dox/glibc-2.23/stdlib_2strtol__l_8c_source.html
KyL
2016-02-25 11:23:53 +08:00
@ChiChou 我曾经在面试中被问到过,在 leetcode 中也看到过,在写程序中也遇到过。但是奇怪的是,似乎没有人提到过处理整型溢出问题,在网上搜索的所有 atoi 实现,都没有,连提到都没有。
CoderRunner
2016-02-25 14:34:02 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/258896

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX