概述
先来看一下以下几行代码运行的结果:
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解决精度问题所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复