double类型小数点精度

问题遇到的现象和发生背景

double类型小数点精度

问题相关代码,请勿粘贴截图

[root@localhost tmp]# cat aa.c
#include
#include
void main()
{
/case 1/
printf("111 %.15f\n", 1.234567890123456 + 1e-15);

double d1;
/*case 2*/
d1 = 1.234567890123456;
d1 = d1 + 1e-15;
printf("222 %.15g\n", d1);

/*case 3*/
d1 = 1.234567890123456;
d1 = d1 + 1e-15;
printf("222 %.16g\n", d1);

}

运行结果及报错内容

[root@localhost tmp]# ./a.out
111 1.234567890123457
222 1.23456789012346
222 1.234567890123457

我的解答思路和尝试过的方法

case1和case2看起来是一样的操作,为什么同样用%.15g显示,case2丢了一位呢,正确结果是1.234567890123457,结果四舍五入为1.23456789012346了。而在case 3中改为%.16多一位显示,结果就正确了

我想要达到的结果

为什么要用%.16才正确显示15位的计算结果,是因为补码?

[root@localhost tmp]# cat main.c
#include <stdio.h>
#include <stdlib.h>
void main()
{
printf("1e-15:%.15f\n", 1e-15);
printf("1e-15:%.15f\n", 1.234567890123456 + 1e-15);
double d1 = 1234567890123456789;
printf("111 %f\n", d1);
d1 = 1.234567890123456e+15;
d1 = d1 + 1;
printf("222 %.15g\n", d1);
d1 = 1.234567890123456;
d1 = d1 + 1e-15;
printf("333 %.16g\n", d1);
printf("1200000.1: %g\n", 1200000.1);
printf("1: %g\n", 1);
printf("1.0: %g\n", 1.0);
}
[root@localhost tmp]# ./a.out
111 1.23456789012346
222 1.23456789012346
333 1.234567890123457
--代码有点问题,将%.15f改为%.15g就一致了,现在看来用%.15g的话必丢一位,难道%.15要去掉一个小数点,只能表示14位小数?

#include
#include
using namespace std;
int main()
{
cout<<fixed<<setprecision(8)<<endl
}