我是靠谱客的博主 机灵招牌,最近开发中收集的这篇文章主要介绍使用BigDecimal解决精度问题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

先来看一下以下几行代码运行的结果:

public class Test{
    public static void main(String[] arg){
        int a=3;
        double b=3.3;
        double c=a*b;
        System.out.println(c);
    }
}

运行结果:

9.899999999999999

为什么不是输出9.9呢?是由于java的精度损失造成的。详细原因见http://www.cnblogs.com/backwords/p/9826773.html

所以需要用BigDecimal类来处理精度缺失问题。

BigDemical是Number类的子类。要使用BigDemical做运算首要先将其他类型的数字转换成BigDemical类,那么就要用到BigDemical的构造方法。BigDemical提供很多构造方法。例如:

public BigDecimal(int val)

public BigDecimal(long val)

public BigDecimal(double val)

public BigDecimal(String val)

注意,我们看到,没有Float类型的参数。但是,我们知道,Float类型的变量可以自动转型为Double,那么可否用public BigDecimal(double val)这个构造方法去接收Float类型的参数呢?虽然可以,但是这样会导致精度的损失。因为Float只有32位,Double有64位。不信的话看代码:

float q=3.33f;
double w=q;
System.out.println(w);

输出:

3.3299999237060547

那么,如果是一个double类型的变量就可以用public BigDecimal(double val)了么?还是会导致精度的损失。因为3.33无法准确的用二进制来表示。所以建议把double类型或者float类型的变量转化成String类型,然后用public BigDecimal(String val)。可以直接用

public static BigDecimal valueOf(double val)

合成这两步。但是把double类型的变量或者float类型的变量转化为String这一步骤又可能出现精度损失。因为Double.toString()会使用一定的精度来四舍五入double。Double.toString(0.1000000000000000055511151231257827021181583404541015625)输出的事实上是"0.1"。所以,如果你希望BigDecimal能够精确地表示你希望的数值,那么一定要使用字符串来表示小数,并传递给BigDecimal的构造函数。如果你使用Double.toString来把double转化字符串,然后调用BigDecimal(String),这个也是不靠谱的,它不一定按你的想法工作。参考博客https://www.cnblogs.com/wangzhongqiu/p/9542145.html

完成构造以后,就可以调用BigDecimal的方法进行运算:

public BigDecimal add(BigDecimal augend)
public BigDecimal subtract(BigDecimal subtrahend)
public BigDecimal multiply(BigDecimal multiplicand)
public BigDecimal divide(BigDecimal divisor)

示例:

import java.math.BigDecimal;

public class Test{

    public static void main(String[] arg){
        int a=3;
        double b=0.3;
        System.out.println(BigDecimal.valueOf(b).add(new BigDecimal(a)));
        System.out.println(BigDecimal.valueOf(b).subtract(new BigDecimal(a)));
        System.out.println(BigDecimal.valueOf(b).multiply(new BigDecimal(a)));
        System.out.println(BigDecimal.valueOf(b).divide(new BigDecimal(a)));
        System.out.println("******************");
        System.out.println(b+a);
        System.out.println(b-a);
        System.out.println(b*a);
        System.out.println(b/a);
    }
}

输出:

3.3
-2.7
0.9
0.1
******************
3.3
-2.7
0.8999999999999999
0.09999999999999999

注意,使用divede()方法时,若结果是无限小数,会抛出ArithmeticException异常。这时可以使用以下两种方法代替:

public BigDecimal divide(BigDecimal divisor,RoundingMode roundingMode)
public BigDecimal divide(BigDecimal divisor,int scale,RoundingMode roundingMode)

其中 scale表示保留几位小数,roundingMode表示舍入的模式。详细模式介绍可参考API。

BigDecimal还有其他常用方法:

public BigDecimal setScale(int newScale)//设置四舍五入到小数点几位
public double doubleValue()//将BigDecimal转换为double类型
public int intValue()//将BigDecimal转换为int类型

 

最后

以上就是机灵招牌为你收集整理的使用BigDecimal解决精度问题的全部内容,希望文章能够帮你解决使用BigDecimal解决精度问题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部