【发布时间】:2011-02-11 17:55:18
【问题描述】:
在处理需要将字符串转换为长数字的应用程序时,atol() 和 strtol() 无法正确转换任何大于 9 位的字符串。
strtol 会提示一个与字符串无关的数字,而 atol 会导致一个负数(溢出)。
知道为什么会发生这种情况,我该如何解决?
【问题讨论】:
标签: c string long-integer
在处理需要将字符串转换为长数字的应用程序时,atol() 和 strtol() 无法正确转换任何大于 9 位的字符串。
strtol 会提示一个与字符串无关的数字,而 atol 会导致一个负数(溢出)。
知道为什么会发生这种情况,我该如何解决?
【问题讨论】:
标签: c string long-integer
听起来您系统上的long 是一个 32 位值。这意味着任何高于 4,294,967,295 的无符号数都不会正确转换,也不会正确转换高于 2,147,483,647 或低于 2,147,483,648 的有符号数。
一般来说,一个n位表示可以表示[-2n-1,-2n-1) 或 [0,2n) 范围内的无符号数。
维基百科文章Computer numbering formats 可能是了解有关此行为的更多信息的一个很好的起点。
您从atol() 和strtol() 看到不同结果的原因是它们具有不同的错误处理特性。来自strtol() man page:
strtol()函数返回转换结果,除非值会下溢或溢出。如果发生下溢,strtol()返回LONG_MIN。如果发生溢出,strtol()返回LONG_MAX。在这两种情况下,errno都设置为ERANGE。
相同
atoi()函数将nptr指向的字符串的初始部分转换为 int。行为与strtol(nptr, (char **)NULL, 10);除了
atoi()不检测错误。
atol()和atoll()函数的行为与atoi()相同,只是它们将字符串到他们的返回类型long或long long。
【讨论】:
这可能与您平台上long 的大小有关。在 32 位平台上,适合 long 的最大值是 2147483647 (2^31-1),因此任何大于此的值都不会适合。请改用long long 和strtoll。
【讨论】:
您可能正在转换为 32 位整数。有一些库可以解决这个问题。
尝试使用libgmp,它不会对整数的大小施加任何限制。
【讨论】:
abort'ed...