第一版
java.math.RoundingMode 详解几个参数
java.math.RoundingMode中有几个参数让我有点头晕,现在用个人的理解来总结一下:
为了更好地理解,我们可以画一个XY轴
RoundingMode.CEILING:取右边最近的整数
RoundingMode.DOWN:去掉小数取整,即正数取左,负数取右,相当于向原点靠近的方向取整
RoundingMode.FLOOR:取左边最近的正数
RoundingMode.HALF_DOWN:五舍六入,负数先取绝对值,五舍六入再负数
RoundingMode.HALF_UP:四舍五入,负数原理同上
RoundingMode.HALF_EVEN:这个比较绕,如果整数是奇数,四舍五入,如果偶数是五舍六入
第二版
roundmode是指舍位时的模式,传输参数时使用BigDecimal.ROUND_XXXX_XXX,
以下例子是setscale(0,BigDecimal.ROUND_XXXX_XXX));如果保留小数位数不是零,例如
setScale(2,BigDecimal.ROUND_XXXX_XXX)); 是 2 ,这个数字的小数位数应该大于2位。第三个是选择得位。
ROUND_CEILING: 向无限方向移动 1.1->2 1.5->2 1.8->2 -1.1->-1 -1.5->-1 -1.8->-1
ROUND_DOWN:1.1.1向0方向移动->1 1.5->1 1.8->1 -1.1->-1 -1.5->-1 -1.8>-1
ROUND_FLOOR:与CEILING相反,负无限 1.1->1 1.5->1 1.8->1 -1.1->-2 -1.5->-2 -1.8->-2
ROUND_HALF_DOWN:以5为分界线,或五舍六入1.5->1 1.6->1 -1.5->-1 -1.6->-2 1.15->1.1 1.16->1.2 1.55->1.6 1.56->1.6
ROUND_HALF_EVEN:以5为分界线,如果是5,则前一个变偶数为1.15->1.2 1.16->1.2 1.25->1.2 1.26->1.3
ROUND_HALF_UP:最常见的四舍五入
ROUND_UNNECESSARY:无需舍位
ROUND_UP:ROUND_DOWN,1.1远离0的方向->2 1.5->2 1.8->2 -1.1->-2 -1.5->-2 -1.8->-2
具体精确到几个位置,因此应该使用它
商=被除数.devide(除数,保留小数位数,方法准确)
第三版
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 pide (BigDecimal val,RoundingMode mode) 除法
具体使用 计算:
加: a.add(b);
减: a.subtract(b);
乘: a.multiply(b);
除: a.pide(b,2);//2是精度取值
除法细解:
//注意以下相除会抛出异常的原因: 通过BigDecimal的pide方法进行除法时,当出现无限循环小数时,就会抛出异常
//BigDecimal pideBg = a.pide(b);
//解决方案是:设置精度;是为pide设置精确的小数点
pide(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.pide(BigDecimal.java:1278)
at main.Main.main(Main.java:41)
让我们来看看除法的详细说明:
pide(BigDecimal pisor, int scale, introundingMode)
BigDecimalsetScale方法
BigDecimal.setScale()
格式化小数点的方法
这意味着保留一个小数,默认情况下四舍五入
setScale(1)
如果2.35会变成2.35,直接删除多余的小数位 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入
注意点三
pide(BigDecimal pisor, int scale, introundingMode)意思是说:
我用bigdecimal对象除以pisor后的结果,并要求结果保留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比较大小
可通过BigDecimalcompareto方法进行比较。
返回的结果是int类型,-1小于,0等于,1大于。
下面的例子:
BigDecimal a = new BigDecimal("1.00");
BigDecmial b = new BigDecimal(1);
想比较a和b的大小,通常使用equals
System.out.println(a.equals(b));
但输出结果如下:false
原因是:BigDecimal比较时,不仅比较值,而且精度更高?
if(a.compareTo(b)==0) 结果是true
比较大小可以用 a.compareTo(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 = NumberFormat.getInstance();
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 BigDecimal(Double.toString(v1));
21 BigDecimal b2 = new BigDecimal(Double.toString(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 BigDecimal(Double.toString(v1));
32 BigDecimal b2 = new BigDecimal(Double.toString(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 BigDecimal(Double.toString(v1));
43 BigDecimal b2 = new BigDecimal(Double.toString(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 p(double v1,double v2){
55 return p(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 p(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 BigDecimal(Double.toString(v1));
72 BigDecimal b2 = new BigDecimal(Double.toString(v2));
73 return b1.pid(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 BigDecimal(Double.toString(v));
88 BigDecimal one = new BigDecimal("1");
89 return b.pid(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
90 }
91 }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 pide (BigDecimal val,RoundingMode mode) 除法
具体使用 计算:
加: a.add(b);
减: a.subtract(b);
乘: a.multiply(b);
除: a.pide(b,2);//2是精度取值
除法细解:
//注意以下相除会抛出异常的原因: 通过BigDecimal的pide方法进行除法时,当出现无限循环小数时,就会抛出异常
//BigDecimal pideBg = a.pide(b);
//解决方案是:设置精度;是为pide设置精确的小数点
pide(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.pide(BigDecimal.java:1278)
at main.Main.main(Main.java:41)
让我们来看看除法的详细说明:
pide(BigDecimal pisor, int scale, introundingMode)
BigDecimalsetScale方法
BigDecimal.setScale()
格式化小数点的方法
这意味着保留一个小数,默认情况下四舍五入
setScale(1)
如果2.35会变成2.35,直接删除多余的小数位 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入
注意点三
pide(BigDecimal pisor, int scale, introundingMode)意思是说:
我用bigdecimal对象除以pisor后的结果,并要求结果保留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比较大小
可通过BigDecimalcompareto方法进行比较。
返回的结果是int类型,-1小于,0等于,1大于。
下面的例子:
BigDecimal a = new BigDecimal("1.00");
BigDecmial b = new BigDecimal(1);
想比较a和b的大小,通常使用equals
System.out.println(a.equals(b));
但输出结果如下:false
原因是:BigDecimal比较时,不仅比较值,而且精度更高?
if(a.compareTo(b)==0) 结果是true
比较大小可以用 a.compareTo(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 = NumberFormat.getInstance();
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 BigDecimal(Double.toString(v1));
21 BigDecimal b2 = new BigDecimal(Double.toString(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 BigDecimal(Double.toString(v1));
32 BigDecimal b2 = new BigDecimal(Double.toString(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 BigDecimal(Double.toString(v1));
43 BigDecimal b2 = new BigDecimal(Double.toString(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 p(double v1,double v2){
55 return p(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 p(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 BigDecimal(Double.toString(v1));
72 BigDecimal b2 = new BigDecimal(Double.toString(v2));
73 return b1.pid(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 BigDecimal(Double.toString(v));
88 BigDecimal one = new BigDecimal("1");
89 return b.pid(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
90 }
91 }
![](/images/780-200-2.jpg)