我知道strictfp模式下的转换用于可移植性,而不是this question中提到的准确性。但是,Java语言规范,Java SE 8版本说
从float到double 的扩展原语转换(不是strictfp )可能会丢失有关转换值总体大小的信息。
在我看来,扩展的原始转换即strictfp 旨在提高准确性。此外,我怀疑double可以表示float可以采用的所有值,其中我认为没有理由将float从double转换为double。
修改
规范中的“ ...可能会丢失有关...... 的信息”让我感觉非严格模式下的转换与strictfp相比具有某种准确性模式。这对我来说没有意义,因为非严格模式下的转换可能会以更高的精度使用中间值。这个问题首先是基于这种理解而写的,可能看起来并不像你期望的那样令人满意。
答案 0 :(得分:3)
英特尔的IA64架构使用固定浮点寄存器格式,一个符号位,17个指数位和64个有效位。当浮点数从其中一个寄存器存储到32或64位变量时,必须进行转换。
Java旨在获得一致的结果,因此不希望表达式的值根据中间结果是保存在寄存器中还是作为内存中的float或double而改变。
最初,Java只是坚持要完成所有计算,就好像存储了所有中间结果一样。由于难以在每次计算时将指数强制到正确的范围,结果表明性能很差。解决方案是让程序员在完全一致的strictfp模式和更宽松的模式之间做出选择,在该模式下,指数可以超出表达式类型的范围,而不会将值强制为零或无穷大。
假设在宽松模式下,寄存器内浮点数的指数超出双指数范围,并且正在转换为内存中的双精度数。该转换将迫使该值为零或无穷大,从而失去其幅度。这是一般规则的一个例外,即扩大算术转换可以保持总体幅度。
如果在strictfp模式下进行相同的计算,则不允许浮点数具有浮点指数范围之外的指数。无论生成什么计算,它都会将值强制为零或无穷大。每个浮点值都可以用double表示,因此转换根本不会改变值,更不用说丢失整体幅度了。