[英]Difference in the values of atoi
我有以下代码:
char* input = (char*)malloc(sizeof(char) * BUFFER) // buffer is defined to 100
int digit = atoi(input); // convert char into a digit
int digit_check = 0;
digit_check += digit % 10; // get last value of digit
当我运行输入1234567896和类似的数字= 1234567896和digit_check = 6。
但是,当我运行输入9999999998时,数字= 1410065406,因此当数字应为8时,数字_check = 6。
对于第二个例子,当输入和数字应该是相同的值时,为什么输入和数字之间存在差异?
可能是因为9999999998比最大(带符号)整数表示大,所以你得到溢出。
实际上这是9999999998和1410065406的二进制表示:
10 01010100 00001011 11100011 11111110
01010100 00001011 11100011 11111110
正如您所看到的,如果您看到1410065406是32位位值9999999998
atoi
仅限于int大小(最近的平台上为32位)。
如果要处理大数字,可以使用atol
或scanf("%ld")
。
不要忘记将变量键入long int
(或long
)。
您也可以只获取输入的最后一个字符(收集为字符串而不是int)并在其上使用atoi
,因此它永远不会溢出。
在许多平台上, int
大小限制为4个字节,这限制了[-2 ** 31, 2**31 - 1]
。
根据您构建的平台,使用strtol
(或strtoll
) long
(或long long
)。 例如,x86上的GCC将具有64位long long
,而对于amd64,它将具有64位long
和long long
型。
所以:
long long digit = strtoll(input, NULL, 10);
注意: strtoll()
在类Unix系统中很流行,并且在C ++ 11中成为标准,但并非所有VC ++实现都有它。 使用_strtoi64()
代替:
__int64 digit = _strtoi64(input, NULL, 10);
你可能想使用atoll
函数返回一个long long int
,也就是两倍大int
(最有可能在你的情况下,64位)。
它在stdlib.h
声明
你应该避免在未初始化的字符串上调用atoi
,如果字符串上没有\\0
,你将无效读取并出现分段错误。 你应该使用strtoimax
,它更安全。
9999999998大于整数可以表示的最大值。 要么使用atol()
OR atoll()
您应该停止使用atoi
功能或来自ato...
组的任何其他功能。 这些功能尚未正式弃用,但自1995年以来就被有效放弃,仅用于遗留代码兼容性目的。 忘记这些功能就好像它们不存在一样。 这些功能在出现错误或溢出时不提供有用的反馈。 溢出就是你的例子中明显发生的事情。
为了将字符串转换为数字,C标准库提供strtol
函数和strto...
group的其他函数。 这些是您应该用于执行转换的函数。 并且不要忘记检查溢出的结果: strto...
函数通过返回值和errno
变量提供此反馈。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.