我对C语言很陌生,到目前为止我还不了解如何防止整数溢出,我读了很多文章,但我仍然不是100%确定! 在这种情况下

int ft_sqrt(int nb)
{
    长 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);
}

为了防止溢出,我应该使用

?做到这一点的最佳实践是什么?

推荐答案

long不一定比int宽,因此使用它可能不会扩大计算范围.


为了避免溢出,不要相乘,而要除法.

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

是的,代码的性能会受到影响-但OP算法有很多改进的方法)


备用代码:

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

C++相关问答推荐

为什么已经设置的值在C中被重置为for循环条件中的新值?

Ebpf内核代码:permission denied:invalid access to map value

显式地将值转换为它从函数返回的类型的含义是什么?

C:二进制搜索和二进制插入

Can函数指针指向C++中具有不同参数连续性的函数

Kdb:仅升级指定的列

Square不与Raylib一起移动

#定义SSL_CONNECTION_NO_CONST

S和查尔有什么不同[1]?

C语言中神秘的(我认为)缓冲区溢出

int * 指向int的哪个字节?

如何使用calloc和snprintf

意外的C并集结果

在git补丁中自动添加C的宏

计算时出现奇怪的计算错误;N Select K;在C中

在C中交换字符串和数组的通用交换函数

C循环条件内的函数

全局变量 y0 与 mathlib 冲突,无法编译最小的 C 代码

C11 嵌套泛型

如何确保 gcc + libc 对于多字节字符串使用 UTF-8,对于 wchar_t 使用 UTF-32?