Java:添加2个浮点数,结果为double

Java:添加2个浮点数,结果为double,java,floating-point,double,Java,Floating Point,Double,据我所知,双精度数字在内存中保留64位。浮点数保留32位 我尝试了以下方法: double result=0.1f+0.3f; System.out.println(result); 因此,它会打印0.4000000059604645。是来自下一个内存块的数据(前32位和后32位)? 是别的吗 这一行: double result=0.1f+0.3f; 首先将字符串“0.1”和“0.3”转换为float值,然后使用float的规则添加这两个float值,最后将结果转换为double以执行赋值

据我所知,双精度数字在内存中保留64位。浮点数保留32位

我尝试了以下方法:

double result=0.1f+0.3f;
System.out.println(result);
因此,它会打印
0.4000000059604645
。是来自下一个内存块的数据(前32位和后32位)?
是别的吗

这一行:

double result=0.1f+0.3f;
首先将字符串“0.1”和“0.3”转换为
float
值,然后使用
float
的规则添加这两个
float
值,最后将结果转换为
double
以执行赋值。将浮点文本转换为
float
值会引入舍入错误。(就像1/3在基数10中有无限重复扩展一样,1/10和3/10在基数2中有无限重复扩展,并且不能在
float
double
中精确表示)添加
float
可能会引入更多的错误(双关语)。从
float
double
的扩展是精确的,但系统随后假设扩展的分辨率包含有意义的数据

如果希望使用
double
的规则进行加法,则需要首先将至少一个操作数转换为
double
,可以使用强制转换,也可以使用
double
文字:

double result=0.1f+0.3d;
在上述情况下,0.3将转换为
double
到full
double
精度;0.1将转换为
浮点
,然后扩展为
双精度
,从而产生
双精度
值,其舍入误差大于
0.1d
。大多数编译器都会在编译时执行此操作

使用Oracle的javac编译器编译此代码(版本1.7.0_11,默认设置):

生成如下开头的字节码(使用javap-c进行反汇编):

并产生以下输出:

dff=0.4000000059604645  
dfd=0.4000000014901161  
ddd=0.4  
dff==dfd: false  
dff==ddd: false  
dfd==ddd: false  
ddd==0.4: true
最后一行显示“true”,因为0.1d和0.3d的表示错误以及加法的舍入错误(如果有)恰好以与0.4d的表示错误完全匹配的方式组合在一起。如果您将
0.3
更改为
0.2
(并将
10*ddd==4
更改为
10*ddd==3
),情况就不会这么好了

通常,无论您使用的是
浮点
还是
双精度
,都会出现一些舍入误差,结果不太可能精确。对于扩展精度,您应该使用。如果您只需要外观整洁的输出,请使用格式说明符(例如,使用
System.out.printf()
String.format()


您还应该阅读。

请参阅:0.4没有精确的基数2表示法。在最低的条件下,它是2/5,5不是2的任何幂的系数。实际的双位模式是0x3FD9999999A,相当于0.40000000000000002220446049250313080847263336181640625。最后一个“真”的意思是ddd的值是最接近小数点0.4的双精度。@PatriciaShanahan-捕捉得好。我不知道我在想什么。我重新表述了答案的那一部分。不过,有趣的是,10*(0.4d)==4(精确)。有时,一次计算的舍入误差会抵消上一次计算的舍入误差,从而得到精确的结果。这就是在10*(0.4d)计算中发生的情况。
ldc2_w        #2                  // double 0.4000000059604645d
dstore_1
ldc2_w        #4                  // double 0.4000000014901161d
dstore_3
ldc2_w        #6                  // double 0.4d
dstore        5
dff=0.4000000059604645  
dfd=0.4000000014901161  
ddd=0.4  
dff==dfd: false  
dff==ddd: false  
dfd==ddd: false  
ddd==0.4: true