简体   繁体   English

在不损失精度的情况下安全地将“float”转换为“double”

[英]Safely convert `float` to `double` without loss of precision

I have the following head scratcher, demonstrated in jshell 11.0.12 and 17.0.1 here我有以下头部刮刀,在jshell 11.0.1217.0.1中演示

jshell> 13.9f
$1 ==> 13.9

jshell> 13.9
$2 ==> 13.9

jshell> (double) 13.9f
$3 ==> 13.899999618530273

The same thing occurs in a simple compiled class in both versions同样的事情发生在两个版本的简单编译的 class 中

strictfp public class Test {

    public strictfp static void main(String[] args) {
        System.out.format("%s%n", (double) 13.9f);
        System.out.format("%s%n", 13.9f);
    }

}
╰─➤  java Test      
13.899999618530273
13.9

Although 17 warns that strictfp is no longer required虽然 17 警告不再需要strictfp

warning: [strictfp] as of release 17, all floating-point expressions are evaluated strictly and 'strictfp' is not required

The JLS says this in section 5.1.2 JLS在第 5.1.2 节中说明了这一点

A widening primitive conversion does not lose information about the overall
magnitude of a numeric value in the following cases, where the numeric value is
preserved exactly:
• from an integral type to another integral type
• from byte, short, or char to a floating-point type
• from int to double
• from float to double

In 14 it contained the following after the bullet list在 14 中,它在项目符号列表之后包含以下内容

A widening primitive conversion from float to double that is not strictfp may
lose information about the overall magnitude of the converted value.

Based on my reading this is a bug in the implementation?根据我的阅读,这是实施中的错误吗? The only reliable way I've found to perform this conversion is Double.parseDouble(Float.toString(13.9f)) .我发现执行此转换的唯一可靠方法是Double.parseDouble(Float.toString(13.9f))

Based on my reading this is a bug in the implementation?根据我的阅读,这是实施中的错误吗?

No. It's a bug in your expectations.不,这是您期望中的错误。 The double value you're seeing is exactly the same value as the float value.您看到的double精度值与float值完全相同。 The precise value is 13.8999996185302734375.精确值为 13.8999996185302734375。

That's not the same as "the closest double value to 13.9" which is 13.9000000000000003552713678800500929355621337890625.与“最接近 13.9 的double精度值”不同,后者是 13.9000000000000003552713678800500929355621337890625。

You're assigning the value 13.8999996185302734375 to a double value, and then printing the string representation - which is 13.899999618530273 as that's enough precision to completely distinguish it from other double values.您将值 13.8999996185302734375 分配给double精度值,然后打印字符串表示形式 - 即 13.899999618530273,因为这足以将其与其他double精度值完全区分开来。 If it were to print 13.9, that would be a bug, as there's a double value that's closer to 13.9, namely 13.9000000000000003552713678800500929355621337890625.如果要打印 13.9,那是一个错误,因为有一个更接近 13.9 的double精度值,即 13.90000000000000003552713678800500929355621337890625。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM