在不损失精度的情况下安全地将 `float` 转换为 `double`
Safely convert `float` to `double` without loss of precision
我有以下令人头疼的东西,在 jshell
11.0.12
和 17.0.1
此处演示
jshell> 13.9f
==> 13.9
jshell> 13.9
==> 13.9
jshell> (double) 13.9f
==> 13.899999618530273
在两个版本
中的简单编译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
尽管 17 警告不再需要 strictfp
warning: [strictfp] as of release 17, all floating-point expressions are evaluated strictly and 'strictfp' is not required
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
在 14 中,项目符号列表后包含以下内容
A widening primitive conversion from float to double that is not strictfp may
lose information about the overall magnitude of the converted value.
根据我的阅读,这是实现中的错误?我发现执行此转换的唯一可靠方法是 Double.parseDouble(Float.toString(13.9f))
.
Based on my reading this is a bug in the implementation?
没有。这是您期望中的错误。您看到的 double
值与 float
值完全相同。精确值为13.8999996185302734375.
这 不 与“最接近 13.9 的 double
值”相同,即 13.9000000000000003552713678800500929355621337890625。
您将值 13.8999996185302734375 分配给 double
值,然后打印字符串表示形式 - 即 13.899999618530273,因为它的精度足以将其与其他 double
值完全区分开来。如果要打印 13.9,那 会 是一个错误,因为有一个 double
值更接近 13.9,即 13.9000000000000003552713678800500929355621337890625.
我有以下令人头疼的东西,在 jshell
11.0.12
和 17.0.1
此处演示
jshell> 13.9f
==> 13.9
jshell> 13.9
==> 13.9
jshell> (double) 13.9f
==> 13.899999618530273
在两个版本
中的简单编译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
尽管 17 警告不再需要 strictfp
warning: [strictfp] as of release 17, all floating-point expressions are evaluated strictly and 'strictfp' is not required
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
在 14 中,项目符号列表后包含以下内容
A widening primitive conversion from float to double that is not strictfp may
lose information about the overall magnitude of the converted value.
根据我的阅读,这是实现中的错误?我发现执行此转换的唯一可靠方法是 Double.parseDouble(Float.toString(13.9f))
.
Based on my reading this is a bug in the implementation?
没有。这是您期望中的错误。您看到的 double
值与 float
值完全相同。精确值为13.8999996185302734375.
这 不 与“最接近 13.9 的 double
值”相同,即 13.9000000000000003552713678800500929355621337890625。
您将值 13.8999996185302734375 分配给 double
值,然后打印字符串表示形式 - 即 13.899999618530273,因为它的精度足以将其与其他 double
值完全区分开来。如果要打印 13.9,那 会 是一个错误,因为有一个 double
值更接近 13.9,即 13.9000000000000003552713678800500929355621337890625.