BigDecimal带精度的运算

编程技术  /  houtizong 发布于 3年前   61

在商业运算中要使用BigDecimal来进行相关的钱的运算(java中关于浮点运算需要注意的 ),可是实际使用中,简单的用BigDecimal还是出现了一些小问题。

 

Java代码 

1. BigDecimal a = new BigDecimal(998.01);  

2. BigDecimal b=new BigDecimal("100");  

3. System.out.println(a.multiply(b));  

4.   

5. BigDecimal aa = new BigDecimal(135.95);  

6. BigDecimal bb=new BigDecimal("100");  

7. System.out.println(aa.multiply(bb));  

8.   

9.   

10. BigDecimal test = new BigDecimal(4.015);  

11. BigDecimal test1 = new BigDecimal(100);  

12. System.out.println(test.multiply(test1));  

        BigDecimal a = new BigDecimal(998.01);

        BigDecimal b=new BigDecimal("100");

        System.out.println(a.multiply(b));

        

        BigDecimal aa = new BigDecimal(135.95);

        BigDecimal bb=new BigDecimal("100");

        System.out.println(aa.multiply(bb));

        

        

        BigDecimal test = new BigDecimal(4.015);

        BigDecimal test1 = new BigDecimal(100);

        System.out.println(test.multiply(test1));

  

输出结果为:

 

Java代码 

1. 99800.999999999999090505298227071762084960937500  

2. 13594.99999999999886313162278383970260620117187500  

3. 401.49999999999996802557689079549163579940795898437500  

99800.999999999999090505298227071762084960937500

13594.99999999999886313162278383970260620117187500

401.49999999999996802557689079549163579940795898437500

 

   出现这种情况的原因就是没有使用BigDecimal的精度。不罗嗦了,直接写上使用BigDecimal的带精度的运算。

 

   比较简单,看代码:

 

 

Java代码 

1. BigDecimal aa = new BigDecimal(135.95);  

2. BigDecimal bb=new BigDecimal("100");  

3. BigDecimal result=aa.multiply(bb);  

4. System.out.println(result.setScale(2,BigDecimal.ROUND_HALF_EVEN));  

BigDecimal aa = new BigDecimal(135.95);

BigDecimal bb=new BigDecimal("100");

BigDecimal result=aa.multiply(bb);

System.out.println(result.setScale(2,BigDecimal.ROUND_HALF_EVEN));

  

    此时的输出结果为:

 

Java代码 

1. 13595.00  

13595.00

  

    最主要的是运用了:

 

 

Java代码 

1. result.setScale(2,BigDecimal.ROUND_HALF_EVEN)  

result.setScale(2,BigDecimal.ROUND_HALF_EVEN)

 

    看一下BigDecimal的setScale的api

 

 

BigDecimal的API 写道

可以通过两种类型的操作来处理 BigDecimal 的标度:标度/舍入操作和小数点移动操作。标度/舍入操作(setScale 和 round)返回 BigDecimal,其值近似地(或精确地)等于操作数的值,但是其标度或精度是指定的值;即:它们会增加或减少对其值具有最小影响的存储数的精度。小 数点移动操作(movePointLeft 和 movePointRight)返回从操作数创建的 BigDecimal,创建的方法是按指定方向将小数点移动一个指定距离。

 

 

Java代码 

1. setScale  

2.   

3. public BigDecimal setScale(int newScale,  

4.                            int roundingMode)  

5. 返回一个 BigDecimal,其标度为指定值,其非标度值通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定,  

6. 以维护其总值。如果该操作减少标度,则非标度值必须被除(而不是乘),并且该值可以更改;在这种情况下,将指定的  

7. 舍入模式应用到除法中。  

8. 注意,由于 BigDecimal 对象是不可变的,此方法的调用不会 导致初始对象被修改,  

9. 这与使用名为 setX 变异字段 X 方法的常规约定相反。相反,setScale 返回具有适当标度的对象;  

10. 返回的对象不一定是新分配的。  

11.   

12. 相对于此遗留方法,应优先使用新的 setScale(int, RoundingMode) 方法。  

13.   

14. 参数:  

15. newScale - 要返回的 BigDecimal 值的标度。  

16. roundingMode - 要应用的舍入模式。  

17. 返回:  

18. 一个 BigDecimal,其标度为指定值,其非标度值可以通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定。  

setScale

public BigDecimal setScale(int newScale,

                           int roundingMode)

返回一个 BigDecimal,其标度为指定值,其非标度值通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定,

以维护其总值。如果该操作减少标度,则非标度值必须被除(而不是乘),并且该值可以更改;在这种情况下,将指定的

舍入模式应用到除法中。

注意,由于 BigDecimal 对象是不可变的,此方法的调用不会 导致初始对象被修改,

这与使用名为 setX 变异字段 X 方法的常规约定相反。相反,setScale 返回具有适当标度的对象;

返回的对象不一定是新分配的。

相对于此遗留方法,应优先使用新的 setScale(int, RoundingMode) 方法。

参数:

newScale - 要返回的 BigDecimal 值的标度。

roundingMode - 要应用的舍入模式。

返回:

一个 BigDecimal,其标度为指定值,其非标度值可以通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定。

RoundingMode的API

 

 

枚举常量摘要 

CEILING   
          向正无限大方向舍入的舍入模式。

DOWN   
          向零方向舍入的舍入模式。

FLOOR   
          向负无限大方向舍入的舍入模式。

HALF_DOWN   
          向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向下舍入。

HALF_EVEN   
          向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。

HALF_UP   
          向最接近数字方向舍入的舍入模式,如果与两个相邻数字的距离相等,则向上舍入。

UNNECESSARY   
          用于断言请求的操作具有精确结果的舍入模式,因此不需要舍入。

UP   
          远离零方向舍入的舍入模式。

 

 

  看完这些前面那个:

 

Java代码 

1. result.setScale(2,BigDecimal.ROUND_HALF_EVEN)  

result.setScale(2,BigDecimal.ROUND_HALF_EVEN)

 

   的意思就是,将这个BigDecimal小数点后保留2位,四舍五入的方式为向最接近数字方向舍入的舍入 模式,如果与两个相邻数字的距离相等,则向相邻的偶数舍入。 

 

    ok,记录完毕,看来以后要用bigDecimal还必须要用它这个scale的功能来保证精度,不然还是跟double一样会出现悲剧!

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!

留言需要登陆哦

技术博客集 - 网站简介:
前后端技术:
后端基于Hyperf2.1框架开发,前端使用Bootstrap可视化布局系统生成

网站主要作用:
1.编程技术分享及讨论交流,内置聊天系统;
2.测试交流框架问题,比如:Hyperf、Laravel、TP、beego;
3.本站数据是基于大数据采集等爬虫技术为基础助力分享知识,如有侵权请发邮件到站长邮箱,站长会尽快处理;
4.站长邮箱:[email protected];

      订阅博客周刊 去订阅

文章归档

文章标签

友情链接

Auther ·HouTiZong
侯体宗的博客
© 2020 zongscan.com
版权所有ICP证 : 粤ICP备20027696号
PHP交流群 也可以扫右边的二维码
侯体宗的博客