C++中printf保留三位小数时+1e-7修正输出的原理咨询
浮点数printf四舍五入异常的原因与解决方案解释
我遇到一个C++浮点数输出的问题:
下面这段代码运行结果是72.740,但预期应该是72.741:
mx = 72.74050000; printf("%.3lf", mx);
后来找到解决方案,给mx加上1e-7后输出符合预期:
mx = 72.74050000; printf("%.3lf", mx + 1e-7);
但我不清楚这个方法的原理,同时试了另一段代码,输出结果是72.7405,没看到明显变化:
mx = 72.74050003; cout << mx + 1e-10;
原代码输出不符合预期的原因
这是因为浮点数的二进制存储精度限制。像72.7405这样的十进制小数,无法被C++中的double类型精确表示,实际存储的值会略小于72.7405。当printf用%.3lf格式化时,会对这个略小的值进行四舍五入,最终得到72.740而非预期的72.741。
加1e-7解决问题的原理
添加1e-7本质是给存储的略小值补一个微小偏移,让它刚好跨过四舍五入的阈值。原存储值比72.7405小一点点,加上1e-7后,整体值会略大于72.7405,printf四舍五入时就会进位到72.741。
1e-7是针对double类型精度选择的——double的精度约为15-17位十进制有效数字,这个值足够小,不会影响正常数值,但刚好能修正这类精度误差。
第二段代码加1e-10无变化的原因
你测试的72.74050003,其存储值与真实值的误差远小于1e-10,加上这么小的偏移后,数值的有效位数没有发生足以改变输出结果的变化。另外cout默认输出精度是6位有效数字,72.7405刚好是6位,所以即使加了1e-10,输出还是72.7405。
内容的提问来源于stack exchange,提问作者Ank H
相关产品推荐
相关产品推荐

