前言:
互联网公司,对于BigDecimal的使用,还是较为频繁的,那么就会涉及到关于这个类型的种种问题.

1:为什么使用BigDecimal
首先java八大基本类型真的很基本,4个整型搞不了小数,double和float搞的了小数,但搞不好,关键时刻就调链子,当然这也和他们存储方式有关(二进制无法精确的表示1/10),天生注定搞不了精密计算,尤其是和钱相关的.

所以一般我们对于精密点的计算和涉及货币的计算,都会使用BigDecimal.他的出现,就是为了解决基本数据类型浮点数不能进行精确计算的问题.

2:如何使用BigDecimal
就说最常用的:
2.1.初始化,一般使用这个构造方法:new BigDecimal(String value);
其他的不再多说,某度很多,只能说我们一般都会用这个String类型的入参

关于BigDecimal的初始化,有一个坑要注意,就是尽量使用String类型的去初始化。
不信的话,可以看看下面的例子:BigDecimal a = new BigDecimal(1.01);BigDecimal b = new BigDecimal(1.02);BigDecimal c = new BigDecimal("1.01");BigDecimal d = new BigDecimal("1.02");System.out.println(a.add(b));System.out.println(c.add(d));
最终的打印结果是:
2.0300000000000000266453525910037569701671600341796875
2.03
很明显,也是精度问题。这块要注意。

2.2.基本运算

add(BigDecimal)            BigDecimal对象中的值相加,然后返回这个对象。
subtract(BigDecimal)       BigDecimal对象中的值相减,然后返回这个对象。
multiply(BigDecimal)       BigDecimal对象中的值相乘,然后返回这个对象。
divide(BigDecimal)         BigDecimal对象中的值相除,然后返回这个对象。
toString()                 将BigDecimal对象中的值以字符串形式返回。
doubleValue()              将BigDecimal对象中的值以双精度数返回。
floatValue()               将BigDecimal对象中的值以单精度数返回。
longValue()                将BigDecimal对象中的值以长整数返回。
intValue()                 将BigDecimal对象中的值以整数返回。

3.采坑经验(敲黑板的重点!!!)
3.1.将BigDecimal类性的值(10.1000)传给页面后,页面展示的(10.1000)不是我们想要的(10.1),该怎么处理?

    BigDecimal money;public BigDecimal getMoney() {return money;}最开始上面的这种处理方式,如果money是10.1000,那么get方法也会拿到10.1000,但其实我们想要的是10.1就好了.
-------------------------------------------------------------------------    那怎么办,直接上最终版(重写个getMoneyString方法):public String getMoneyString() {return money.stripTrailingZeros().toPlainString();}这个方法返回的,就是10.1,String类型的
--------------------------------------------------------------------------解释下:1.stripTrailingZeros()方法官方文档对返回的解释是:a numerically equal BigDecimal with any trailing zeros removed.而且从方法名就可以看出来,就是去掉末尾的0.那么,为什么还要用toPlainString()方法呢?看个例子:new BigDecimal("60000.000").stripTrailingZeros();这个结果是6E+4,而不是我们想要的60000,而且官方文档上也说明了,返回的值,会用科学计数法来表示,所以看下个方法2.toPlainString()官方文档对返回的解释是:a string representation of this BigDecimal without an exponent field.就是返回一个不用指数表示的字符串形式的值.所以两个方法连用,就可以达到对BigDecimal的初步控制.

3.2.值的比较用compareTo,不要用equals
compareTo:左边比右边数大,返回1,相等返回0,比右边小返回-1
equals:BigDecimal重写了equals,比较的是数值

3.3.除法要养成习惯去设置精度,以免出现无限循环的小数而抛异常
(java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result)

new BigDecimal("10").divide(new BigDecimal("3"));
这个就会抛出上面的异常.所以要用下面的new BigDecimal("10").divide(new BigDecimal("3"), 4,        BigDecimal.ROUND_HALF_DOWN);
这个代表10除以3,结果保留4位小数,采用四舍五入保留
所以结果就是:3.3333

3.4.既然用了BigDecimal了,就应避免再与浮点类型互相转换,否则精度会受很大的影响

4.BigDecimal格式化
可以使用NumberFormat类的format(BigDecimal)方法,利用NumberFormat不同类型的实例,对BigDecimal转换不同的格式.详细可以查查NumberFormat的各种实例方法,比如:
NumberFormat.getCurrencyInstance();
NumberFormat.getCurrencyInstance();
NumberFormat.getInstance();

根据不同的需求,使用不同的格式…
下面提供两个现成的转换精度的方法

/**** @param obj 传入的BigDecimal类型* @return 返回String类型,保留两位小数(四舍五入),不够补0*/public static String formatToStringWithTwoPlaces(BigDecimal obj) {DecimalFormat df = new DecimalFormat("#.00");if (obj.compareTo(BigDecimal.ZERO) == 0) {return "0.00";} else if (obj.compareTo(BigDecimal.ZERO) > 0 && obj.compareTo(new BigDecimal(1)) < 0) {return "0" + df.format(obj).toString();} else {return df.format(obj).toString();}}//这个方法效果和上一个一样,两种不同的实现罢了public static String getDecimalStr(BigDecimal bd) {String bdStr;if (bd != null) {bdStr = bd.setScale(2, RoundingMode.HALF_EVEN).toPlainString();} else {bdStr = "0.00";}return bdStr;}public static void main(String[] args) {//各种类型测试BigDecimal bigDecimal1 = new BigDecimal("0");System.out.println(formatToStringWithTwoPlaces(bigDecimal1));//0.00BigDecimal bigDecimal11 = new BigDecimal("0.6");System.out.println(formatToStringWithTwoPlaces(bigDecimal11));//0.60BigDecimal bigDecimal12 = new BigDecimal("0.6666");System.out.println(formatToStringWithTwoPlaces(bigDecimal12));//0.67BigDecimal bigDecimal2 = new BigDecimal("2");System.out.println(formatToStringWithTwoPlaces(bigDecimal2));//2.00BigDecimal bigDecimal3 = new BigDecimal("2.1");System.out.println(formatToStringWithTwoPlaces(bigDecimal3));//2.10BigDecimal bigDecimal4 = new BigDecimal("2.22");System.out.println(formatToStringWithTwoPlaces(bigDecimal4));//2.22BigDecimal bigDecimal5 = new BigDecimal("2.333");System.out.println(formatToStringWithTwoPlaces(bigDecimal5));//2.33BigDecimal bigDecimal15 = new BigDecimal("0");System.out.println(getDecimalStr(bigDecimal15));//0.00BigDecimal bigDecimal115 = new BigDecimal("0.6");System.out.println(getDecimalStr(bigDecimal115));//0.60BigDecimal bigDecimal125 = new BigDecimal("0.6666");System.out.println(ConvertUtil.getDecimalStr(bigDecimal125));//0.67BigDecimal bigDecimal25 = new BigDecimal("2");System.out.println(getDecimalStr(bigDecimal25));//2.00BigDecimal bigDecimal35 = new BigDecimal("2.1");System.out.println(getDecimalStr(bigDecimal35));//2.10BigDecimal bigDecimal45 = new BigDecimal("2.22");System.out.println(getDecimalStr(bigDecimal45));//2.22BigDecimal bigDecimal55 = new BigDecimal("2.333");System.out.println(getDecimalStr(bigDecimal55));//2.33}

5.BigDecimal取整

    public static void main(String[] args) {BigDecimal bigDecimal = new BigDecimal(6.66);//6.66除以6,向上取整,结果为2BigDecimal divide = bigDecimal.divide(BigDecimal.valueOf(6),0, BigDecimal.ROUND_UP);System.out.println(divide);//2//6.66除以6,不报错,但有这么多小数跟在后面BigDecimal divide2 = bigDecimal.divide(BigDecimal.valueOf(6), BigDecimal.ROUND_UP);System.out.println(divide2);//1.110000000000000023684757858670006195704142252605//1.110000000000000023684757858670006195704142252605向上取整,结果为2BigDecimal bigDecimal1 = divide2.setScale(0, BigDecimal.ROUND_UP);System.out.println(bigDecimal1);//6.66除以6,报错:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.BigDecimal divide1 = bigDecimal.divide(BigDecimal.valueOf(6));System.out.println(divide1);//报错}

各个roundingMode详解如下:
ROUND_UP:非0时,舍弃小数后(整数部分)加1,比如1.11结果为2,-1.11结果为 -2
ROUND_DOWN:直接舍弃小数
ROUND_CEILING:如果 BigDecimal 是正的,则做 ROUND_UP 操作;如果为负,则做 ROUND_DOWN 操作 (一句话:取附近较大的整数)
ROUND_FLOOR: 如果 BigDecimal 是正的,则做 ROUND_DOWN 操作;如果为负,则做 ROUND_UP 操作(一句话:取附近较小的整数)
ROUND_HALF_UP:四舍五入(取更近的整数)
ROUND_HALF_DOWN:跟ROUND_HALF_UP 差别仅在于0.5时会向下取整
ROUND_HALF_EVEN:取最近的偶数
ROUND_UNNECESSARY:不需要取整,如果存在小数位,就抛ArithmeticException 异常

BigDecimal的个人总结相关推荐

  1. BigDecimal 转换为int 或者其他类型

    我列举了转换的方法 BigDecimal HALF_UP = new BigDecimal("-12.44").setScale(1, RoundingMode.HALF_UP); ...

  2. Android 金钱计算BigDecimal 的使用

    今天做了一个购物车的功能 ,设计到了钱的计算,使用到了BigDecimal 晚上回来总结下 这个BigDecimal 计算钱呢很好用 其主要有 1 add 加法 2 subtract 减法 3 mul ...

  3. 在进行商业运算时解决BigDecimal的精度丢失问题

    System.out.println(0.05+0.01); System.out.println(1.0-0.42); System.out.println(4.015*100); System.o ...

  4. java striptrailingzeros_java – 为什么不BigDecimal.stripTrailingZeros()总是删除所有尾随零?...

    我做了以下事情 MathContext context = new MathContext(7, RoundingMode.HALF_UP); BigDecimal roundedValue = ne ...

  5. js 实现精确加减乘除运算之BigDecimal.js

    在前端实际开发中,进行前端计算会出现丢失精度的问题,这里我们项目中运用了BigDecimal.js. js计算丢失精度原因 计算机的二进制实现和位数限制有些数无法有限表示.就像一些无理数不能有限表示, ...

  6. Java中BigDecimal工具类(支持空值运算版)

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 前言 需要计算的场景绕不过去会使用BigDecimal类, ...

  7. 为什么阿里巴巴禁止使用BigDecimal的equals方法做等值比较?

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! BigDecimal,相信对于很多人来说都不陌生,很多人都 ...

  8. 面试:BigDecimal一定不会丢失精度吗?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 来源 | urlify.cn/ZVN7Nb 我们基本已经形成了常识 ...

  9. Java中的BigDecimal类你真的了解吗?

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者:HikariCP www.jianshu.com/p/c81 ...

  10. 如何使用BigDecimal?

    点击上方"方志朋",选择"设为星标" 做积极的人,而不是积极废人 本文来源于读者投稿,已授权原创申明. 前言:BigDecimal的产生背景 在Java的8种基 ...

最新文章

  1. 区域人工智能集群效果显著 各大省市怎样布局?
  2. 如何看懂一个深度学习的项目代码
  3. 基于人工智能智商研究的智能定律初探
  4. 如何在树莓派上进行python编程_设置并使用树莓派进行Python和C语言编程 (下)
  5. 【翻译】Ext JS 5:为不同设备设置不同的主题
  6. EXCEL2013保存时提示Be careful!Parts of your document may include personal information...
  7. python3数据类型:Number(数字)
  8. 再见c罗再见梅西_再见,再见,5 * 60 * 1000 //五分钟,再见,再见
  9. 工作406- Error:Node Sass version 5.0.0 is incompatible with ^4.0.0 问题解决
  10. 【终于等到你】7种策略解除云风险警报
  11. kvm迁移镜像启动报错(the CPU is incompatible with host CPU: Host CPU does not provide required features: fma)
  12. 波卡跨链交易协议RAI Finance将接入Bounce Finance实现IDO代币发行
  13. linux-0.11内核 任务的堆栈切换
  14. C++箴言:多态基类中将析构函数声明为虚拟zz
  15. steam快速换号工具易语言源码 附成品
  16. 数据仓库之元数据管理
  17. python人脸对比相似度_相似度算法原理及python实现
  18. html5表格制作教程,html怎么做表格
  19. Access与Trunk
  20. Nature|人类肠道细菌对治疗药物的生物累积

热门文章

  1. CF1129D Isolation(分块+DP)
  2. 三极管稳压管组成的线性电源关键理解
  3. K-Means ++ 算法
  4. java实现可有括号的android计算器
  5. 对PostgreSQL cmin和cmax的理解
  6. QQ空间及邮箱验证码登录的校验方式及自动登录的解决方案
  7. 图灵2008年12月出版的计算机图书
  8. 操作系统 —— 内存管理
  9. 【剑指offer】面试题63:股票的最大利润(Java)
  10. Leetcode--319. 灯泡开关