检测ASCII到整数转换中的整数溢出

时间:2013-04-30 18:33:03

标签: c integer

我有一个带有ASCII数字的buf char*我需要在32位机器上转换为整数值。来自INT_MAX标题的limits.h常量给我:printf("%d\n",INT_MAX) = 2147483647。我添加了一个,并将这个数字正确地放到我的函数转换中。通过它不会赶上如此大的整数值。有人会解释一下吗?

我的第一个解决方案:

if((unsigned int)v >= INT_MAX)对大数字无效。

第二个解决方案:

if(v < 0) - 它有效,但是:

1)我不确定它是否真的安全

2)我很快会为负数提供支持,因此,它不会被挪用。

这是当前的代码:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <limits.h>

int main(void)
{

  int v = 0;
  char* numbers = "2147483648";
  char* p=numbers;
  while(*p && isdigit(*p)) {
    if((unsigned int)v >= INT_MAX) {
      fprintf(stderr,"too large number");
      exit(1);
    }
    v = v * 10 + (*p - '0');
    p++;
  }
  printf("%d\n",v);
  return 0;
}

此输出-2147483648而不是if()测试中的退出。

有些实现使用一些汇编代码来捕获这些溢出,并有助于jo指令。这是更合适的方式吗?

注意:我没有指定平台,因为它需要在任何C编译器中移植到32位机器。

1 个答案:

答案 0 :(得分:3)

一种方法是:

if (INT_MAX/10 < v || INT_MAX/10 == v && INT_MAX%10 < *p - '0')
{
    fprintf(stderr,"too large number");
    exit(1);
}
v = v * 10 + (*p - '0');

第一个条件INT_MAX/10 < v测试v * 10是否会溢出。第二个条件INT_MAX/10 == v && INT_MAX%10 < *p - '0'测试*p - '0'的添加是否会溢出。