Java Explicit Cast from Double 到 Int 的舍入规则是什么

问题描述 投票:0回答:2

今天演示 Java 显式类型转换时遇到了一个奇怪的怪癖,并且想知道为什么会发生这种情况。

如果我将 double 转换为 int,并且我的数字是 0.9 到 16 精度,它将向上舍入。 (请参阅代码中的注释)如果我将其设为 15 精度,则会向下舍入。

同样,如果我将数字设为 0.8...它仍会向下舍入。

        double a = 5.9999999999999999;// 16 precision rounds to 6
        double a1 = 5.8888888888888888; // 16 precision rounds to 5
        double b = 5.999999999999999;// 15 precision rounds to 5
        double c = 5.111111111111111111111111111111111111111; //rounds to 5
        int cast = (int)a;
        for (int i = 0 ; i < 1000000 ; i++){
            System.out.print(cast);
        }

最初以为我溢出了int,但事实似乎并非如此。

有什么想法吗?

java casting integer double
2个回答
0
投票

这与投射到

int
无关。

如果打印

a
的值:

double a = 5.9999999999999999;
System.out.println(a);

打印出

6.0

这是因为 double 的精度有限,无法准确表示字面值。


0
投票

根据 JLS 第 5.1.3 节,涉及从浮点类型到整型类型的缩小原始转换的转换将舍入为零:

浮点数到整型 T 的缩小转换需要两个步骤:

  1. 在第一步中,如果 T 是 long,则将浮点数转换为 long;如果 T 是 byte、short、char 或 int,则将浮点数转换为 int,如下所示:
  • 如果浮点数为 NaN(第 4.2.3 节),则第一步转换的结果为 int 或 long 0。
  • 否则,如果浮点数不是无穷大,则使用向零舍入策略(第 4.2.4 节)将浮点值舍入为整数值 V。

那么为什么

double a = 5.9999999999999999;
看起来四舍五入呢?
double
文字必须首先转换为
double
值。 JLS (3.10.2):

的浮点文字部分对此进行了介绍

包 java.lang 的 Float 类和 Double 类的方法 valueOf 描述了从浮点数的 Unicode 字符串表示形式到内部 IEEE 754 二进制浮点表示形式的正确输入转换的详细信息。

好的,我们去

valueOf
Double
:

[字符串值]被视为代表通常的“计算机科学计数法”中的精确十进制值或精确的十六进制值;然后,这个精确的数值在概念上被转换为“无限精确”的二进制值,然后通过 IEEE 754 浮点算术的常用“舍入到最近规则”舍入到类型“

double
”,其中包括保留零值。

(粗体强调我的)

小数点后有 16 位精度(包括

5

在内有 17 位),您正在突破

double
文字的精度极限。此时,
5.9999999999999999
比下一个较低的
6
值更接近
double
因此,显示 6 是因为您的浮点文字被四舍五入为 

6.0

before

double
,而
int
6.0 转换为
int
是 6你看到印刷的。
您拥有的其他值不会像 
6.0
文字那样一直四舍五入到

double

,因此转换为

int
会使其一直下降到 5。
    

© www.soinside.com 2019 - 2024. All rights reserved.