浮动加倍给出奇怪的结果

时间:2014-04-13 11:35:54

标签: java double

我在类型转换过程中遇到了float和double的这种行为。

我修改了我的实际陈述以便更好地理解。

1

System.out.println((double)((float)(128.12301)));//Output:128.12301635712188

始终保持相同的输出。

2

System.out.println((double)((float)(128888.12301)));//Output:128888.125

这两个输出对我来说都很奇怪我无法理解它是如何工作的。

任何人都可以帮助我吗?

3 个答案:

答案 0 :(得分:3)

这里涉及几个步骤,每个步骤都有不同的编号。让我们为每个语句拆分代码:

double original = 128.12301; // Or 128888.12301
float floatValue = (float) original;
double backToDouble = (double) floatValue;
System.out.println(backToDouble);

因此,对于每个数字,步骤是:

  1. 编译时间:将源代码中的十进制值转换为最接近的确切double
  2. 执行时间:将double值转换为最接近的确切float
  3. 执行时间:将float值转换为double值(这绝不会丢失任何信息)
  4. 执行时间:将最终double值转换为字符串
  5. 步骤1和2可能会丢失信息;第4步并不总是打印完全值 - 它只是遵循Double.toString(double)所做的。

    让我们以128.12301为例。这在编译时转换为128.123009999999993624442140571773052215576171875。然后转换为float恰好产生128.123016357421875。因此,在转换转换为double(保留该值)后,我们打印出128.123016357421875。这打印128.12301635712188,因为这是可以打印出来的最少数字,而不会在该值与大于或小于它的最近double值之间不明确。

    现在有了128888.12301,确切的double值是128888.123009999995701946318149566650390625 - 最接近的float就是 128888.125。将其转换回double后,会打印出double完全值,因为其附近还有其他精确的double值。

    基本上,结果将取决于您开始时包含的有效位数,以及当它舍入到最近的double然后到最近的float时丢失了多少信息。

答案 1 :(得分:1)

System.out.println(number)将通过Double.toString(),这是一种相当复杂的方法(如文档中所示),并不总是按照您的预期行事。它基本上给出了唯一确定number的最短字符串。

  

m或a的小数部分必须打印多少位数?必须至少有一个数字来表示小数部分,并且除此之外必须有多个,但只需要多少,更多的数字来唯一地区分参数值和double类型的相邻值。也就是说,假设x是由该方法为有限非零参数d生成的十进制表示所表示的精确数学值。那么d必须是最接近x的double值;或者如果两个double值同样接近x,则d必须是其中之一,d的有效位的最低有效位必须为0.

答案 2 :(得分:0)

浮点数是32位IEEE 754浮点数。

double是64位IEEE 754浮点。

float和double是相同的,都是二进制浮点类型,但double比float更精确。

查看this了解详情