(上下文:我正在为嵌入式应用程序编写一个轻量级的printf(),并且我希望它在实际中表现得像真正的printf()。)
据我所知,gcc和其他表现良好的图书馆使用" round of half to even" (又名"银行家的四舍五入")以防止在以下情况下出现统计偏差:
printf("%0.0f %0.0f %0.0f %0.0f\n", 0.5, 1.5, 2.5, 3.5);
=> 0 2 2 4
令我感到惊讶的是,相同的舍入规则不适用于其他精度:
printf("%0.1f %0.1f %0.1f %0.1f\n", 0.05, 0.15, 0.25, 0.35);
=> 0.1 0.1 0.2 0.3
这是预期的行为吗?我原以为:
=> 0.0 0.2 0.2 0.4
精通数值计算的人能解释哪种行为是理想的,为什么?
(注意:有关实例,请参阅http://rextester.com/IUXDW9788。)
答案 0 :(得分:4)
不同之处在于输入数字,而不是格式。
0.5,1.5,2.5,3.5和0.25都可以在IEEE 754 64位二进制文件中完全表示,这是C double的最可能的实现,因此适用舍入到偶数规则。
0.05的最接近的可表示值是0.05000000000000000277555756156289135105907917022705078125,它接近0.1而不是0.0
与0.15最接近的可表示值为0.1499999999999999944488848768742172978818416595458984375,接近0.1而不是0.2。
0.35的最接近的可表示值是0.34999999999999997779553950749686919152736663818359375,接近0.3而不是0.4。
“舍入到偶数”规则仅适用于两个可能结果之间完全的数字,而不是与可能结果之一相比更接近另一个的数字。