[英]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.12
和17.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.