概述
一、和BigInteger的区别
整型大数据:BigInteger
浮点型大数据:BigDecimal
二、常量
BigDecimal num0=BigDecimal.ZERO;//0
BigDecimal num1=BigDecimal.ONE;//1
BigDecimal num10=BigDecimal.TEN;//10
三、初始化
1.字符串String做参数
BigDecimal a =new BigDecimal(“0.1”);
输出:0.1
2.数字double做参数
BigDecimal a =new BigDecimal(0.1);
输出:0.1000000000000000055511151231257827021181583404541015625
而:
BigDecimal a =new BigDecimal(0.5);
输出:0.5
不知道为啥(…,还望热心网友解答!
注意:最好用String做参数的原因:
1.0.1 无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1。
2.String 构造方法是完全可预知的:写入 new BigDecimal(”0.1″) 将创建一个BigDecimal,它正好等于预期的 0.1。
3.float和double类型主要是为了科学计算和工程计算而设计,他们执行二进制浮点运算,二进制不能准确的表示一个小数,就像十进制不能准确的表示1/3,1/6等。
另一种说法:
我们的计算机是二进制的。浮点数没有办法是用二进制进行精确表示。
我们的CPU表示浮点数由两个部分组成:指数和尾数,这样的表示方法一般都会失去一定的精确度,有些浮点数运算也会产生一定的误差。
如:2.4的二进制表示并非就是精确的2.4。反而最为接近的二进制表示是 2.3999999999999999。
浮点数的值实际上是由一个特定的数学公式计算得到的。
所以,通常情况下,我们会使用String对象作为参数来构造一个精确的BigDecimal对象。下面提供的三种方法都可以:
//方法一
BigDecimal a= new BigDecimal("1.1");
//方法二
BigDecimal b= new BigDecimal(Double.toString(1.1));
//方法三
BigDecimal c= BigDecimal.valueOf(1.1);
System.out.println(a);
System.out.println(b);
System.out.println(c);
运行结果:
1.1
1.1
1.1
BigDecimal.value(double val)方法为什么可以呢?
看看下面的源码,大家应该就清楚了:
public static BigDecimal valueOf(double val) {
return new BigDecimal(Double.toString(val));
}
四、常用方法
public static void main(String[] args) {
// 尽量用字符串的形式初始化
BigDecimal num1 = new BigDecimal("5");
BigDecimal num2 = new BigDecimal("17");
BigDecimal num3 = new BigDecimal("100");
// 加法
BigDecimal add = num1.add(num2);
// 减法
BigDecimal subtract = num1.subtract(num2);
// 乘法
BigDecimal multiply = num1.multiply(num2);
// 除法
BigDecimal divide = num2.divide(num1, 7, BigDecimal.ROUND_HALF_UP);
// 取余方法一
BigDecimal mod1 = num1.remainder(num2);
// 取余方法二
BigDecimal[] mod2 = num1.divideAndRemainder(num2);
// 绝对值
BigDecimal abs = num3.abs();
// 相反数
BigDecimal negate = num3.negate();
System.out.println("加法用string结果:" + add);
System.out.println("减法用string结果:" + subtract);
System.out.println("乘法用string结果:" + multiply);
System.out.println("除法用string结果:" + divide);
System.out.println("取余方法一用string结果:" + mod1);
System.out.println("取余方法二用string结果:" + mod2[1]);// 注:mod2[0]是商
System.out.println("绝对值用string结果:" + abs);
System.out.println("相反数用string结果:" + negate);
}
五、除法操作
除法操作有需要注意的地方,下面单独拿来说:
情况一:
结果是有限小数
eg:15/3 15/4
public static void main(String[] args) {
BigDecimal a = new BigDecimal("15");
BigDecimal b=new BigDecimal("3");
BigDecimal divide=a.divide(b);
System.out.println(divide);
}
情况二:
结果是无限小数,如果还是按上面方法计算的话,会报错: Non-terminating decimal expansion; no exact representable decimal result.
eg:15/9
public static void main(String[] args) {
BigDecimal a = new BigDecimal("15");
BigDecimal b=new BigDecimal("9");
BigDecimal divide=a.divide(b);
System.out.println(divide);
}
为什么会报这种错呢??
原来JAVA中如果用BigDecimal做除法的时候一定要在divide方法中传递第二个参数,定义精确到小数点后几位,否则在不整除的情况下,结果是无限循环小数时,就会抛出以上异常。
怎样解决不整除仍能出现结果的情况呢,这时候就要传进去几个参数
方法一:BigDecimal构造方法
public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode);
第一参数:除数
第二个参数:小数点后保留的位数
第三个参数:舍入模式,只有在作除法运算或四舍五入时才用到舍入模式,有下面这几种:
ROUND_CEILING //向正无穷方向舍入
ROUND_DOWN //向零方向舍入
ROUND_FLOOR //向负无穷方向舍入
ROUND_HALF_DOWN //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5
ROUND_HALF_EVEN //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP,如果是偶数,使用ROUND_HALF_DOWN
ROUND_HALF_UP //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6
ROUND_UNNECESSARY //计算结果是精确的,不需要舍入模式
ROUND_UP //向远离0的方向舍入
代码:
public static void main(String[] args) {
BigDecimal a = new BigDecimal("15");
BigDecimal b=new BigDecimal("3");
BigDecimal divide=a.divide(b,2,BigDecimal.ROUND_HALF_UP);
System.out.println(divide);
}
运行截图:
方法二:setScale方法
代码:
public static void main(String[] args) {
BigDecimal a = new BigDecimal("15");
BigDecimal b=new BigDecimal("3");
BigDecimal divide=a.divide(b);
BigDecimal ans=divide.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println(ans);
}
运行截图:
注意+强调:
public static void main(String[] args) {
BigDecimal a = new BigDecimal("15");
BigDecimal b1=new BigDecimal("4");
BigDecimal b2=new BigDecimal("7");
BigDecimal divide1=a.divide(b1);
BigDecimal ans1=divide1.setScale(1, BigDecimal.ROUND_HALF_UP);
System.out.println(ans1);
BigDecimal divide2=a.divide(b2);
BigDecimal ans2=divide2.setScale(1, BigDecimal.ROUND_HALF_UP);
System.out.println(ans2);
}
总之,第五个大标题除法操作,主要讲的是两种情况:
相除结果是有限小数、相除结果是无限小数(不能说成这两种情况:能被整除、不能被整除 因为15/4不能被整除,但是也可以运行出结果)
1.相除结果是有限小数:
可以通过构造方法或者setScale方法来输出结果。
2.相除结果是无限小数:
要想运行出结果就必须设置参数,即public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode);`
附:
setScale使用注意:
代码1:
public static void main(String[] args) {
BigDecimal a = new BigDecimal("15");
BigDecimal b2=new BigDecimal("7");
BigDecimal divide2=a.divide(b2);
BigDecimal ans2=divide2.setScale(1, BigDecimal.ROUND_HALF_UP);
System.out.println(ans2);
}
运行报错,因为setScale(1, BigDecimal.ROUND_HALF_UP)之前得到的divide2是无限小数。
代码2:
public static void main(String[] args) {
BigDecimal a = new BigDecimal("15");
BigDecimal b2=new BigDecimal("7");
BigDecimal divide2=a.divide(b2,1,BigDecimal.ROUND_HALF_UP);
BigDecimal ans2=divide2.setScale(0, BigDecimal.ROUND_HALF_UP);
System.out.println(divide2);
System.out.println(ans2);
}
最后
以上就是坦率蛋挞为你收集整理的Java大数据之BigDecimal的全部内容,希望文章能够帮你解决Java大数据之BigDecimal所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复