best way to recognize and handle integer overflow in c?

106 Views Asked by At

I am so new in C and so far I didn't comprehend how to prevent from integer overflow, I read many articles but still I am not 100% sure! in this case

int ft_sqrt(int nb)
{
    long int    sqrt;
    
    if (nb <= 0)
        return (0);
    if (nb == 1)
        return (1); 
    sqrt = 1;
    while (sqrt * sqrt < nb)
    {
        sqrt++;
    }
    if (sqrt * sqrt == nb)
        return (sqrt);
    else
        return (0);
}

to prevent overflow should I use

long

? what is the best practice to do that?

2

There are 2 best solutions below

0
chux - Reinstate Monica On BEST ANSWER

long is not certainly wider than int and so its use may not widen the computation.


To certainly avoid overflow, don't multiple, but divide.

int ft_sqrt(int nb) {
    int    sqrt;
    if (nb <= 0)
        return (0);
    if (nb == 1)
        return (1); 
    sqrt = 1;
    // while (sqrt * sqrt < nb)
    while (sqrt < nb / sqrt) {
        sqrt++;
    }
    if (sqrt == nb / sqrt)
        return (sqrt);
    else
        return (0);
}

Yes code takes a performance hit - yet OP algorithm has many ways for improvement)


Alternate code:

unsigned bit_width(unsigned x) {
  unsigned width = 0;
  while (x) {
    x /= 2;
    width++;
  }
  return width;
}

unsigned usqrt(unsigned x) {
  if (x == 0) {
    return 0;
  }
  unsigned y = 1u << bit_width(x) / 2;
  unsigned y_previous;
  unsigned diff;
  unsigned diff1count = 0;

  do {
    y_previous = y;
    y = (y + x / y) / 2;
    diff = y_previous < y ? y - y_previous : y_previous - y;
    if (diff == 1)
      diff1count++;
  } while (diff > 1 || (diff == 1 && diff1count <= 1));
  y = (y_previous + y) / 2;
  return y;
}
0
Alef Carneiro de Sousa On

So, first of all, you need to know if you want to detect an overflow or if you could just avoid them.

To just avoid them, if you know how long nb can be, maybe you could see if long or long long is big enough. And, if it isn't, maybe the solution proposed by @Jonathan Leffler of using while (sqrt < nb / sqrt) is the way to making it fit in one of those types.

Now, if you really want/need to check for overflow, then you'll need to check for square_root(MAX_NUMBER_ALLOWED) < sqrt, where MAX_NUMBER_ALLOWED would depend on which type you are using. C/C++ already have constants for that, you can check them here.