为何使用math.h的round()函数无法正确四舍五入,结果均向下取整?
灰度化函数四舍五入失效问题解决
问题描述:
编写灰度化函数时,使用round()对RGB平均值做四舍五入,但所有结果都向下取整,完全没实现预期的四舍五入效果。即使把avg改为float类型,或者改用roundf()都无效。比如输入RGB值为27、28、28时,计算出的平均值是27,但正确结果应该是28。
原代码:
void grayscale(int height, int width, RGBTRIPLE image[height][width]) { int avg = 0; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { avg = round((image[i][j].rgbtRed + image[i][j].rgbtGreen + image[i][j].rgbtBlue) / 3); image[i][j].rgbtRed = avg; image[i][j].rgbtGreen = avg; image[i][j].rgbtBlue = avg; } } return; }
问题根源:
C语言中,整数之间的除法会自动舍弃小数部分。代码里rgbtRed + rgbtGreen + rgbtBlue是三个int类型相加,结果仍是int;除以3(同样是int)时,会直接执行整数除法——比如27+28+28=83,83/3的整数除法结果是27,再传给round()函数时,round(27)自然还是27,完全没起到四舍五入的作用。
解决方案:
需要让除法变成浮点除法,只要把其中一个操作数转为浮点类型即可,两种常见实现方式:
- 将RGB的和强制转换为float类型:
avg = round( (float)(image[i][j].rgbtRed + image[i][j].rgbtGreen + image[i][j].rgbtBlue) / 3 );
- 用浮点型的3.0代替整数3进行除法:
avg = round( (image[i][j].rgbtRed + image[i][j].rgbtGreen + image[i][j].rgbtBlue) / 3.0 );
修改后,83/3.0会得到27.666...,round()处理后就能得到正确的28,实现预期的四舍五入效果。
内容的提问来源于stack exchange,提问作者user75470
相关产品推荐
相关产品推荐

