下面的Java类型转换是如何工作的?

下面的Java类型转换是如何工作的?,java,casting,Java,Casting,输出结果如何为“1” long number = 499_999_999_000_000_001L; double converted = (double) number; System.out.println(number - (long) converted); 您所需要做的只是一点调试。 尝试运行此代码 长号码=499_999_999_000_000_001L; System.out.PrintLNumber; 双重转换=双重数字; System.out.println转换; S

输出结果如何为“1”

long number = 499_999_999_000_000_001L;    
double converted = (double) number;
System.out.println(number - (long) converted);

您所需要做的只是一点调试。 尝试运行此代码

长号码=499_999_999_000_000_001L; System.out.PrintLNumber; 双重转换=双重数字; System.out.println转换; System.out.printlnlong已转换; System.out.printlnnumber-长转换; 这就是它所显示的

499999999000000001
4.99999999E17
499999999000000000
1
你想知道为什么转换回长从双下降1? 如果你这样做了,我建议你去看医生

编辑 准确地说,请参阅第节

从…扩展的原语转换。。。长到两倍,可能会导致精度损失-也就是说,结果可能会丢失一些值的最低有效位。在这种情况下,产生的浮点值将是整数值的正确四舍五入版本,使用IEEE 754四舍五入至最近模式§4.2.4


您所需要做的只是一点调试。 尝试运行此代码

长号码=499_999_999_000_000_001L; System.out.PrintLNumber; 双重转换=双重数字; System.out.println转换; System.out.printlnlong已转换; System.out.printlnnumber-长转换; 这就是它所显示的

499999999000000001
4.99999999E17
499999999000000000
1
你想知道为什么转换回长从双下降1? 如果你这样做了,我建议你去看医生

编辑 准确地说,请参阅第节

从…扩展的原语转换。。。长到两倍,可能会导致精度损失-也就是说,结果可能会丢失一些值的最低有效位。在这种情况下,产生的浮点值将是整数值的正确四舍五入版本,使用IEEE 754四舍五入至最近模式§4.2.4

TLDR:这是因为溢出位

如果您查看java文档。您将看到java支持的最大双整数值是2^53≅ 10^16但您的值在类型转换后变为4.9999999*10^17,超出了double的范围,因此由于溢出,它被四舍五入。为了更好地理解,请运行此代码

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:这是因为溢出位

如果您查看java文档。您将看到java支持的最大双整数值是2^53≅ 10^16但您的值在类型转换后变为4.9999999*10^17,超出了double的范围,因此由于溢出,它被四舍五入。为了更好地理解,请运行此代码

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

堆栈溢出在每篇文章只有一个问题时效果最好。你对哪些问题感兴趣?请给它更多的上下文-你希望代码不会编译吗?还是你在问执行时间?目前这个问题还不清楚。我能理解第二个问题,但你所说的打字是什么意思?正如语言规范中指定的那样,double-to和from-long都是有效的强制转换。这里没有什么要解释的…@Sweeper我不明白输出是如何返回1的?你希望它返回零,对吗?每个帖子只有一个问题时堆栈溢出效果最好。你对哪些问题感兴趣?请给它更多的上下文-你希望代码不会编译吗?还是你在问执行时间?目前这个问题还不清楚。我能理解第二个问题,但你所说的打字是什么意思?正如语言规范中指定的那样,double-to和from-long都是有效的强制转换。这里没有什么要解释的…@Sweeper我不明白输出如何返回1?你希望它返回零,对吗?谢谢你的回答,但我仍然有一个疑问,因为long和double都是8字节,那么为什么long转换结果是4999999900000000而不是49999900000001?所有编程语言对long和double的解释都不同,因为long是整数值,double不是。例如,你会发现许多在线文章解释了这种差异。您还可以参考Java虚拟机JVM规范,我在回答中提供了一个链接。感谢您的回答,但我仍然有疑问,因为long和double都是8字节,那么为什么long转换后的结果是4999999900000000而不是49999999000001?所有编程语言都解释long和double的位不同的是,因为long是整数值,而double不是。例如,你会发现许多在线文章解释了这种差异。您还可以参考Java虚拟机JVM规范,我在回答中提供了一个链接。