2.00-1.10(找零时刻分析)问题分析
今天老师问了这么一个问题:
public class program {
? ? ??
? ?//判断是否为奇数,是就返回true ??
public static boolean isOdd(int i){
? ? ? ?return i % 2==1; ? ? ??
? ?} ??
public static void main(String[] args){
? ? ? ?for(int i=-2;i<=2;i++){ ??
? ? ? ?System.out.println(isOdd(i)); ??
? ? ? ?} ??
? ? ? ?System.out.println("ssss"+(2-1.1)); ??
?? ? ? ?}
}
//请问,这段程序将会输出什么? ??
//请解释并优化该代码
?
开始以为也没什么,但结果还是不容你想到的。
结果是:false false true false?0.8999999999999999
为什么是这样的呢?
其实是double的精度问题。0.1,无法用二进制精确表示,如果N是负数,10的N次幂无法用二进制精确表示。
既然不精确 如:(System.out.println(3-2.99); 输出:0.009999999999999787),总之差一点点,可以理解。在JAVA中要取得精确的带小数的值,用BigDecimal ?即:System.out.println("优化后代码:"+new BigDecimal("2.00").subtract(new BigDecimal("1.10")));
?
==============================================================完美分界线
?
?
如下是转载?http://liuwei1981.iteye.com/blog/162891?的具体分析:
1.1这个数字不能被精确的表示为一个double,因此被表示为最接近它的double值。改程序从2中减去的就是这个值。遗憾的是,这个计算的结果并不是最接近0.9的double值。作为结果的double值的最短表示就是你看到的那个程序输出的可恶的数字。
并不是所有的小数都可以用二进制浮点数精确表示。如果使用的是JDK5或者更新的版本,那么您可能会受其诱惑,通过使用printf工具设置输出精度的方法改正程序:
"1.10")));??在需要精确答案的地方,要避免使用float和double;对于货币运算,要使用int,long,BigDecimal。