一直以来我几乎未使用过BigDecimal类型,只有在DB中涉及到金额字段时听说要用Decimal类型,但是今天再项目代码中看到使用BigDecimal表示贷款金额。

本篇文章不是介绍BigDecimal原理,只是说明BigDecimal和浮点的区别以及其应用场景。

借用《Effactive Java》这本书中的话:

float和double类型的主要设计目标是为了科学计算和工程计算。他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合。但是,商业计算往往要求结果精确,这时候BigDecimal就派上大用场啦。

下面来看几个例子:

 double d1 = 11540;
double d2 = 0.35;
System.out.println(d1 * d2);

执行结果:

4038.9999999999995

但是实际结果应该是:

4039.00

这类就出现上述Effective Java中提到的double用于科学计算,提供的是精确的快速近似计算,导致失去了精准结果。

 // 科学计数法
double d3 = 0.0000000000000000111;
System.out.println(d3);

输出结果:

1.11E-17

这也是上述提到的double用于科学计算领域,使用了科学计数法。

但是在实际项目中,特别对于金融领域,对金额十分敏感和精确的前提下不可能使用double或者float的浮点类型:

  • 用于科学计算领域使用了科学计数法
  • 用于大型数值近似计算,结果近似准确

基于以上,需要新的类型实现精准计算,Java提供BigDecimal类型:

Immutable, arbitrary-precision signed decimal numbers. A

  • {@code BigDecimal} consists of an arbitrary precision integer
  • unscaled value and a 32-bit integer scale

由Java docs中可以看出,BigDecimal是不可变的任意进度的十进制数。

BigDecimal位于java.math包下,正如其包名和类名,该类也提供了很多算术运算:加减乘除。

这里就不做详细介绍,具体可以查阅api文档。下面可一些例子:

BigDecimal bigDecimal1 = new BigDecimal("11540");
BigDecimal bigDecimal2 = new BigDecimal("0.35");
System.out.println(bigDecimal1.multiply(bigDecimal2));

输出结果:

4039.00

这里就是精准计算,所以项目应用中金额一般都用BigDecimal类型。

下面再介绍一些关于BigDecimal中使用到的一些坑和使用原则:

BigDecimal bigDecimal1 = new BigDecimal(20.11345);
BigDecimal bigDecimal2 = new BigDecimal("20.11345"); System.out.println(bigDecimal1);
System.out.println(bigDecimal2);

输出结果:

20.11345000000000027284841053187847137451171875
20.11345

在使用BigDecimal的double参数构造函数时,一定要注意看业务场景:是需要double近似还是精确。如果需要精确的场景,在使用前一定要将double转换成String,然后再转换成BigDecimal。否则将都是近似表示。

Java基础扫盲系列(二)—— Java中BigDecimal和浮点类型的更多相关文章

  1. Java基础扫盲系列(-)—— String中的format

    Java基础扫盲系列(-)-- String中的format 以前大学学习C语言时,有函数printf,能够按照格式打印输出的内容.但是工作后使用Java,也没有遇到过格式打印的需求,今天遇到项目代码 ...

  2. java基础解析系列(二)---Integer

    java基础解析系列(二)---Integer 前言:本系列的主题是平时容易疏忽的知识点,只有基础扎实,在编码的时候才能更注重规范和性能,在出现bug的时候,才能处理更加从容. 目录 java基础解析 ...

  3. Java基础扫盲系列(三)— Java内省技术

    前言 Java内省技术属于Java基础体系的的一部分,但是很多人都不甚了解.笔者也是在学习Spring源码的过程中遇到该技术模块的.为了完善技术体系,本文将全面的学习该技术.在提到Java内省技术,就 ...

  4. Java基础学习笔记二 Java基础语法

    注释 注释用来解释和说明程序的文字,注释是不会被执行的. 单行注释 //这是一条单行注释 public int i; 多行注释 /* 这是 * 一段注释, * 它跨越了多个行 */ public vo ...

  5. java基础学习系列二

    循环语句 1,for(){} 2,while(){} 3,do{}while() continue和break用法 break是结束循环 continue结束本次循环

  6. java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现

    java基础解析系列(四)---LinkedHashMap的原理及LRU算法的实现 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析 ...

  7. java基础解析系列(五)---HashMap并发下的问题以及HashTable和CurrentHashMap的区别

    java基础解析系列(五)---HashMap并发下的问题以及HashTable和CurrentHashMap的区别 目录 java基础解析系列(一)---String.StringBuffer.St ...

  8. java基础解析系列(六)---深入注解原理及使用

    java基础解析系列(六)---注解原理及使用 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)---Integer ja ...

  9. java基础解析系列(七)---ThreadLocal原理分析

    java基础解析系列(七)---ThreadLocal原理分析 目录 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)-- ...

随机推荐

  1. 配置WDA程序到NWBC

    NWBC是通过角色来做的权限管理,包括菜单项. 如果用户没有分配对应的,登陆后看到的东西很少,或者空白. 这里需要先将BC的个性化参数全部配齐,方便使用.BC最左上角,点击,设置,个性化设置. 如下几 ...

  2. Spark调用Linux命令实现解压和压缩功能

    一.应用场景 在Spark程序中调用Linux命令,实现一些程序难以实现的功能,例如:发送模拟邮件.文件打包或解压等等 二.代码实现 package big.data.analyse.linux im ...

  3. MySQL读写分离之Proxy

    MySQL Proxy: ======================================================== MySQL_Proxy Master Slave1 Slav ...

  4. 剑指offer-08 二叉树的下一个节点

    剑指offer第8题,本来想找leetcode上对应的题,后来没找到,直接去牛客网上刷了. 题目描述: 给定一个二叉树和其中的一个结点(pNode),请找出中序遍历顺序的下一个结点并且返回.注意,树中 ...

  5. SpringBoot中使用Maven插件,上传docker镜像

    开启docker远程端口 我上一篇里面写了,这里暴露的路径: 18.16.202.95:2375 简单构建 配置pom.xml文件 在properties中增加一行指定远程主机的位置 <prop ...

  6. js如何安全的扩展系统函数

    如果直接使用原型扩展系统函数,可能会和其他人的代码相互冲突 为了防止出现冲突,可以使用如下方法进行扩展: function MyArray(){ this.Name="MyArray&quo ...

  7. SpringBoot之邮件服务

    springboot 邮件服务 今天在看网上学习微服务的时候顺遍看到了一些关于springboot的文章,写的springboot拓展功能就顺遍学习了一下,接下来给大家分享一下springboot封装 ...

  8. 第02组Alpha冲刺(4/4)

    队名:十一个憨批 组长博客 作业博客 组长黄智 过去两天完成的任务:了解整个游戏的流程 GitHub签入记录 接下来的计划:继续完成游戏 还剩下哪些任务:完成游戏 燃尽图 遇到的困难:没有美术比较好的 ...

  9. centos7 中iptables、firewalld 和 netfilter 的关系

    centos7系统使用firewalld服务替代了iptables服务,但是依然可以使用iptables来管理内核的netfilter 但其实iptables服务和firewalld服务都不是真正的防 ...

  10. centos7 中没有service iptables save指令来保存防火墙规则

    解决方法: systemctl stop firewalld  关闭防火墙yum install iptables-services 安装 iptables 服务systemctl enable ip ...