`
zhaowei_520
  • 浏览: 123362 次
  • 性别: 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 中的双精度浮点数(double)类型在进行运算时经常出现精度丢失的问题,这是由于双精度浮点数在计算机内部的存储方式所致。双精度浮点数使用 64 位二进制数来存储小数,然而这种存储方式会导致某些小数无法精确...

    test2_JavaDouble类型比较大小_java编程_

    标题"test2_JavaDouble类型比较大小_java编程_"提示我们关注的是Java中`Double`类型的比较操作。通常,我们可能会像处理整数那样直接使用`>`或`来比较两个`Double`值,例如`double a = 0.1; double b = 0.2; if (a +...

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

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

    java double:双精度浮点型.txt

    java double:双精度浮点型

    java-16位内存数据转化为double型

    从给定的代码片段来看,这实际上是一段C++代码,而非Java代码,旨在将一个十六进制字符串转换为双精度浮点数(double)。在深入解析这段代码之前,我们首先来了解一下Java中如何实现16位内存数据转化为double型。 #...

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

    解决java数值范围以及float与double精度丢失的问题 Java中的数值范围和浮点数精度问题是许多开发者经常遇到的问题。下面我们将详细探讨Java中的数值范围、float和double类型的精度问题,并且提供解决方案。 一、...

    double类型精度丢失;double转换到64位整数

    `double`是C++、Java等编程语言中的一种数据类型,它用于表示带有小数部分的数值,通常可以精确到15位十进制数。然而,由于浮点数的二进制表示方式,当进行某些计算或转换时,可能会出现精度丢失的问题。标题提到的...

    关于java的数值精度

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

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

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

    Java 精确计算-double-float-String

    总结来说,Java中处理浮点数的精度问题通常采用`BigDecimal`类,它可以提供精确的十进制运算。通过使用`BigDecimal`,开发者可以在需要精确计算的场景下避免浮点数运算带来的误差,确保代码的正确性和可靠性。

    计算机精度问题(Double)

    本文主要探讨的是“计算机精度问题”,特别是关于双精度浮点数(Double)的表示和计算中可能出现的问题。 双精度浮点数(Double)在计算机中通常按照IEEE 754标准进行存储和运算,它提供了大约15到16位的有效数字,...

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

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

    浅谈Java double 相乘的结果偏差小问题

    总结来说,处理Java中`double`类型相乘产生的结果偏差问题,可以采用调整运算顺序或者使用`BigDecimal`类进行高精度计算。在需要精确计算的场景下,推荐使用`BigDecimal`以确保结果的准确性。对于其他浮点数运算,...

    Java POI读取excel中数值精度损失问题解决

    Java POI 读取 Excel 中数值精度损失问题解决 Java POI 读取 Excel 中数值精度损失问题解决是指在使用 Java POI 读取 Excel 文件时,遇到数值精度损失的问题。这种问题的出现是因为 Excel 中的数值单元格在读取时,...

    Java小数精度、时间格式和类型转换.doc

    Java 小数精度、时间格式和类型转换 Java 中的类型转换是非常重要的,特别是在处理小数和日期时。在 Java 中,存在多种类型的转换,包括基本类型的转换、包装...小数精度问题和日期格式化是 Java 中非常重要的概念。

    java\String类型转换成整数double

    在Java编程语言中,数据类型的转换是一项常见的需求,尤其是在处理用户输入、文件读取或网络通信等场景下,经常需要将字符串(String)转换为数值类型如整数(int)或浮点数(double)。标题与描述“java String类型...

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

    在Java和MySQL中,处理小数时需要注意一系列与精度、数据类型选择以及运算准确性相关的问题。首先,让我们深入了解Java中小数的保存方式。 Java提供了两种基本的小数数据类型:float和double。float占用4个字节,...

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

    本文主要介绍了 Java 中的 BigDecimal 和 double 的示例及相关问题解析,展示了 BigDecimal 的常用方法和使用示例,展示了使用 BigDecimal 进行四则运算的示例,最后总结了 BigDecimal 的优点。

    DecimalFormat精度解决,商业运算精度问题

    特别是在Java这样的语言环境中,由于其内部采用二进制浮点数表示小数的方式,这导致了在处理一些特定数值(尤其是涉及到小数点后多位数的情况)时会出现精度损失的问题。这种情况下,传统的`float`或`double`类型...

Global site tag (gtag.js) - Google Analytics