180615-精度计算BigDecimal

文章链接: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/hexblog
一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
2. 声明
尽信书则不如,已上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
- 微博地址: 小灰灰Blog
- QQ: 一灰灰/3302797840
3. 扫描关注

180615-精度计算BigDecimal的更多相关文章
- 金额的计算BigDecimal类
金额的计算BigDecimal类 double d = 9.84; double d2 = 1.22; //注意需要使用BigDecimal(String val)构造方法 BigDecimal bi ...
- php的精度计算问题(bcadd和bcsub)
一.前言 我们在进行php开发的时候经常会遇到浮点型的问题,特别是涉及金额的部分,常常需要进行加减运算.当小数点的位数比较多的时候,往往容易犯一些很低级的错误.这里记录一下php的精度计算和封装的小d ...
- BigDecimal类(精度计算类)的加减乘除
BigDecimal类 对于不需要任何准确计算精度的数字可以直接使用float或double,但是如果需要精确计算的结果,则必须使用BigDecimal类,而且使用BigDecimal类也可以进行大数 ...
- BigDecimal工具类处理精度计算
/** * Created by My_coder on 2017-07-27. * 加减乘除计算工具类 */ public class BigDecimalUtil { private BigDec ...
- Java的精确整数计算-Bigdecimal学习总结和工具类
随笔:随着最近工作需要,回首需要涉及到一些精确的数据计算,就需要用到Bigdecimal,索性就趁着闲暇之余整理收集一下关于Bigdecimal的使用方法,由于时间的原因,整理的并不是特别详细,但相信 ...
- php精度计算问题
如果用php的+-*/计算浮点数的时候,可能会遇到一些计算结果错误的问题,比如echo intval( 0.58*100 );会打印57,而不是58,这个其实是计算机底层二进制无法精确表示浮点数的一个 ...
- 黄聪:php精度计算问题
如果用php的+-*/计算浮点数的时候,可能会遇到一些计算结果错误的问题,比如echo intval( 0.58*100 );会打印57,而不是58,这个其实是计算机底层二进制无法精确表示浮点数的一个 ...
- Java精度计算与舍入
用到的类: 类 BigDecimal:不可变的.任意精度的有符号十进制数.BigDecimal 由任意精度的整数非标度值 和 32 位的整数标度 (scale) 组成.如果为零或正数,则标度是小数点后 ...
- php 精度计算问题
PHP var_dump(intval(0.58 * 100)); 正确结果是 57,而不是 58 浮点运算惹的祸 其实这些结果都并非语言的 bug,但和语言的实现原理有关, js 所有数字统一为 N ...
随机推荐
- Redis配置文件(1)units/includes/GENERAL/SECURITY/LIMITS
redis.conf文件 在Linux进行文件的查看! units单位: # Note on units: when memory size is needed, it is possible to ...
- 决策树在sklearn中的实现
1 概述 1.1 决策树是如何工作的 1.2 构建决策树 1.2.1 ID3算法构建决策树 1.2.2 简单实例 1.2.3 ID3的局限性 1.3 C4.5算法 & CART算法 1.3.1 ...
- if __name__ == "__main__"如何正确理解
粗略来讲,__name__是当前模块,当模块被直接运行时模块名为__main__.这句话的意思是,当模块被直接执行时,代码将运行,当模块是被导入时,代码不被运行 例如,执行one.py # file ...
- 【题解】洛谷P1541 [NOIP2010TG] 乌龟棋(类似背包的DP)
题目来源:洛谷P1541 思路 类似背包的题 总之就是四种卡牌取的先后顺序不同导致的最终ans不同 所以我们用一个四维数组每一维分别表示第几种取了几张的最大分数 然后就是简单DP解决 代码 #incl ...
- Azure服务器上不了外网
将服务器的DNS改成223.5.5.5或者223.6.6.6
- 使用Kubespray部署Kubernetes集群
转载请标明出处: http://blog.csdn.net/forezp/article/details/82730382 本文出自方志朋的博客 Kubespray是Google开源的一个部署生产级别 ...
- JavaScript document对象
1.document对象是window对象的子对象,可直接使用,多用于获取HTML页面元素 2.document对象属性 a) alinkColor活动链接颜色 b) linkColor文本链接颜色 ...
- linux ping命令实践
ping 解析 Linux系统的ping命令是常用的网络命令,它通常用来检测与目标主机的连通性,经常说"ping以下机器,看是否开着,不能打开网页时候,可以ping ...
- 高级同步器:可重用的同步屏障Phaser
引自:https://shift-alt-ctrl.iteye.com/blog/2302923 在JAVA 1.7引入了一个新的并发API:Phaser,一个可重用的同步barrier.在此前,JA ...
- font(字体)所使用的属性
1.font-weight:normal blod bolder lighter 100-900之间 400=normal p:first-child{ padding-top: 50px; pos ...