float
变量中的尾数位总共为23,而double
变量为53。
这意味着可以由
精确表示的数字 float
变量总共为log10(2^23) = 6.92368990027 = 6
和double
变量log10(2^53) = 15.9545897702 = 15
让我们看看这段代码:
float b = 1.12391;
double d = b;
cout<<setprecision(15)<<d<<endl;
打印
1.12390995025635
然而这段代码:
double b = 1.12391;
double d = b;
cout<<setprecision(15)<<d<<endl;
打印1.12391
有人可以解释为什么我会得到不同的结果吗?我将一个6位浮点变量转换为double,编译器必须知道这6位数是重要的。为什么?因为我没有使用更多的数字,所有数字都不能在float变量中正确表示。因此,不是打印正确的值,而是决定打印其他内容。
答案 0 :(得分:4)
从float
转换为double
会保留该值。因此,在第一个代码段中,d
恰好包含float
精度为112391/100000的近似值。理性112391/100000以float
格式存储为9428040/2 23 。如果执行此除法,结果恰好是1.12390995025634765625:float
近似值不是非常接近。 cout <<
将表示打印到小数点后的14位数。第一个省略的数字是7,因此最后打印的数字4将向上舍入为5。
在第二个片段中,d
包含值{112}的真实值的近似值为double
,1.123909999999999964614971759147010743618011474609375(换句话说,5061640657197974/2 52 )。这种近似更接近于理性。如果在小数点后面打印了14位数字,则最后的数字全部为零(在舍入后因为第一个省略的数字为9)。 cout <<
不会打印尾随零,因此您会看到1.12391作为输出。
因为我没有使用更多数字,而这些数字都无法在浮点变量中正确表示
当您错误地将log10应用于2 23 (它应该是2 24 )时,您将获得可以存储在float中的小数位数。由于float
的表示不是十进制,因此这七个左右后的数字通常不是零。对于编译器为您编写的数字选择的最接近的二进制表示,它们是十进制的数字。
答案 1 :(得分:1)
浮动b = 1.12391;
问题在这里,而且在这里:
double b = 1.12391;
这些作业已经不准确了。因此,使用它们的计算或演员也是不精确的。
答案 2 :(得分:0)
你错误地假设前6位数字精确相同。当我们说float精确到6(十进制)数字时,我们的意思是实际值和预期值之间的相对差异小于10 -6 。因此,1.12390995和1.12391相差0.0000005。这比你可以依赖的10 -6 要好得多。