bigDecimal使⽤⽅法详解(转载)
BigDecimal 由任意精度的整数⾮标度值和 32 位的整数标度 (scale) 组成。如果为零或正数,则标度是⼩数点后的位数。如果为负数,则将该数的⾮标度值乘以 10 的负 scale 次幂。因此,BigDecimal 表⽰的数值是 (unscaledValue × 10-scale)。
可以处理任意长度的浮点数运算。
BigDecimal add(BigDecimal val) //BigDecimal 加法
BigDecimal subtract (BigDecimal val) //BigDecimal 减法
BigDecimal multiply (BigDecimal val) //BigDecimal 乘法
BigDecimal divide (BigDecimal val,RoundingMode mode) 除法
具体使⽤计算:
加: a.add(b);
减: a.subtract(b);
乘: a.multiply(b);
除: a.divide(b,2);//2为精度取值
除法细解:
//注意以下相除会抛出异常,原因: 通过BigDecimal的divide⽅法进⾏除法时当不整除,出现⽆限循环⼩数时,就会抛异常
//BigDecimal divideBg = a.divide(b);
//解决⽅法是:设置精确度;就是给divide设置精确的⼩数点
divide(xxxxx,2, BigDecimal.ROUND_HALF_EVEN)
//其中的第⼆个参数表⽰的是:保留⼩数点之后多少位
BigDecimal不整除抛出的异常,请设置精确度!
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
at java.math.BigDecimal.divide(BigDecimal.java:1278)
at main.Main.main(Main.java:41)
下⾯我们来看看除法的详细说明:
divide(BigDecimal divisor, int scale, introundingMode)
BigDecimal的setScale⽅法
BigDecimal.setScale()
⽅法⽤于格式化⼩数点
表⽰保留⼀位⼩数,默认⽤四舍五⼊⽅式
setScale(1)
直接删除多余的⼩数位,如2.35会变成2.3 setScale(1,BigDecimal.ROUND_DOWN)
进位处理,2.35变成2.4 setScale(1,BigDecimal.ROUND_UP)
四舍五⼊,2.35变成2.4 setScale(1,BigDecimal.ROUND_HALF_UP)
四舍五⼊,2.35变成2.3,如果是5则向下舍setScaler(1,BigDecimal.ROUND_HALF_DOWN)
注意点⼀
scale指的是你⼩数点后的位数。
scale()就是BigDecimal类中的⽅法。如
BigDecimal b = new BigDecimal("123.456");
b.scale()返回的就是3
注意点⼆roundingMode是⼩数的保留模式。它们都是BigDecimal中的常量字段,
有很多种,如
BigDecimal.ROUND_HALF_UP表⽰的就是4舍5⼊
注意点三
divide(BigDecimal divisor, int scale, introundingMode)的意思是说:
我⽤⼀个BigDecimal对象除以divisor后的结果,并且要求这个结果保留有scale个⼩数位,roundingMode表⽰的就是保留模式是什么,是四舍五⼊啊还是其它的
BigDecimal aa = new BigDecimal(135.95 );
BigDecimal bb=new BigDecimal("100" );
BigDecimal result=aa.multiply(bb); //做加法
3.java中 BigDecimal类型的可以转换到double类型:
⽤变量.doubleValue();函数即可将 BigDecimal 类型数据转化为 double类型!
4.java BigDecimal⽐较⼤⼩
可以通过BigDecimal的compareTo⽅法来进⾏⽐较。
返回的结果是int类型,-1表⽰⼩于,0是等于,1是⼤于。
看下⾯这个例⼦:
BigDecimal a = new BigDecimal("1.00");
BigDecmial b = new BigDecimal(1);
想⽐较⼀下a和b的⼤⼩,⼀般都会⽤equals
System.out.println(a.equals(b));
但是输出结果是:falsebigdecimal除法保留小数
原因是:BigDecimal⽐较时,不仅⽐较值,⽽且还⽐较精度?
if(apareTo(b)==0) 结果是true
⽐较⼤⼩可以⽤ apareTo(b)
返回值 -1 ⼩于 0 等于 1 ⼤于
5.BigDecimal取其中最⼤、最⼩值、绝对值、相反数:
a.max (b) //⽐较取最⼤值
a.min(b) //⽐较取最⼩值
a.abs()//取最绝对值
a.negate()//取相反数
6.下⾯是注意:
BigDecimal枚举常量⽤法摘要:
CEILING
向正⽆限⼤⽅向舍⼊的舍⼊模式。
DOWN
向零⽅向舍⼊的舍⼊模式。
FLOOR
向负⽆限⼤⽅向舍⼊的舍⼊模式。
HALF_DOWN
向最接近数字⽅向舍⼊的舍⼊模式,如果与两个相邻数字的距离相等,则向下舍⼊。
HALF_EVEN
向最接近数字⽅向舍⼊的舍⼊模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍⼊。
HALF_UP
向最接近数字⽅向舍⼊的舍⼊模式,如果与两个相邻数字的距离相等,则向上舍⼊。
UNNECESSARY
⽤于断⾔请求的操作具有精确结果的舍⼊模式,因此不需要舍⼊。
UP
远离零⽅向舍⼊的舍⼊模式。
7.关于BigDecimal格式化
public String formatValue(Object value){
String content = null;
if (value == null) {
content = "";
} else {
if(value instanceof BigDecimal){
//conver to fortmat String
NumberFormat nf = Instance();
nf.setMinimumFractionDigits(2);
nf.setMaximumFractionDigits(2);
content = nf.format(value);
}else{
content = String.valueOf(value);
}
}
return content;
}
使⽤这样⼀个⽅法可以达到格式化的效果,其中value instanceof BigDecimal,表⽰的是字符类型是BigDecimal类型的时候执⾏,这⾥的NumberFormat就表⽰字符类型,下⾯的两句代码就表⽰⼩数点后⾯的精确位数。
这⾥还要提到NumberFormat的其他两个类型:
getCurrencyInstance():返回当前默认环境的货币格式
CurrencyInstance():返回指定语⾔环境的数字格式,⼀般是百分⽐格式
8.在《Effective Java》这本书中也提到这个原则,float和double只能⽤来做科学计算或者是⼯程计算,在商业计算中我们要⽤
java.math.BigDecimal。
我们如果需要精确计算,⾮要⽤String来够造BigDecimal不可!
下⾯的这个⼯具类是是转载别⼈的,可以通过个⼯具类实现⼩数的精确计算。
1import java.math.BigDecimal;
2/** *//**
3* 由于Java的简单类型不能够精确的对浮点数进⾏运算,这个⼯具类提供精
4* 确的浮点数运算,包括加减乘除和四舍五⼊。
5*/
6public class Arith{
7 //默认除法运算精度
8 private static final int DEF_DIV_SCALE = 10;
9 //这个类不能实例化
10 private Arith(){
11 }
12
13 /** *//**
14 * 提供精确的加法运算。
15 * @param v1 被加数
16 * @param v2 加数
17 * @return 两个参数的和
18 */
19 public static double add(double v1,double v2){
20 BigDecimal b1 = new String(v1));
21 BigDecimal b2 = new String(v2));
22 return b1.add(b2).doubleValue();
23 }
24 /** *//**
25 * 提供精确的减法运算。
26 * @param v1 被减数
27 * @param v2 减数
28 * @return 两个参数的差
29 */
30 public static double sub(double v1,double v2){
31 BigDecimal b1 = new String(v1));
32 BigDecimal b2 = new String(v2));
33 return b1.subtract(b2).doubleValue();
34 }
35 /** *//**
36 * 提供精确的乘法运算。
37 * @param v1 被乘数
38 * @param v2 乘数
39 * @return 两个参数的积
40 */
41 public static double mul(double v1,double v2){
42 BigDecimal b1 = new String(v1));
43 BigDecimal b2 = new String(v2));
44 return b1.multiply(b2).doubleValue();
45 }
46
47 /** *//**
48 * 提供(相对)精确的除法运算,当发⽣除不尽的情况时,精确到
49 * ⼩数点以后10位,以后的数字四舍五⼊。
50 * @param v1 被除数
51 * @param v2 除数
52 * @return 两个参数的商
53 */
54 public static double div(double v1,double v2){
55 return div(v1,v2,DEF_DIV_SCALE);
56 }
57
58 /** *//**
59 * 提供(相对)精确的除法运算。当发⽣除不尽的情况时,由scale参数指
60 * 定精度,以后的数字四舍五⼊。
61 * @param v1 被除数
62 * @param v2 除数
63 * @param scale 表⽰表⽰需要精确到⼩数点以后⼏位。
64 * @return 两个参数的商
65 */
66 public static double div(double v1,double v2,int scale){
67 if(scale<0){
68 throw new IllegalArgumentException(
69 "The scale must be a positive integer or zero");
70 }
71 BigDecimal b1 = new String(v1));
72 BigDecimal b2 = new String(v2));
73 return b1.divid(b2,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
74 }
75
76 /** *//**
77 * 提供精确的⼩数位四舍五⼊处理。
78 * @param v 需要四舍五⼊的数字
79 * @param scale ⼩数点后保留⼏位
80 * @return 四舍五⼊后的结果
81 */
82 public static double round(double v,int scale){
83 if(scale<0){
84 throw new IllegalArgumentException(
85 "The scale must be a positive integer or zero");
86 }
87 BigDecimal b = new String(v));
88 BigDecimal one = new BigDecimal("1");
89 return b.divid(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
90 }
91 }
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论