1

I have a buf char* with ASCII digits where I need to convert to an integer value on 32-bit machine.The INT_MAX constant from limits.h header give me: printf("%d\n",INT_MAX) = 2147483647. I added plus one, and put exactly this number to my function convert. By it doesn't catch up such large integer value. Would someone explain it?

My first solution:

if((unsigned int)v >= INT_MAX) doesn't work to really large numbers.

second solution:

if(v < 0) - it works, but:

1) I'm not sure if it safe really

2) I'll provide support for negative numbers in soon, so, it isn't appropriated.

Here's the current code:

#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;
}

This output -2147483648 instead of exit on if() test.

There's implementations that use some assembly code to catch such overflows with helps to jo instruction. Is this the more appropriate way to go?

Note: I haven't specified platform because it need to portable in any C compiler to 32bit machines.

4

1 回答 1

3

One way is this:

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');

The first condition, INT_MAX/10 < v, tests whether v * 10 will overflow. The second condition, INT_MAX/10 == v && INT_MAX%10 < *p - '0', tests whether the addition of *p - '0' will overflow.

于 2013-04-30T18:51:01.290 回答