有一道经典的面试题,求解答!

时间:2022-09-26 14:19:32
public class Test{
public static void main(String[] args){
System.out.println(2.0-1.1);
}
}


因为1.1不能用二进制精确表示,有截断误差,在存入时已经不是1.1了

但是在算4.0-1.1时,结果就是2.9,而4.0-3.1时结果又是0.8999999999999999999999999999999999了呢?

26 个解决方案

#1


既然是“误差” 
那自然就有随机性 与 不确定性吧?

#2


问题是什么?

怎么解决。(java.math.BigDecimal)

还是这种现象的原因是什么。(精度问题,比如33.0/0.25也会出现这种问题)

#3


System.out.println(2.0f-1.1f);

#4


我感觉是jdk5.0后的自动装箱的问题! 
   可能小于1是flout 大于1是double  自动装箱的类型是jdk定的!

#5


字符类型的问题

#6


引用 2 楼 sxzlc 的回复:
问题是什么?

怎么解决。(java.math.BigDecimal)

还是这种现象的原因是什么。(精度问题,比如33.0/0.25也会出现这种问题)

这个类我用过了,感觉还是很好解决问题的

#7


问下LZ是不是正在看Java解惑这本书?  该书上有这个例子

#8


下面是一个试图解决上述问题的程序,它会打印出什么呢? 

public class Change{
public static void main(String args[]){
System.out.println(2.00 - 1.10);
}
}

你可能会很天真地期望该程序能够打印出0.90,但是它如何才能知道你想要打印小数点后两位小数呢?
如果你对在Double.toString文档中所设定的将double类型的值转换为字符串的规则有所了解,你就会知道该程序打印出来的小数,是足以将double类型的值与最靠近它的临近值区分出来的最短的小数,它在小数点之前和之后都至少有一位。因此,看起来,该程序应该打印0.9是合理的。 

这么分析可能显得很合理,但是并不正确。如果你运行该程序,你就会发现它打印的是0.8999999999999999。

问题在于1.1这个数字不能被精确表示成为一个double,因此它被表示成为最接近它的double值。该程序从2中减去的就是这个值。遗憾的是,这个计算的结果并不是最接近0.9的double值。表示结果的double值的最短表示就是你所看到的打印出来的那个可恶的数字。

更一般地说,问题在于并不是所有的小数都可以用二进制浮点数来精确表示的。 

#9


学习咯

#10


java.math.BigDecimal不太清楚 好像可以提升精度。。

我想问为什么4.0-1.1结果就是2.9?怎么这么精确?

#11


 长见识了

#12


这个是正常的,这与它的底层数据存储有关,一般这咱运算时要对精度进行最小误差的处理。

#13


0.9

#14


问题在于1.1这个数字不能被精确表示成为一个double,因此它被表示成为最接近它的double值
-------------------------
为啥

#15


计算机的小数存储方式决定,IEE754

http://www.cnblogs.com/bossin/archive/2007/04/08/704567.html

#16


看JAVA解惑

#17


引用 14 楼 jornye 的回复:
问题在于1.1这个数字不能被精确表示成为一个double,因此它被表示成为最接近它的double值
-------------------------
为啥

因为把1.1转化为二进制你会发现会一直循环下去

#18


***********************************************************************************************
***********************************************************************************************



我想问为什么4.0-1.1结果就是2.9?4.0-2.1=1.9,怎么这么精确?而当结果应该是0.9时,它就打印0.899999999999999999999999999999999



************************************************************************************************
************************************************************************************************

#19


见世一回!!!!!

#20


不要吹毛求疵了,这种问题不理解也可以过的,呵呵呵

#21


每天回帖即可获得10分可用分!

#22


受教了!

#23


是1.5没有这类问题吗

#24


学习一下 呵呵

#25


还是不理解。

#26


en 回复内容太短了! 

#1


既然是“误差” 
那自然就有随机性 与 不确定性吧?

#2


问题是什么?

怎么解决。(java.math.BigDecimal)

还是这种现象的原因是什么。(精度问题,比如33.0/0.25也会出现这种问题)

#3


System.out.println(2.0f-1.1f);

#4


我感觉是jdk5.0后的自动装箱的问题! 
   可能小于1是flout 大于1是double  自动装箱的类型是jdk定的!

#5


字符类型的问题

#6


引用 2 楼 sxzlc 的回复:
问题是什么?

怎么解决。(java.math.BigDecimal)

还是这种现象的原因是什么。(精度问题,比如33.0/0.25也会出现这种问题)

这个类我用过了,感觉还是很好解决问题的

#7


问下LZ是不是正在看Java解惑这本书?  该书上有这个例子

#8


下面是一个试图解决上述问题的程序,它会打印出什么呢? 

public class Change{
public static void main(String args[]){
System.out.println(2.00 - 1.10);
}
}

你可能会很天真地期望该程序能够打印出0.90,但是它如何才能知道你想要打印小数点后两位小数呢?
如果你对在Double.toString文档中所设定的将double类型的值转换为字符串的规则有所了解,你就会知道该程序打印出来的小数,是足以将double类型的值与最靠近它的临近值区分出来的最短的小数,它在小数点之前和之后都至少有一位。因此,看起来,该程序应该打印0.9是合理的。 

这么分析可能显得很合理,但是并不正确。如果你运行该程序,你就会发现它打印的是0.8999999999999999。

问题在于1.1这个数字不能被精确表示成为一个double,因此它被表示成为最接近它的double值。该程序从2中减去的就是这个值。遗憾的是,这个计算的结果并不是最接近0.9的double值。表示结果的double值的最短表示就是你所看到的打印出来的那个可恶的数字。

更一般地说,问题在于并不是所有的小数都可以用二进制浮点数来精确表示的。 

#9


学习咯

#10


java.math.BigDecimal不太清楚 好像可以提升精度。。

我想问为什么4.0-1.1结果就是2.9?怎么这么精确?

#11


 长见识了

#12


这个是正常的,这与它的底层数据存储有关,一般这咱运算时要对精度进行最小误差的处理。

#13


0.9

#14


问题在于1.1这个数字不能被精确表示成为一个double,因此它被表示成为最接近它的double值
-------------------------
为啥

#15


计算机的小数存储方式决定,IEE754

http://www.cnblogs.com/bossin/archive/2007/04/08/704567.html

#16


看JAVA解惑

#17


引用 14 楼 jornye 的回复:
问题在于1.1这个数字不能被精确表示成为一个double,因此它被表示成为最接近它的double值
-------------------------
为啥

因为把1.1转化为二进制你会发现会一直循环下去

#18


***********************************************************************************************
***********************************************************************************************



我想问为什么4.0-1.1结果就是2.9?4.0-2.1=1.9,怎么这么精确?而当结果应该是0.9时,它就打印0.899999999999999999999999999999999



************************************************************************************************
************************************************************************************************

#19


见世一回!!!!!

#20


不要吹毛求疵了,这种问题不理解也可以过的,呵呵呵

#21


每天回帖即可获得10分可用分!

#22


受教了!

#23


是1.5没有这类问题吗

#24


学习一下 呵呵

#25


还是不理解。

#26


en 回复内容太短了!