一直以来我几乎未使用过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. ORACLE百分比分析函数RATIO_TO_REPORT() OVER()

    有时候不用的指标的绝对值不能比,但是转转为百分比的形式就容易看出波动了,是数据分析的好用的一个分析函数 20:00:24 SYS@orcl> conn scott/tiger; Connecte ...

  2. 苹果电脑Mac系统如何安装Adobe Flash Player

    一)安装/更新Adobe Flash Player 开系统偏好设置 , Flash player  更新,立即检查/立刻安装: Flash插件官方每月常规更新1~2次,为避免频繁过期,建议设置为允许A ...

  3. k8s集群搭建(一)

    k8s简介 kubernetes,简称K8s,是用8代替8个字符“ubernete”而成的缩写.是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简 ...

  4. 监控进程cpu meminfo

    https://github.com/cdrandin/cpsc_351 https://github.com/cdrandin?after=Y3Vyc29yOnYyOpK5MjAxNC0wNy0xM ...

  5. arXiv上传文章latex源码技巧

    <<2019.09.27>>更新 上传PS文件看来也是不行了,一大早收到邮件被arXiv标记为incomplete了.哎,还是老老实实提交Latex source files吧 ...

  6. Nginx反向代理服务器的安装与配置

    Nginx反向代理服务器的安装与配置 时间:10月19日 Nginx反向代理有不少需要我们解决的问题,其中有不少问题是基于安装上的问题,在安装完成后的相关调试也让很多人头疼不已.下面就向大家介绍有关于 ...

  7. POJ2239-Selecting Courses-(匈牙利算法)

    题意:n门课,每门各自有t个开课时间,在不冲突的情况下选最多课. 题解:把周p第q节课转化为数值sum,表示在一周7*12节课中排第几节,用二分图最大匹配. #include<stdio.h&g ...

  8. hadoop java.io.EOFException: Unexpected end of input stream

    执行hadoop 报错 java.io.EOFException: Unexpected end of input stream at org.apache.hadoop.io.compress.De ...

  9. Python 的AES加密与解密

    AES加密方式有五种:ECB, CBC, CTR, CFB, OFB 从安全性角度推荐CBC加密方法,本文介绍了CBC,ECB两种加密方法的python实现 python 在 Windows下使用AE ...

  10. 对最长公共子序列(LCS)等一系列DP问题的研究

    LIS问题: 设\(f[i]\)为以\(a[i]\)结尾的最长上升子序列长度,有: \[f[i]=f[j]+1(j<i&&a[j]<a[i])\] 可以用树状数组优化至\( ...