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

当我在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/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在问“为什么会发生这种情况?”。