为什么使用 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++)
我正在调试一些需要调试和修复错误或可能的错误的代码。在其中一个例子中,据说 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++)