资讯专栏INFORMATION COLUMN

180615-精度计算BigDecimal

phodal / 2262人阅读

摘要:文章链接精度计算精度计算目前接触的业务中,对数据的精度要求比较高,因此不再使用基本的,改为用进行存储和相关的计算,端午前的这一篇博文,则简单的介绍下的使用姿势,早点回家早点放假基本使用构造方法几个常见的构造方式,将基本类型等,转

文章链接:https://liuyueyi.github.io/hexblog/2018/06/15/180615-精度计算BigDecimal/

180615-精度计算BigDecimal

目前接触的业务中,对数据的精度要求比较高,因此不再使用基本的float,double,改为用BigDecimal进行存储和相关的计算,端午前的这一篇博文,则简单的介绍下BigDecimal的使用姿势,早点回家早点放假

I. 基本使用 1. 构造方法

几个常见的构造方式,将基本类型+String等,转换为BigDecimal对象

public BigDecimal(char[] in);
public BigDecimal(String val);
public BigDecimal(BigInteger val);
public BigDecimal(int val);
public BigDecimal(long val);
public BigDecimal(double val)
2. 加减乘除
public BigDecimal add(BigDecimal value);                        //加法

public BigDecimal subtract(BigDecimal value);                   //减法 

public BigDecimal multiply(BigDecimal value);                   //乘法

public BigDecimal divide(BigDecimal value);                     //除法

从上面的签名上,可以看出操作是属于链式结构(Builder模式),然后一个问题就是执行上面的操作之后,被调用的对象,是否会发生修改? (即下面的测试中的o值是否改变)

@Test
public void testBigDecimal() {
    BigDecimal o = new BigDecimal(11.1);
    BigDecimal d = new BigDecimal(1);

    System.out.println(o.add(d) + "| " + o);
}

输出结果

12.0999999999999996447286321199499070644378662109375| 11.0999999999999996447286321199499070644378662109375

结论: 计算后的结果需要保存,因为不会修改目标对象的值

3. 精度

前面的例子中,输出后面一长串,而这往往并不是我们希望的,所以可以设置下精度

public BigDecimal setScale(int newScale, RoundingMode roundingMode);

一个简单的case如下

@Test
public void testBigDecimal() {
    BigDecimal o = new BigDecimal(11.1);
    System.out.println(o.setScale(3, RoundingMode.CEILING) + "| " + o);
}

输出

11.100| 11.0999999999999996447286321199499070644378662109375

从上面的输出,特别是第二列,如果我们选择的精度方式是取下限,会不会有问题呢?

@Test
public void testBigDecimal() {
    BigDecimal o = new BigDecimal(11.1);
    System.out.println(o.setScale(1, RoundingMode.FLOOR) + "| " + o);
}

输出结果为:

11.0| 11.0999999999999996447286321199499070644378662109375

所以需要注意的地方就来了,对浮点数进行精度设置时,需要根据自己的业务场景,选择合适的取整方式,不然很容易出问题

取精度的几个参数说明

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的方向舍入
II. 其他 1. 一灰灰Blog: https://liuyueyi.github.io/he...

一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

2. 声明

尽信书则不如,已上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

微博地址: 小灰灰Blog

QQ: 一灰灰/3302797840

3. 扫描关注

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/71212.html

相关文章

  • BigDecimal 学习

    摘要:然而表示这个是的锅,我不背。的表示一共的数字位能存储个,表示存储两位小数。因为默认是保留两位小数,超过了精度,所以保存近似值。大范围低精度存储。很准确,采用科学计数法,损失精度,但能存储更大范围的数据,但是精度有损失。 BigDecimal 为什么要使用这个呢?简单点说就是商业要求精度计算,而double计算出来的结果,往往出人意料。 例子 Double运算 showImg(https...

    linkFly 评论0 收藏0
  • 精度数学运算

    摘要:使用,保证精度的同时,能精准的进行四舍六入计算。类精确的数学运算使用来实现精准度因为精度的原因构造方法的结果有一定的不可预知性,例如因此建议使用。算法规则四舍六入五考虑,五后非零就进一,五后皆零看奇偶,五前为偶应舍去,五前为奇要进一。 四舍六入计算 算法规则: 四舍六入五考虑, 五后非零就进一, 五后皆零看奇偶, 五前为偶应舍去, 五前为奇要进一。 使用BigDecimal,保证精度的...

    liaosilzu2007 评论0 收藏0
  • 180706-BigDecimal除法的精度问题

    摘要:除法的精度问题在使用的除法时,遇到一个鬼畜的问题,本以为的精度计算,结果使用返回,当然最终发现还是自己的使用姿势不对导致的,因此记录一下,避免后面重蹈覆辙问题抛出在使用做高精度的除法时,一不注意遇到了一个小问题,如下上面的输出是什么 showImg(https://segmentfault.com/img/remote/1460000015555232); BigDecimal除法的精...

    imccl 评论0 收藏0
  • Double精度丢失解决方案《浅谈BigDecimal

    摘要:错误将导致不能涨薪。如果未指定舍入模式,并且无法表示准确结果,则抛出一个异常否则,通过向该操作提供适当的对象,可以对已选择的精度和舍入模式执行计算。使用此类例如,中的整数字段来表示舍入模式已过时应改为使用例如,的枚举值。 为什么金额要使用BigDecimal而不使用Double? 在电商或者金融行业,看似很小的误差但是通过一番计算后会导致很大的误差,误差将演变为错误。错误将导致不能涨薪...

    icattlecoder 评论0 收藏0
  • 使用BigDecimal处理Java中的小数

    摘要:在中处理带小数的数据时,通常会碰到需要进行对数据进行四舍五入或者截取等操作。提供了一个的方法,很方便的帮助我们实现想要的操作。 在Java中处理带小数的数据时,通常会碰到需要进行对数据进行四舍五入或者截取等操作。BigDecimal提供了一个setScale()的方法,很方便的帮助我们实现想要的操作。 通常用到的是下面的方法 setScale(int newScale, in...

    用户84 评论0 收藏0

发表评论

0条评论

阅读需要支付1元查看
<