为什么从float转换为double会改变这个值?

art*_*ire 16 java floating-point precision double ieee-754

我一直试图找出原因,但我不能.有谁能够帮我?

请看下面的例子.

float f = 125.32f;
System.out.println("value of f = " + f);
double d = (double) 125.32f; 
System.out.println("value of d = " + d);
Run Code Online (Sandbox Code Playgroud)

这是输出:

值f = 125.32

值d = 125.31999969482422

Eri*_*hil 16

float转换为a时,a的值不会改变double.显示的数字存在差异,因为需要更多的数字来区double分值与其邻居,这是Java文档要求的.这是文档toString,从文档中引用(通过几个链接)println.

确切的值125.32f是125.31999969482421875.两个相邻float值是125.3199920654296875和125.32000732421875.观察125.32比任何一个邻居更接近125.31999969482421875.因此,通过显示"125.32",Java已显示足够的数字,以便从十进制数字转换回来float再现float传递给的值println.

两个相邻double值125.31999969482421875是125.3199996948242045391452847979962825775146484375和125.3199996948242329608547152020037174224853515625.观察到125.32比后者更接近于原始值.因此,打印"125.32"不包含足以区分原始值的数字.Java必须打印更多数字,以确保从显示的数字转换回来double再现double传递给的值println.

  • @Amro:多余的数字不会被丢弃或忽略。对浮点对象执行的算术的行为就好像它们具有完全的完整值一样,包括我显示的值。那是因为它们确实具有这些完整的价值。IEEE 754规范指出它们完全具有这些值,而没有其他值。计算机**不**将它们用作带有几位数字的十进制近似值。计算机使用它们以二进制形式进行计算,并且它们具有指定的值。 (2认同)

Pas*_*uoq 12

  1. 当您将a转换float为a时double,不会丢失任何信息.每个float都可以完全表示为a double.
  2. 另一方面,打印的十进制表示都不是数字System.out.println的确切值.精确的十进制表示可能需要最多约760个十进制数字.相反,System.out.println打印精确的十进制数字的数字,允许将十进制表示解析回原始floatdouble.还有更多的doubles,所以在打印时,System.out.println需要在表示变得明确之前打印更多的数字.


Mar*_*nik 4

正如JLS 所指定的float,从到 的转换double扩大转换。扩大转换被定义为较小集合到其超集的单射映射。因此,从到转换后,所表示的数字不会改变floatdouble

有关您更新的问题的更多信息

在您的更新中,您添加了一个示例,该示例应该证明该数字已更改。但是,它仅表明数字的字符串表示形式已更改,这实际上是由于通过转换为 获得的额外精度所致double。请注意,您的第一个输出只是第二个输出的舍入。由 指定 Double.toString

必须至少有一位数字来表示小数部分,除此之外,还必须有尽可能多的数字来唯一区分参数值与类型的相邻值double

由于 类型 中的相邻值double比 中的相邻值更接近float,因此需要更多的数字来遵守该规则。