英文:
How does the Below Java Type casting works?
问题
这个输出为什么会变成 '1'?
long number = 499_999_999_000_000_001L;
double converted = (double) number;
System.out.println(number - (long) converted);
英文:
How does the output turn out to be '1'?
long number = 499_999_999_000_000_001L;
double converted = (double) number;
System.out.println(number - (long) converted);
答案1
得分: 3
TLDR: 这是由于溢出位导致的
如果你查阅Java文档 Double.MAX_VALUE,你会注意到Java支持的最大双精度整数值是2^53 ≅ 10^16,但是在进行类型转换后,你的值变成了(4.99999999 * 10^17),超出了双精度范围,因此发生了溢出,被舍入。为了更好地理解,请运行以下代码:
public class Main
{
public static void main(String[] args) {
long longNumber = 499_999_999_000_000_001L;
double doubleNumber = (double) longNumber;
long longConverted = (long)doubleNumber;
System.out.println(longNumber+" "+doubleNumber+" "+longConverted);
}
}
其输出将会是:
499999999000000001 4.99999999E17 499999999000000000
英文:
TLDR: It's because of overflow bits
If you check java documentation Double.MAX_VALUE. You will observe that max double integer value supported by java is 2^53 ≅ 10^16 but your value becomes (4.99999999 * 10^17) after typecasting which is outside the range of double so because of overflow it is rounded. For better understanding run this code.
public class Main
{
public static void main(String[] args) {
long longNumber = 499_999_999_000_000_001L;
double doubleNumber = (double) longNumber;
long longConverted = (long)doubleNumber;
System.out.println(longNumber+" "+doubleNumber+" "+longConverted);
}
}
Its output will be:
499999999000000001 4.99999999E17 499999999000000000
答案2
得分: 2
以下是代码的翻译部分:
你只需进行一点“调试”。
尝试运行此代码...
long number = 499_999_999_000_000_001L;
System.out.println(number);
double converted = (double) number;
System.out.println(converted);
System.out.println((long) converted);
System.out.println(number - (long) converted);
这是它显示的内容...
499999999000000001
4.99999999E17
499999999000000000
1
你想知道为什么从double
转换回long
会丢失1
吗?
如果是的话,我建议你参考 Java 规范。
编辑
要更精确,参考 Widening Primitive Conversion 部分:
从... long 到 double 的扩展原始类型转换可能导致精度损失 - 即结果可能会丢失值的一些最不显著的位。在这种情况下,得到的浮点值将是整数值的正确舍入版本,使用 IEEE 754 最近舍入模式(§4.2.4)。
<details>
<summary>英文:</summary>
All you need to do is a little "debugging".
Try running this code...
```java
long number = 499_999_999_000_000_001L;
System.out.println(number);
double converted = (double) number;
System.out.println(converted);
System.out.println((long) converted);
System.out.println(number - (long) converted);
This is what it displays...
499999999000000001
4.99999999E17
499999999000000000
1
Do you want to know why the conversion back to long
from double
drops the 1
?
If you do then I refer you to the java specifications.
EDIT
To be precise, refer to section Widening Primitive Conversion
> A widening primitive conversion from ... long to double, may result in loss of precision - that is, the result may lose some of the least significant bits of the value. In this case, the resulting floating-point value will be a correctly rounded version of the integer value, using IEEE 754 round-to-nearest mode (§4.2.4).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论