一直以来我几乎未使用过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. AIX系统逻辑卷管理

    前言: 前期项目需要部署多套AIX环境下RAC集群,之前很少接触AIX系统,上来被创建逻辑卷等基本命令打脸了,其实网上搜下资料很多,总结一下,也是方便自己日后查阅. 创建逻辑卷 1.查看所有磁盘设备 ...

  2. rocketmq 两主两从异步集群搭建

    1.安装JDK 需要先卸载系统默认的OPENJDK,安装 JDK1.8 64位的版本. 卸载open-jdk rpm -qa|grep java 查到open jdk的安装. 使用命令 rpm -e ...

  3. MySQL读写分离之Proxy

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

  4. 指针专题6-空指针NULL和void指针

    1 NULL指针 一个指针变量可以指向计算机中任何一块内存,不管该内存有没有被分配,也不管该内存有没有使用权限,只要把地址给他,他就可以指向.C语言没有一种机制保证指向内存的正确性,程序员必须自己提高 ...

  5. Nginx Rewrite相关功能-ngx_http_rewrite_module模块指令

    Nginx Rewrite相关功能-ngx_http_rewrite_module模块指令 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.

  6. 目标检测论文解读7——YOLO v2

    背景 YOLO v1检测效果不好,且无法应用于检测密集物体. 方法 YOLO v2是在YOLO v1的基础上,做出如下改进. (1)引入很火的Batch Normalization,提高mAP和训练速 ...

  7. ppt演讲者视图不可用的解决办法

    1. 关闭ppt 2. 对着桌面右键,选择:nView Desktop Manager 3. 应用程序--增强--去掉“添加Powerpoint幻灯片显示扩展程序(W)”

  8. 小学四则运算口算练习app---No.6

    今天主要解决按钮的闪退问题以及答案页面的设置: (位置问题还是无能为力....) 除此之外加了一些菜单键,右上角 resultActivity.class ; String select=;i< ...

  9. 模拟赛 T3 DFS序+树状数组+树链的并+点权/边权技巧

    题意:给定一颗树,有 $m$ 次操作. 操作 0 :向集合 $S$ 中加入一条路径 $(p,q)$,权值为 $v$ 操作 1 :给定一个点集 $T$,求 $T$ 的并集与 $S$ 中路径含交集的权和. ...

  10. MYSQL:基于哈希的索引和基于树的索引有什么区别?

    B+树是一个平衡的多叉树.B+树从根节点到叶子节点的搜索效率基本相当,不会出现大幅波动. 哈希索引采用一定的哈希算法,把键值换成新的哈希值,检索时不需要类似B+树那样从根节点逐级查找,只需一次哈希算法 ...