为何C语言printf对16.125不向上取整却对16.135取整?
printf格式化double时的取整不一致问题
现象
- 执行代码
double t = 16.125; printf("%-10.2lf", t);,输出为16.12,而非预期的16.13 - 执行代码
double t = 16.135; printf("%-10.2lf", t);,输出为16.14,符合向上取整预期
原因解析
浮点数二进制存储精度限制
double是64位二进制浮点数,仅能精确表示分母为2的幂的十进制小数:- 16.125 = 16 + 1/8,分母是2^3,能被double精确存储,实际值就是16.125
- 16.135的分母是200(135/1000=27/200),无法用2的幂次表示,double存储的是它的近似值,实际略大于16.135(约为16.135000000000001)
printf默认的舍入规则:四舍六入五成双
这是一种无偏舍入法,核心逻辑:- 当舍去部分恰好等于保留位最低位的半个单位(这里是0.005)时,若保留位最后一位是偶数则舍去,是奇数则进1
- 对于16.125,保留两位小数时舍去部分恰好是0.005,第二位是2(偶数),所以直接舍去,得到16.12
- 对于16.135的实际存储值,舍去部分略大于0.005,触发普通的进1规则,得到16.14
验证代码
#include <stdio.h> int main() { double t1 = 16.125; double t2 = 16.135; // 打印高精度数值,查看实际存储值 printf("t1 高精度值: %.20lf\n", t1); printf("t2 高精度值: %.20lf\n", t2); return 0; }
内容的提问来源于stack exchange,提问作者Sei4or
相关产品推荐
相关产品推荐

