当我在Java中尝试以下代码时:
System.out.println("0.1d/0.3d is " + 0.1d/0.3d)
System.out.println("0.1f/0.3d is " + 0.1f/0.3d)
我将获得以下输出:
0.1d/0.3d is 0.33333333333333337
0.1f/0.3d is 0.3333333383003871
如果float/double应该获得双重,则在这种情况下,float/double应该与double/double相同。
只需执行以下代码即可查看要检查的数字的二进制字符串:
System.out.println(Long.toBinaryString(Double.doubleToLongBits(0.1d)));
System.out.println(Integer.toBinaryString(Float.floatToIntBits(0.1f)));
输出:
111111111100110011001100110011001100110011001100110011001100110011010
111101110011001100110011001101
,您会看到浮子钻头和双倍位的差异。因此,对于更长的精确值,我们无法获得浮点/双/双/双/双/双/double的结果。
是"米尔布兰特"(Milbrandt)说,当我们通过隐式打字在小数点处的某些信息将浮点数转换为double时,正确。这就是为什么它在除外时显示不同的结果 float/double。
您可能知道,double
使用64位存储一个值,但float
32位。
代表显着,double
使用52位,float
使用23位。因此,double
最多可以给出15位数字精度,而float
可以给出7。
如果您执行float / double
,则实际上尝试将浮点以7位精度(远至精确)除以具有15位数字精度的浮点(更接近精确),然后将结果隐式地将结果分类为具有15位精度的浮点。该类型不能将您的结果从7位精度恢复到15位。因此,结果是不同的,尽管它们都是double
。
然后用浮子初始化双重并分开。您会看到相同的结果。
double f = 0.1f;
double d = 0.1d;
double n = 0.3d;
System.out.println("float /double = " + f/n);
System.out.println("double/double = " + d/n);
结果是
float /double = 0.3333333383003871
double/double = 0.33333333333333337
您看到此区别的原因是因为您没有这些确切的值。
即使我们假设 0.1d
和 0.3d
是准确的(它们不是,您可以在结果 0.33333333333333337
上看到的), 0.1f
是 0.10000000149011612
,这与众不同。