java中浮点除以双与双除以双
当我在Java中尝试以下代码时:java中浮点除以双与双除以双,java,Java,当我在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应该得到一个double,那么在这种情况下float/double应该与double/doub
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应该得到一个double,那么在这种情况下float/double应该与double/double相同。用float初始化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
是的,“米尔布兰特”说得对,当我们通过隐式类型转换浮点数为双精度时,小数点处的一些信息会有所不同。这就是为什么它在除以float/double时显示不同的结果。您可能知道,
double
使用64位存储值,但float
使用32位
为了表示有效位,double
使用52位,float
使用23位。因此,double
最多可以给出15位精度,float
最多可以给出7位精度
如果您使用
浮点/double
,您实际上会尝试将最多7位精度的浮点(远至精确)除以最多15位精度的浮点(接近精确),然后将结果隐式类型转换为15位精度的浮点。typecast无法将结果从7位精度恢复到15位精度。因此,结果是不同的,尽管两者都是double
您看到这种差异的原因是因为您没有这些精确的值
即使我们假设
0.1d
和0.3d
是精确的(它们不是,你能在结果0.3333333333 7
)上看到什么,0.1f
是0.1000000149011612
,这就产生了区别。只要执行下面的代码就可以看到你想要检查的二进制数字字符串:
System.out.println(Long.toBinaryString(Double.doubleToLongBits(0.1d)));
System.out.println(Integer.toBinaryString(Float.floatToIntBits(0.1f)));
输出:
1111111011100110011010
11110111001101
你可以看到浮动位和双位的区别。因此,对于精度更高的值,浮点/双精度和双精度/双精度无法得到相同的结果。不,这是双精度,但
0.1d!=0.1f
。要获得精确的结果,只需使用BigDecimal。我们可以很好地看到,浮点(4字节)的精度约为double(8字节)的一半。0.1在二进制中是一个无限序列。等等,你实际上要求的是相同的精度,而成本只有一半?双进位16精度0.1111111 d/0.3d
无论你在16位以上的精度上加多少,都是相同的,和浮点进位8精度0.11111111 f/0.3d
无论在8位以上的精度位置添加多少,它都是相同的值,因此无法获得相同的值,因为双精度使用64位,浮点使用32位。这个答案提供了什么额外的值?正如上面提到的值,同样的结果将在执行后打印出来。这种差异是因为打字造成的。这并不能回答问题。OP在问“为什么会发生这种情况?”。