java中BigDecimal用法详解

首先,学习一个东西,我们都必须要带着问题去学,这边我分为 【为什么?】【是什么?】【怎么用?】

【为什么要用BigDecimal?】

首先,我们先看一下,下面这个现象

那为什么会出现这种情况呢?

因为不论是float 还是double都是浮点数,而计算机是二进制的,浮点数会失去一定的精确度。

注:根本原因是:十进制值通常没有完全相同的二进制表示形式;十进制数的二进制表示形式可能不精确。只能无限接近于那个值

但是,在项目中,我们不可能让这种情况出现,特别是金融项目,因为涉及金额的计算都必须十分精确,你想想,如果你的支付宝账户余额显示193.99999999999998,那是一种怎么样的体验?

【BigDecimal是什么?】

1、简介

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

2、构造器描述 

BigDecimal(int)       创建一个具有参数所指定整数值的对象。 

BigDecimal(double) 创建一个具有参数所指定双精度值的对象。 //不推荐使用

BigDecimal(long)    创建一个具有参数所指定长整数值的对象。 

BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。//推荐使用

3、方法描述 

add(BigDecimal)        BigDecimal对象中的值相加,然后返回这个对象。 

subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。 

multiply(BigDecimal)  BigDecimal对象中的值相乘,然后返回这个对象。 

divide(BigDecimal)     BigDecimal对象中的值相除,然后返回这个对象。 

toString()                将BigDecimal对象的数值转换成字符串。 

doubleValue()          将BigDecimal对象中的值以双精度数返回。 

floatValue()             将BigDecimal对象中的值以单精度数返回。 

longValue()             将BigDecimal对象中的值以长整数返回。 

intValue()               将BigDecimal对象中的值以整数返回。

特别说明一下,为什么BigDecimal(double)  不推荐使用

看上面代码运行结果,你就应该知道为什么不推荐使用了,因为用这种方式也会导致计算有问题,

为什么会出现这种情况呢?

 JDK的描述:

1、参数类型为double的构造方法的结果有一定的不可预知性。有人可能认为在Java中写入newBigDecimal(0.1)所创建的BigDecimal正好等于 0.1(非标度值 1,其标度为 1),但是它实际上等于0.1000000000000000055511151231257827021181583404541015625。这是因为0.1无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。

2、另一方面,String 构造方法是完全可预知的:写入 newBigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用String构造方法

double必须用作BigDecimal的源时,请使用Double.toString(double)转成String,然后使用String构造方法,或使用BigDecimal的静态方法valueOf,如下

【怎么用?】

这边我就不多说什么了,直接上代码,都挺简单的,最基本的加减乘除,应该能看的懂

这边特别提一下,如果进行除法运算的时候,结果不能整除,有余数,这个时候会报java.lang.ArithmeticException: ,这边我们要避免这个错误产生,在进行除法运算的时候,针对可能出现的小数产生的计算,必须要多传两个参数divide(BigDecimal,保留小数点后几位小数舍入模式)

舍入模式

ROUND_CEILING    //向正无穷方向舍入
ROUND_DOWN    //向零方向舍入
ROUND_FLOOR    //向负无穷方向舍入
ROUND_HALF_DOWN    //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向下舍入, 例如1.55 保留一位小数结果为1.5
ROUND_HALF_EVEN    //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,如果保留位数是奇数,使用ROUND_HALF_UP,如果是偶数,使用ROUND_HALF_DOWN
ROUND_HALF_UP    //向(距离)最近的一边舍入,除非两边(的距离)是相等,如果是这样,向上舍入, 1.55保留一位小数结果为1.6,也就是我们常说的“四舍五入”
ROUND_UNNECESSARY    //计算结果是精确的,不需要舍入模式
ROUND_UP    //向远离0的方向舍入

需要对BigDecimal进行截断和四舍五入可用setScale方法,例:

参考:

https://www.jb51.net/article/231683.htm

//www.jb51.net/article/231687.htm

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 浅谈Java基础知识之BigDecimal

    一.基本使用 使用示例: // 初始化 BigDecimal bd1=new BigDecimal("456"); BigDecimal bd2=new BigDecimal("123"); // 加 BigDecimal add=bd1.add(bd2); // 减 BigDecimal subtract=bd1.subtract(bd2); // 乘 BigDecimal multiply=bd1.multiply(bd2); // 除 BigDecimal d

  • Java精确计算BigDecimal类详解

    引言 float和double类型的主要设计目标是为了科学计算和工程计算.他们执行二进制浮点运算,这是为了在广域数值范围上提供较为精确的快速近似计算而精心设计的.然而,它们没有提供完全精确的结果,所以不应该被用于要求精确结果的场合.但是,商业计算往往要求结果精确,这时候BigDecimal就派上大用场啦. 先看下面代码 public static void main(String[] args) { System.out.println(0.2 + 0.1); System.out.printl

  • 详解java中BigDecimal精度问题

    一.背景 在实际开发中,对于 不需要任何准确计算精度的属性可以直接使用float或double,但是如果需要精确计算结果,则必须使用BigDecimal,例如价格.质量. 为什么这么说,主要有两点 1.double计算会有精度丢失问题 2.在除法运算时,BigDecimal提供了丰富的取舍规则.(double虽然可以通过NumberFormat进行四舍五入,但是NumberFormat是线程不安全的) 对于精度问题我们可以看下实际的例子 public static void main(Strin

  • Java BigDecimal类用法详解

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

  • java中BigDecimal用法详解

    首先,学习一个东西,我们都必须要带着问题去学,这边我分为 [为什么?][是什么?][怎么用?] [为什么要用BigDecimal?] 首先,我们先看一下,下面这个现象 那为什么会出现这种情况呢? 因为不论是float 还是double都是浮点数,而计算机是二进制的,浮点数会失去一定的精确度. 注:根本原因是:十进制值通常没有完全相同的二进制表示形式;十进制数的二进制表示形式可能不精确.只能无限接近于那个值 但是,在项目中,我们不可能让这种情况出现,特别是金融项目,因为涉及金额的计算都必须十分精确

  • Java中SimpleDateFormat用法详解

    public class SimpleDateFormat extends DateFormat SimpleDateFormat 是一个以国别敏感的方式格式化和分析数据的具体类. 它允许格式化 (date -> text).语法分析 (text -> date)和标准化. SimpleDateFormat 允许以为日期-时间格式化选择任何用户指定的方式启动. 但是,希望用 DateFormat 中的 getTimeInstance. getDateInstance 或 getDateTime

  • Java中DecimalFormat用法详解

    我们经常要将数字进行格式化,比如取2位小数,这是最常见的.Java 提供DecimalFormat类,帮你用最快的速度将数字格式化为你需要的样子.下面是一个例子: importjava.text.DecimalFormat; public class TestNumberFormat{ public static void main(String[]args){ doublepi=3.1415927; //圆周率 //取一位整数 System.out.println(newDecimalForm

  • Java 中 Reference用法详解

    Java  Reference详解 在 jdk 1.2 及其以后,引入了强引用.软引用.弱引用.虚引用这四个概念.网上很多关于这四个概念的解释,但大多是概念性的泛泛而谈,今天我结合着代码分析了一下,首先我们先来看定义与大概解释(引用类型在包 Java.lang.ref 里). 1.强引用(StrongReference) 强引用不会被GC回收,并且在java.lang.ref里也没有实际的对应类型.举个例子来说: Object obj = new Object(); 这里的obj引用便是一个强引

  • Java中Socket用法详解

    目录 1 问题引入 1.1 网络架构模型 1.1.1 OSI参考模型 1.1.2 TCP/IP五层模型 1.1.3 各协议层的说明 1.2 网络编程中的问题 1.3 TCP协议与UDP协议 1.3.1 TCP 1.3.2 UDP 1.3.3 TCP和UDP的区别 2 socket网络编程 2.1什么是socket? 2.2 Socket的原理 3 基于java的socket网络编程实现 3.2 基于UDP的socket实现 1 问题引入 1.1 网络架构模型 网络架构模型主要有OSI参考模型和T

  • java.text.DecimalFormat用法详解

    简要 DecimalFormat 的 pattern 都包含着 正负子 pattern ,例如 "#,##0.00;(#,##0.00)": /** * Created by Shuai on 2016/7/11. */ public class Main { public static void main(String[] args) { // 正值 BigDecimal bigDecimal = BigDecimal.valueOf(-12211151515151.541666);

  • java Beanutils.copyProperties( )用法详解

    这是一篇开发自辩甩锅稿~~~~ 昨天测试小姐姐将我的一个bug单重开了,emmmm....内心OS:就调整下对象某个属性类型这么简单的操作,我怎么可能会出错呢,一定不是我的锅!!but再怎么抗拒,bug还是要改的,毕竟晚上就要发版本了~~ 老老实实将我前天改的部分跟了一遍,恩,完美,没有任何的缺失~~but本应success的测试数据,接口返还的结果确实是false来着,那还是老老实实debug吧. 一步步跟下来,恩,多么顺畅,就说一定不是我的锅~~诶?不对不对,这里的ID值,为啥是null?传

  • Java RandomAccessFile的用法详解

    RandomAccessFile RandomAccessFile是用来访问那些保存数据记录的文件的,你就可以用seek( )方法来访问记录,并进行读写了.这些记录的大小不必相同:但是其大小和位置必须是可知的.但是该类仅限于操作文件. RandomAccessFile不属于InputStream和OutputStream类系的.实际上,除了实现DataInput和 DataOutput接口之外(DataInputStream和DataOutputStream也实现了这两个接口),它和这两个类系毫

  • Java中final关键字详解

    谈到final关键字,想必很多人都不陌生,在使用匿名内部类的时候可能会经常用到final关键字.另外,Java中的String类就是一个final类,那么今天我们就来了解final这个关键字的用法. 主要介绍:一.final关键字的基本用法.二.深入理解final关键字 一.final关键字的基本用法 在Java中,final关键字可以用来修饰类.方法和变量(包括成员变量和局部变量).下面就从这三个方面来了解一下final关键字的基本用法. 1.修饰类 当用final修饰一个类时,表明这个类不能

  • Java中Volatile关键字详解及代码示例

    一.基本概念 先补充一下概念:Java内存模型中的可见性.原子性和有序性. 可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉.通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情.为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制. 可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的.也就是一个线程修改的结果.另一个线程马上就能看到.比如:用volatile修饰的变量,就会具有可见性.volatile修饰的

随机推荐