以下是翻译好的内容: 如何进行Java中的类型转换?

huangapple go评论69阅读模式
英文:

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 &quot;debugging&quot;.  
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).

huangapple
  • 本文由 发表于 2020年9月16日 18:04:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/63917689.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定