`
zhaowei_520
  • 浏览: 122849 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Java Double 精度问题总结

    博客分类:
  • Java
阅读更多
    使用Java,double 进行运算时,经常出现精度丢失的问题,总是在一个正确的结果左右偏0.0000**1。 特别在实际项目中,通过一个公式校验该值是否大于0,如果大于0我们会做一件事情,小于0我们又处理其他事情。 这样的情况通过double计算出来的结果去和0比较大小,尤其是有小数点的时候,经常会因为精度丢失而导致程序处理流程出错。
     所以一般对double类型进行运算时,做好对结果进行处理,然后拿这个值去做其他事情。

     目前总结如下:

     /** 
     * 对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类型的数据计算问题就可以处理了。
另外补充一下 JavaScript 四舍五入的方法:
小数点问题
Math.round(totalAmount*100)/100 (保留 2 位)

function formatFloat(src, pos)
{
  return Math.round(src*Math.pow(10, pos))/Math.pow(10, pos);
}


希望以上对大家有所帮助,如果说错了,还希望大家给点指正!


分享到:
评论
7 楼 mingyang2013 2013-01-28  
SereinChan 写道
楼主好厉害,收益了!
由于本人水平有点弱,所以想请教一下下面代码的含义:
BigDecimal bd1 = new BigDecimal(Double.toString(d1));

大概知道这语句的意思是调用
BigDecimal的BigDecimal(String val)构造方法生成BigDecimal对象,但有点不是很明白Double.toString(d1)的意思,为什么可以直接写Double来调用toString方法,这个Double不需要new一下吗?


静态方法不需要new啦!
6 楼 小乌鸦 2012-06-12  
SereinChan 写道
楼主好厉害,收益了!
由于本人水平有点弱,所以想请教一下下面代码的含义:
BigDecimal bd1 = new BigDecimal(Double.toString(d1));

大概知道这语句的意思是调用
BigDecimal的BigDecimal(String val)构造方法生成BigDecimal对象,但有点不是很明白Double.toString(d1)的意思,为什么可以直接写Double来调用toString方法,这个Double不需要new一下吗?


********
这是一个单例。。。
5 楼 SereinChan 2012-03-13  
楼主好厉害,收益了!
由于本人水平有点弱,所以想请教一下下面代码的含义:
BigDecimal bd1 = new BigDecimal(Double.toString(d1));

大概知道这语句的意思是调用
BigDecimal的BigDecimal(String val)构造方法生成BigDecimal对象,但有点不是很明白Double.toString(d1)的意思,为什么可以直接写Double来调用toString方法,这个Double不需要new一下吗?
4 楼 all_wmh 2011-09-14  
System.out.println(new BigDecimal(Double.toString(712312312327.42325)));
System.out.println(new BigDecimal(Double.toString(712312312327.42326)));
System.out.println(new BigDecimal(Double.toString(712312312327.42327)));
System.out.println(new BigDecimal(Double.toString(712312312327.42328)));

楼主你可以试试这个就知道toString还是要缺失精度的!
3 楼 spiritfrog 2010-02-24  
zhaowei_520 写道
gary_zg 写道
楼主这种做法有问题,只要使用flaot或double,就会出现精度丢失
方法里的参数都是double,在new BigDecimal前,double值就已经出现精度丢失了



BigDecimal 有两个构造:
   1. BigDecimal(double val)
   2. BigDecimal(String val)

但如果使用 double 构造,API中已经说明,这个构造器的结果可能会有不可预知的结果。如: System.out.println(new BigDecimal(1.2));
结果是:1.1999999999999999555910790149937383830547332763671875
而并非我们认为的 1.2;

所以再构造BigDecimal的时候,原则上我们使用 BigDecimal(String val)构造,这样就不会出问题,而我提供的方法中(当然也是借鉴了网上的资料),都是把Double类型转换成String类型去构造的,所以不会出现问题。


言之有理。
2 楼 zhaowei_520 2009-10-16  
gary_zg 写道
楼主这种做法有问题,只要使用flaot或double,就会出现精度丢失
方法里的参数都是double,在new BigDecimal前,double值就已经出现精度丢失了



BigDecimal 有两个构造:
   1. BigDecimal(double val)
   2. BigDecimal(String val)

但如果使用 double 构造,API中已经说明,这个构造器的结果可能会有不可预知的结果。如: System.out.println(new BigDecimal(1.2));
结果是:1.1999999999999999555910790149937383830547332763671875
而并非我们认为的 1.2;

所以再构造BigDecimal的时候,原则上我们使用 BigDecimal(String val)构造,这样就不会出问题,而我提供的方法中(当然也是借鉴了网上的资料),都是把Double类型转换成String类型去构造的,所以不会出现问题。
1 楼 gary_zg 2009-09-30  
楼主这种做法有问题,只要使用flaot或double,就会出现精度丢失
方法里的参数都是double,在new BigDecimal前,double值就已经出现精度丢失了

相关推荐

    java_double_精度

    解释并解决Java开发中doubule精度问题。

    Java 基本类型double精度计算工具

    该工具用户进行double类型的精度计算,包含加法、减法、乘法、除法、精确点计算、小数点计算,限制小数点后数字

    java double:双精度浮点型.txt

    java double:双精度浮点型

    关于java的数值精度

    java程序中数值的精度问题,float、double容易产生精度数值问题,不适合精度计算,而bigdecimal正好解决这一问题

    Java中double类型下出现精度计算错误情况下出力方法

    Java中的简单浮点数类型float和double不能够进行运算,因为大多数情况下是正常的,但是偶尔会出现如上所示的问题。这个问题其实不是JAVA的bug,因为计算机本身是二进制的,而浮点数实际上只是个近似值,所以从二进制...

    Java 加减乘除工具类(解决精度损失问题)

    //精度为2,舍入模式为大于0.5进1,否则舍弃 BigDecimal b1 = new BigDecimal(Double.toString(value1.doubleValue())); BigDecimal b2 = new BigDecimal(Double.toString(value2.doubleValue())); return b1....

    解决java数值范围以及float与double精度丢失的问题

    下面小编就为大家带来一篇解决java数值范围以及float与double精度丢失的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    Java BigDecimal和double示例及相关问题解析

    主要介绍了Java BigDecimal和double示例及相关问题解析,简单介绍了BigDecimal类的相关内容,分享了两则相关实例,对问题进行了分析,具有一定参考价值,需要的朋友可以了解下。

    基于Java实现的图像识别

    ImageComparerUI——基于Java语言实现的相似图像识别,基于直方图比较算法。 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font...

    java数学计算工具类 double精确的加法算法 double精确的减法算法

    java数学计算工具类 double精确的加法算法 double精确的减法算法 精确的乘法算法 对精确的除法运算,当发生除不尽的 保留小数、数值精度

    Java与MySQL中小数保存问题解析.pptx.pptx

    在Java和MySQL中,小数的精度可能会受到限制,如float类型的小数只能精确到6-7位,double类型也只能精确到15-16位。 浮点数运算问题 在进行浮点数运算时,可能会出现精度丢失的问题,例如0.1+0.2的结果并不等于0.3...

    J2ME 高精度 反正切函数等 atan(double angle) Pol(double x, double y) Rec(double r, double θ)

    写J2ME程序时,如果想使用反正切函数是必须自己写算法的.因为J2ME的Math类里没有的反正功函数.修改里面的n值可更改精度和性能.

    Java-关于基本数据类型中浮点数计算产生的精度问题

    在基本数据类型中,float和double都表示浮点型数据,而计算机计算采取的是对二进制的计算,所以会存在一定程度上的精度丢失问题。 BigDecimal类是一个大小数操作类,可以用来对超过16位有效位的数据进行精确的运算,...

    java中double转化为BigDecimal精度缺失的实例

    下面小编就为大家带来一篇java中double转化为BigDecimal精度缺失的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    单双精度转十六进制.zip

    单双精度浮点数与十六进制双向转换工具,单双精度浮点数与十六进制双向转换工具,单双精度浮点数与十六进制双向转换工具

    详谈javascript精度问题与调整

    在JS中数值类型就只有number类型,没有int,float,double之分,number类型实际上存储的就是IEEE754标准的浮点数,计算规则也是。 在表达式计算前,先要按照标准将两个数转成浮点数。 IEEE 754规定: 1.32位的浮点数...

    精确计算工具类

    public static double div(double v1, double v2, int scale) { if (scale ) { throw new IllegalArgumentException( "The scale must be a positive integer or zero"); } BigDecimal b1 = new BigDecimal...

    Java Number & Math 类.pdf

    为了解决这个问题,Java 语言为每一个内置数据类型提供了对应的包装类。 所有的包装类都是抽象类 Number 的子类。 包装类 基本数据类型 Boolean boolean Byte byte Short short Integer int Long long Character ...

    java个人所得税计算程序

    java 个人所得税计算程序 1.1. 类名:IncomeTax 1.1.1. 类描述 程序入口类,完成菜单显示、输入、回显、计算个人所得税、修改相关计算参数的总调度。 1.1.2. 类成员变量 1) private static TaxTable tt //税率表 ...

Global site tag (gtag.js) - Google Analytics