C 中的舍入 (math.h) 无法正常工作
Rounding (math.h) in C not working as it should
#include <stdio.h>
#include <math.h>
int main(){
printf("Rounded value of 6*0.95*0.25 = %.2f\n", round(6*0.95*0.25*100)/100);
printf("Rounded value of 1.425 = %.2f\n", round(1.425*100)/100);
}
我怀疑这与双精度和各自的算术精度有关,但我如何解决这个问题(这样 6*0.95*0.25 即 1.425 将四舍五入为 1.43)我不知道....
(我使用的是最新版本的GNU编译器(1.7左右))
感谢帮助
我正在尝试四舍五入到 2 d.p。
输出如下:
6*0.95*0.25 的舍入值 = 1.42
舍入值 1.425 = 1.43
( https://onlinegdb.com/r1ZtZ2lCW )
我要
6*0.95*0.25 的舍入值 = 1.43
舍入值 1.425 = 1.43
math.h 中的舍入完全正常。当你给你的程序一个像 1.425 这样的十进制数时,它会将它存储为该数字最接近的二进制表示形式。数字 1.425 = 57 / 40。因为 40 不是 2 的幂,所以这个数字没有精确的二进制表示。在这种情况下,存储的数字略小于 1.425,因此数字向下舍入。
停止这种舍入差异的唯一通用解决方案是使用十进制浮点实现。除非硬件支持,否则这将比二进制浮点实现慢得多。
我的解决方案是实现以下功能:
double twoDPRoundHack(double x){
return round(round(x*10000)/100)/100;
}
这似乎有效
#include <stdio.h>
#include <math.h>
double twoDPRoundHack(double x){
return round(round(x*1000)/100)/100;
}
int main(){
printf("Rounded value of 6*0.95*0.25 = %.2f\n",
twoDPRoundHack(6*0.95*0.25*100));
printf("Rounded value of 1.425 = %.2f\n", round(1.425*100)/100);
}
很明显,它被存储为 142.499999999999...
如果您在打印语句之外进行计算,您将得到正确答案
#include <stdio.h>
#include <math.h>
int main (){
float value = 6*0.95*0.25;
printf ("Rounded value of 6*0.95*0.25 = %.2f\n",
round(value*100)/100);
printf ("Rounded value of 1.425 = %.2f\n", round (1.425 * 100) / 100);
}
输出
Rounded value of 6*0.95*0.25 = 1.43
Rounded value of 1.425 = 1.43
这似乎确实没有按预期工作。我不知道它是否有帮助,但改变乘法的顺序似乎可以解决问题。
#include <stdio.h>
#include <math.h>
int main(){
printf("Rounded value of 6*0.95*0.25 (hundred last) = %.2f\n", round(6*0.95*0.25*100)/100);
printf("Rounded value of 6*0.95*0.25 (hundred first) = %.2f\n", round(100*6*0.95*0.25)/100);
printf("Rounded value of 1.425 = %.2f\n", round(100*1.425)/100);
}
输出
Rounded value of 6*0.95*0.25 (hundred last) = 1.42
Rounded value of 6*0.95*0.25 (hundred first) = 1.43
Rounded value of 1.425 = 1.43
这显然是超级愚蠢的!也许其中有关于问题原因的线索。
#include <stdio.h>
#include <math.h>
int main(){
printf("Rounded value of 6*0.95*0.25 = %.2f\n", round(6*0.95*0.25*100)/100);
printf("Rounded value of 1.425 = %.2f\n", round(1.425*100)/100);
}
我怀疑这与双精度和各自的算术精度有关,但我如何解决这个问题(这样 6*0.95*0.25 即 1.425 将四舍五入为 1.43)我不知道....
(我使用的是最新版本的GNU编译器(1.7左右))
感谢帮助
我正在尝试四舍五入到 2 d.p。
输出如下:
6*0.95*0.25 的舍入值 = 1.42
舍入值 1.425 = 1.43
( https://onlinegdb.com/r1ZtZ2lCW )
我要
6*0.95*0.25 的舍入值 = 1.43
舍入值 1.425 = 1.43
math.h 中的舍入完全正常。当你给你的程序一个像 1.425 这样的十进制数时,它会将它存储为该数字最接近的二进制表示形式。数字 1.425 = 57 / 40。因为 40 不是 2 的幂,所以这个数字没有精确的二进制表示。在这种情况下,存储的数字略小于 1.425,因此数字向下舍入。
停止这种舍入差异的唯一通用解决方案是使用十进制浮点实现。除非硬件支持,否则这将比二进制浮点实现慢得多。
我的解决方案是实现以下功能:
double twoDPRoundHack(double x){
return round(round(x*10000)/100)/100;
}
这似乎有效
#include <stdio.h>
#include <math.h>
double twoDPRoundHack(double x){
return round(round(x*1000)/100)/100;
}
int main(){
printf("Rounded value of 6*0.95*0.25 = %.2f\n",
twoDPRoundHack(6*0.95*0.25*100));
printf("Rounded value of 1.425 = %.2f\n", round(1.425*100)/100);
}
很明显,它被存储为 142.499999999999...
如果您在打印语句之外进行计算,您将得到正确答案
#include <stdio.h>
#include <math.h>
int main (){
float value = 6*0.95*0.25;
printf ("Rounded value of 6*0.95*0.25 = %.2f\n",
round(value*100)/100);
printf ("Rounded value of 1.425 = %.2f\n", round (1.425 * 100) / 100);
}
输出
Rounded value of 6*0.95*0.25 = 1.43
Rounded value of 1.425 = 1.43
这似乎确实没有按预期工作。我不知道它是否有帮助,但改变乘法的顺序似乎可以解决问题。
#include <stdio.h>
#include <math.h>
int main(){
printf("Rounded value of 6*0.95*0.25 (hundred last) = %.2f\n", round(6*0.95*0.25*100)/100);
printf("Rounded value of 6*0.95*0.25 (hundred first) = %.2f\n", round(100*6*0.95*0.25)/100);
printf("Rounded value of 1.425 = %.2f\n", round(100*1.425)/100);
}
输出
Rounded value of 6*0.95*0.25 (hundred last) = 1.42
Rounded value of 6*0.95*0.25 (hundred first) = 1.43
Rounded value of 1.425 = 1.43
这显然是超级愚蠢的!也许其中有关于问题原因的线索。