为什么使用 round() 而不是 floor() 可能会导致 C 中的错误/(程序错误)?

Why using round() instead of floor() may cause bug/(program error) in C?

我正在调试一些需要调试和修复错误或可能的错误的代码。在其中一个例子中,据说 round() 可能会导致错误并用 floor() 修复了它。但是,我不太明白为什么。

任何人都可以举出前面的例子吗?

for (unsigned y = 0; y < round(factor * img->size_y); y++) { // round changed to floor
  for (unsigned x = 0; x < round(factor * img->size_x); x++) { // round changed to floor

    /* Calculate the location of the pixel in the old image */
    unsigned nearest_x = x / factor;
    unsigned nearest_y = y / factor;

    /* Store the pixel */
    image_data_new[y][x] = image_data[nearest_y][nearest_x];
  }
}

将上面的代码 round() 替换为 floor() 以避免可能的攻击或错误。

初始化代码:

struct pixel(*image_data_new)[new_width] =
        (struct pixel(*)[new_width])new_img->px;

其中 new_width:

unsigned new_width = (unsigned)(img->size_x * factor);
double factor = atof(argv[3]);

如果 round 向上舍入,nearest_y 可以等于 img->size_y,它大于用于索引的数组的维数。

你的尺寸好像是

unsigned new_width = (unsigned)(img->size_x * factor);

在这种情况下,转换为整数与 floor 具有相同的效果。

现在您正在使用

for (unsigned x = 0; x < round(factor * img->size_x); x++) 

这真的是自找麻烦,因为如果小数部分四舍五入的结果高于 .5(并且可以缓冲区溢出)。只需使用之前计算的值:

for (unsigned x = 0; x < new_width; x++)