我在类型转换过程中遇到了float和double的这种行为。
我修改了我的实际陈述以便更好地理解。
1
System.out.println((double)((float)(128.12301)));//Output:128.12301635712188
始终保持相同的输出。
2
System.out.println((double)((float)(128888.12301)));//Output:128888.125
这两个输出对我来说都很奇怪我无法理解它是如何工作的。
任何人都可以帮助我吗?
答案 0 :(得分:3)
这里涉及几个步骤,每个步骤都有不同的编号。让我们为每个语句拆分代码:
double original = 128.12301; // Or 128888.12301
float floatValue = (float) original;
double backToDouble = (double) floatValue;
System.out.println(backToDouble);
因此,对于每个数字,步骤是:
double
值double
值转换为最接近的确切float
值float
值转换为double
值(这绝不会丢失任何信息)double
值转换为字符串步骤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)