原文地址:https://blog.csdn.net/cen_s/article/details/76472834

在日常开发中我们经常会碰到小数计算,而小数直接计算的话会出现一些小小的错误,如下

System.out.println(1.01 + 2.02);

你说能输出什么?3.03?实际上输出的是3.0300000000000002。这是因为不论是float 还是double都是浮点数,而计算机是二进制的,浮点数会失去一定的精确度。有没有不失精度的办法呢?这里就要用到BigDecimal了。

java.math.BigDecimal。Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精度浮点型变量double可以处理16位有效数。在实际应用中,需要对更大或者更小的数进行运算和处理。float和double只能用来做科学计算或者是工程计算,在商业计算中要用java.math.BigDecimal。BigDecimal所创建的是对象,我们不能使用传统的+、-、*、/等算术运算符直接对其对象进行数学运算,而必须调用其相对应的方法。方法中的参数也必须是BigDecimal的对象。构造器是类的特殊方法,专门用来创建对象,特别是带有参数的对象。

创建BigDecimal对象主要有两种。

  1. BigDecimal b1 = new BigDecimal("1.34");//1.34
  2. BigDecimal b2 = BigDecimal.valueOf(1.34);//1.34

其中b1也可以写成new BigDecimal(Double.toString(1.34)),可以直接new BigDecimal(1.34)吗,也是可以的,只是会出现上述的精度问题。

  1. BigDecimal one1 = new BigDecimal(1.34);//1.3400000000000000799360577730112709105014801025390625
  2. BigDecimal two1 = new BigDecimal("1.34");//1.34

除了这两种外,特殊的像0、1、10可以这样写。

  1. BigDecimal zero = BigDecimal.ZERO;
  2. BigDecimal one = BigDecimal.ONE;
  3. BigDecimal ten = BigDecimal.TEN;

比较一下BigDecimal.ZERO、new BigDecimal("0")、BigDecimal.valueOf(0)这三者,equals都是true,==的话new BigDecimal("0")就不用看了都new了,而BigDecimal.ZERO
== BigDecimal.ZERO为true。查看一下源代码可得。

  1. public static BigDecimal valueOf(long val) {
  2. if (val >= 0 && val < zeroThroughTen.length)
  3. return zeroThroughTen[(int)val];
  4. else if (val != INFLATED)
  5. return new BigDecimal(null, val, 0, 0);
  6. return new BigDecimal(INFLATED_BIGINT, val, 0, 0);
  7. }
  1. // Cache of common small BigDecimal values.
  2. private static final BigDecimal zeroThroughTen[] = {
  3. new BigDecimal(BigInteger.ZERO, 0, 0, 1),
  4. new BigDecimal(BigInteger.ONE, 1, 0, 1),
  5. new BigDecimal(BigInteger.valueOf(2), 2, 0, 1),
  6. new BigDecimal(BigInteger.valueOf(3), 3, 0, 1),
  7. new BigDecimal(BigInteger.valueOf(4), 4, 0, 1),
  8. new BigDecimal(BigInteger.valueOf(5), 5, 0, 1),
  9. new BigDecimal(BigInteger.valueOf(6), 6, 0, 1),
  10. new BigDecimal(BigInteger.valueOf(7), 7, 0, 1),
  11. new BigDecimal(BigInteger.valueOf(8), 8, 0, 1),
  12. new BigDecimal(BigInteger.valueOf(9), 9, 0, 1),
  13. new BigDecimal(BigInteger.TEN, 10, 0, 2),
  14. };

发现10以内的对象都是同一个,所以为true。

BigDecimal的加减乘除运算。

  1. public BigDecimal add(BigDecimal value);//加法
  2. public BigDecimal subtract(BigDecimal value);//减法
  3. public BigDecimal multiply(BigDecimal value);//乘法
  4. public BigDecimal divide(BigDecimal value);//除法

也可以照下面加法例子写成一个util,另外三个都差不多就不展开了。

  1. public static double add(double value1,double value2){
  2. BigDecimal b1 = new BigDecimal(Double.toString(value1));
  3. BigDecimal b2 = new BigDecimal(Double.toString(value2));
  4. return b1.add(b2).doubleValue();
  5. }

BigDecimal的运算都没有对原值进行操作,而是返回一个新的BigDecimal对象,这点可能有些小伙伴会搞错要注意一下。

  1. BigDecimal b1 =new BigDecimal("1.34");
  2. System.out.println("b1: " + b1);
  3. BigDecimal b2 =new BigDecimal("2.34");
  4. b1.add(b2);
  5. System.out.println("b1: " + b1);//b1并没有变

BigDecimal的比较用的是BigDecimal的compareTo方法,将此 BigDecimal 与指定的 BigDecimal 比较。

根据此方法,值相等但具有不同标度的两个BigDecimal对象(如,2.0 和 2.00)被认为是相等的。

当此 BigDecimal 在数字上小于、等于或大于被比较对象时,返回 -1、0 或 1。

    1. BigDecimal one = BigDecimal.valueOf(1);
    2. BigDecimal two = BigDecimal.valueOf(2);
    3. BigDecimal three = one.add(two);
    4. int i1 = one.compareTo(two);//-1
    5. int i2 = two.compareTo(two);//0
    6. int i3 = three.compareTo(two);//1

[转]Java中BigDecimal的使用的更多相关文章

  1. Java中BigDecimal的8种舍入模式是怎样的

    Java中BigDecimal的8种舍入模式是怎样的?下面长沙欧柏泰克软件学院和大家一起来学习下吧:  java.math.BigDecimal 不可变的.任意精度的有符号十进制数.BigDecima ...

  2. 关于java中BigDecimal的简介

    关于java中BigDecimal的简介 1.BigDecimal属于大数据,精度极高,不属于基本数据类型,属于java对象(引用数据类型), 这是sun提供的一个类,专门用在财务软件中. 2.注意: ...

  3. java中BigDecimal加减乘除基本用法

    Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位有效数. 在实际应用中,需要对更大或者更小的数进 ...

  4. Java中BigDecimal的8种舍入模式

    java.math.BigDecimal 不可变的.任意精度的有符号十进制数.BigDecimal 由任意精度的整数非标度值和32位的整数标度(scale)组成. 如果为零或正数,则标度是小数点后的位 ...

  5. Java中BigDecimal的舍入模式

    java.math.BigDecimal 不可变的.任意精度的有符号十进制数.BigDecimal 由任意精度的整数非标度值和32位的整数标度(scale)组成. 如果为零或正数,则标度是小数点后的位 ...

  6. Java中BigDecimal类介绍及用法

    Java中提供了大数字(超过16位有效位)的操作类,即 java.math.BinInteger 类和 java.math.BigDecimal 类,用于高精度计算. 其中 BigInteger 类是 ...

  7. java中BigDecimal在金融行业中的使用

    1.引言 在java语言中,double和float用于二进制浮点型计算,无法得到精确的结果.而BigDecimal则用于精确的计算.不超过16位有效数字(最好是不超过13位)的科学和工程计算,可以使 ...

  8. java中BigDecimal的学习

    干着java的活,但是看的都是一些偏底层的东西(或者我根本就没有看),有点荒废了java的学习. 最近一直在用到一个类是BigDecimal,但都是模棱两可地在那儿用,并没有深入研究这个类的细节,感觉 ...

  9. Java基础扫盲系列(二)—— Java中BigDecimal和浮点类型

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

随机推荐

  1. 【Algorithm】希尔排序

    一. 算法描述 希尔排序:将无序数组分割为若干个子序列,子序列不是逐段分割的,而是相隔特定的增量的子序列,对各个子序列进行插入排序:然后再选择一个更小的增量,再将数组分割为多个子序列进行排序..... ...

  2. Oracle 12C -- Identity Columns(标识列)

    Identity Columns很适合数据库中需要"surrogate keys"的场景.依赖sequence产生器,每行的标识列会被赋予一个自增或自减的值.缺省,标识列在创建的时 ...

  3. Java原理之HashMap

    一下JDK1.7测试没问题,1.8就不一样了,应该散列的更优化. 最近看了很多java底层之HashMap的原理,根据自己的实现如下: package com.gmq.chapter02; impor ...

  4. Java 8 – How to sort a Map

    Java 8 – How to sort a Map 1. Quick ExplanationMap result = map.entrySet().stream() .sorted(Map.Entr ...

  5. Spring Security教程(二):通过数据库获得用户权限信息

    上一篇博客中,Spring Security教程(一):初识Spring Security,我把用户信息和权限信息放到了xml文件中,这是为了演示如何使用最小的配置就可以使用Spring Securi ...

  6. c语言实现xor加密

    异或运算:^ 定义:它的定义是:两个值相同时,返回false,否则返回true.也就是说,XOR可以用来判断两个值是否不同. 特点:如果对一个值连续做两次 XOR,会返回这个值本身. ^ // 第一次 ...

  7. Android TextView 支持的HTML标签

    * <a href="...">    * <b>    * <big>    * <blockquote>    * <br ...

  8. 两种屏幕HUD区域限制的做法(矩形,弧形)

    HUD区域限制算是比较常用到的功能,方形的HUD区域限制多见于小地图,弧形或者椭圆多见于屏幕范围约束. 我没有研究倒角矩形做法,而是将椭圆和矩形进行插值得到一个弧度比较高的形状: 当插值为0时限制范围 ...

  9. modelsim编译Xilinx器件库的另一种方法(节省时间)

    以前在用modelsim对Xilinx进行器件库编译时,我用的比较多的是直接在ISE中编译器件库,感觉很方便简单,就是编译时间有点长.自从前段时间,在自己电脑装MathType,360杀毒软件将它视为 ...

  10. HTTP 错误 404.13 - Not Found 请求筛选模块被配置为拒绝超过请求内容长度的请求。

    问题:HTTP 错误 404.13 - Not Found 请求筛选模块被配置为拒绝超过请求内容长度的请求. 原因:Web 服务器上的请求筛选被配置为拒绝该请求,因为内容长度超过配置的值(IIS 7 ...