提问人:Evloution78 提问时间:10/25/2023 更新时间:10/25/2023 访问量:51
Java Explicit Cast 从 Double 到 Int 的舍入规则是什么
What are the rounding rules of Java Explicit Cast from Double to Int
问:
今天在演示 Java 显式类型转换时遇到了一个奇怪的怪癖,我想知道为什么会发生这种情况。
如果我将双精度转换为整数,并且我的数字是 .9 到 16 精度,它将四舍五入。(请参阅代码中的注释)如果我使它达到 15 精度,它会向下舍入。
同样,如果我把我的数字 .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,但似乎并非如此。
有什么想法吗?
答:
这与强制转换为 无关。int
如果打印 的值:a
double a = 5.9999999999999999;
System.out.println(a);
它打印 .6.0
这是因为 double 的精度有限,不能精确表示文本值。
根据 JLS 第 5.1.3 节,涉及从浮点类型到整数类型的缩小基元转换的转换将四舍五入为零:
将浮点数缩小为整型 T 的转换需要两个步骤:
- 在第一步中,如果 T 为 long,则将浮点数转换为 long,如果 T 为 byte、short、char 或 int,则转换为 int,如下所示:
- 如果浮点数为 NaN (§4.2.3),则转换第一步的结果为 int 或 long 0。
- 否则,如果浮点数不是无穷大,则使用向零舍入策略 (§4.2.4) 将浮点值舍入为整数值 V。
那么为什么看似四舍五入呢?必须先将文本转换为值。JLS (3.10.2) 的 Floating-Point Literals 部分对此进行了介绍:double a = 5.9999999999999999;
double
double
对于包 java.lang 的 Float 类和 Double 类的方法 valueOf 描述了从浮点数的 Unicode 字符串表示形式到内部 IEEE 754 二进制浮点表示形式的正确输入转换的详细信息。
好的,让我们转到 Value Of
for Double
:
[字符串值]被视为在通常的“计算机化科学记数法”中表示精确的十进制值或精确的十六进制值;然后,这个精确的数值在概念上被转换为一个“无限精确”的二进制值,然后按照 IEEE 754 浮点运算的通常舍入到最接近规则四舍五入为类型,其中包括保留零值的符号。
double
(粗体强调我的)
在超出小数点的 16 位精度(有 17 个包含点)时,您正在突破文字的精度极限。此时,比下一个较低的值更接近。5
double
5.9999999999999999
6
double
因此,之所以显示 6,是因为浮点文字在转换为 之前被舍入为 a,而转换为 an 是您看到打印的 6。6.0
double
int
6.0
int
您拥有的其他值不会一直四舍五入为文字,因此强制转换将其一直缩小到 5。6.0
double
int
评论
cast