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