A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 丁朋 中级黑马   /  2012-7-16 10:33  /  1761 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

今天在做练习时遇到了一个很奇怪的事,
class  lianxi
{
public static void main(String[] args)
{
  System.out.println(9.8-8.8);//打印正常
  System.out.println(9.9-8.8);//打印不正常
}
}

打印结果为什么失真
1.0
1.0999999999999996

评分

参与人数 1技术分 +1 收起 理由
韦念欣 + 1 赞一个!

查看全部评分

5 个回复

倒序浏览
学过计算机组成原理的话,你应该就会知道,这个是浮点数的问题
回复 使用道具 举报
且看看float数据类型的存储结构:
float占用4个字节,也就是32为二进制码,分别是:
符号位:1位(31),表示float的正负,0为正,1为负
幂指数:8位(23-30),表示2进制权的幂次
有效位:23位(0-22),表示有效数字

因为浮点数在系统中使用的是二进制的科学计数法,浮点运算有误差。

评分

参与人数 1技术分 +1 收起 理由
蒋映辉 + 1

查看全部评分

回复 使用道具 举报
在java中,使用double进行运算,有时会出现精度丢失的问题,值会有那么0.00000***1偏差的偏差,导致匹配校验常常出现问题
解决方案如下:
  /**  
     * 对double数据进行取精度.  
     * @param value  double数据.  
     * @param scale  精度位数(保留的小数位数).  
     * @param roundingMode  精度取值方式.  
     * @return 精度计算后的数据.  
     */  
    public static double round(double value, int scale,
             int roundingMode) {   
        BigDecimal bd = new BigDecimal(value);   
        bd = bd.setScale(scale, roundingMode);   
        double d = bd.doubleValue();   
        bd = null;   
        return d;   
    }   


     /**
     * double 相加
     * @param d1
     * @param d2
     * @return
     */
    public double sum(double d1,double d2){
        BigDecimal bd1 = new BigDecimal(Double.toString(d1));
        BigDecimal bd2 = new BigDecimal(Double.toString(d2));
        return bd1.add(bd2).doubleValue();
    }


    /**
     * double 相减
     * @param d1
     * @param d2
     * @return
     */
    public double sub(double d1,double d2){
        BigDecimal bd1 = new BigDecimal(Double.toString(d1));
        BigDecimal bd2 = new BigDecimal(Double.toString(d2));
        return bd1.subtract(bd2).doubleValue();
    }

    /**
     * double 乘法
     * @param d1
     * @param d2
     * @return
     */
    public double mul(double d1,double d2){
        BigDecimal bd1 = new BigDecimal(Double.toString(d1));
        BigDecimal bd2 = new BigDecimal(Double.toString(d2));
        return bd1.multiply(bd2).doubleValue();
    }


    /**
     * double 除法
     * @param d1
     * @param d2
     * @param scale 四舍五入 小数点位数
     * @return
     */
    public double div(double d1,double d2,int scale){
        //  当然在此之前,你要判断分母是否为0,   
        //  为0你可以根据实际需求做相应的处理

        BigDecimal bd1 = new BigDecimal(Double.toString(d1));
        BigDecimal bd2 = new BigDecimal(Double.toString(d2));
        return bd1.divide
               (bd2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
    }


这样,计算double类型的数据计算问题就可以处理了。

点评

这个是百度的答案,如果同学引用了百度的资料,请在回帖时注明。  发表于 2012-7-16 16:34
回复 使用道具 举报
楼上的说得对,计算机计算整型的精度比较高,编译器编译的时候浮点型数据可能会丢失,8.8可能变成8.7999999
java的API的java.math包里提供了一个BigDecimal类,该类里有个方法subtract方法可以解决此问题,具体的你可以查阅API文档
回复 使用道具 举报
这跟浮点数数精确度有关
2次运算结果不同 是因为浮点数精确度损失
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马