bigdecimal向上取整Java_BigDecimal类「建议收藏」

bigdecimal向上取整Java_BigDecimal类「建议收藏」BigDecimal是java小数操作的一个专有类,在电商、金融行业存储跟金额有关的字段java里面明明已经有了,float,double这种精度的小数,为什么还需要BigDecimal呢?这难道不是多余吗?接下来看一个例子:1@Test2publicvoidtestDoubleSimple(){3doublea=3;4doubleb=10;5doublec=a…

大家好,又见面了,我是你们的朋友全栈君。

BigDecimal 是java小数操作的一个专有类,在电商、金融行业 存储跟金额有关的字段

java里面明明已经有了,float,double这种精度的小数,为什么还需要BigDecimal呢?

这难道不是多余吗?

接下来看一个例子:

1 @Test2 public voidtestDoubleSimple() {3 double a = 3;4 double b = 10;5 double c = a /b;6 System.out.println(c);7 }

控制台输出:0.3

在小数操作中,我们通常希望能有多种自由的定义方式。

例如在不同的场景可能需要返回: 0.3, 0.4, 0.333 不同精度,在不同的精度进位时希望能自主控制

这个时候,就轮到BigDecimal出场了

加减乘除

首先来一段最简单的加减乘除

1 @Test2 public voidtestDecimalSimple() {3 BigDecimal a = new BigDecimal(5);4 BigDecimal b = new BigDecimal(40);5 BigDecimal add =a.add(b);6 BigDecimal subtract =a.subtract(b);7 BigDecimal multiply =a.multiply(b);8 BigDecimal divide =a.divide(b);9 System.out.println(“add:” +add);10 System.out.println(“subtract:” +subtract);11 System.out.println(“multiply:” +multiply);12 System.out.println(“divide:” +divide);13 }

控制台输出内容如下:

add:45;

subtract:-35;

multiply:200;

divide:0.125;

在了解了BigDecimal基本内容后,在去深入的去使用它的精度

精度控制

精度有7种模式,举例如下

1 @Test2 public voidtestRound() {3 //正无穷大方向取整

4 System.out.println(“celling:” + new BigDecimal(0.125, new MathContext(2, RoundingMode.CEILING)));5 //负无穷大方向取整

6 System.out.println(“floor:” + new BigDecimal(0.125, new MathContext(2, RoundingMode.FLOOR)));7 //向 0 的方向取整

8 System.out.println(“down a:” + new BigDecimal(0.121, new MathContext(2, RoundingMode.DOWN)));9 System.out.println(“down b:” + new BigDecimal(-0.129, new MathContext(2, RoundingMode.DOWN)));10 //正数向正无穷大取整,负数向负无穷大取整

11 System.out.println(“up a:” + new BigDecimal(0.121, new MathContext(2, RoundingMode.UP)));12 System.out.println(“up b:” + new BigDecimal(-0.129, new MathContext(2, RoundingMode.UP)));13 /**

14 * 5,6,7,8,9 向上取整15 * 1,2,3,4 向下取整16 *17 * 常用的4舍5入18 */

19 System.out.println(“half up:” + new BigDecimal(0.125, new MathContext(2, RoundingMode.HALF_UP)));20 /**

21 * 6,7,8,9 向上取整22 * 1,2,3,4,5 向下取整23 *24 * 5 向下取整25 */

26 System.out.println(“half down:” + new BigDecimal(0.125, new MathContext(2, RoundingMode.HALF_DOWN)));27

28 /**

29 * 小数位是5时,判断整数部分是奇数就进位30 * 1,2,3,4, 舍弃31 * 6,7,8,9, 进位32 */

33 System.out.println(“odd a:” + new BigDecimal(5.4, new MathContext(1, RoundingMode.HALF_EVEN)));34 System.out.println(“odd b:” + new BigDecimal(5.5, new MathContext(1, RoundingMode.HALF_EVEN)));35 /**

36 * 小数位是5时,判断整数部分是偶数就舍弃37 * 1,2,3,4, 舍弃38 * 6,7,8,9, 进位39 */

40 System.out.println(“even a:” + new BigDecimal(6.5, new MathContext(1, RoundingMode.HALF_EVEN)));41 System.out.println(“even b:” + new BigDecimal(6.6, new MathContext(1, RoundingMode.HALF_EVEN)));42 }

控制台输出内容如下

celling:0.13;

floor:0.12;

down a:0.12;

down b:-0.12;

up a:0.13;

up b:-0.13;

half up:0.13;

half down:0.12;

odd a:5;

odd b:6;

even a:6;

even b:7;

在 RoundingMode.XXXXX 类型的源码注释上面,有更加详细的例子,可以看到是怎么舍入的

除法详细介绍

我认为在电商,金融领域中,用BigDecimal最重要的原因有两个:

1. 精度准确

2. 除法运算支持好

所以一定要对除法做深入的了解,做项目的时候,才能不会对这些类型感到疑惑

1 @Test2 public voidtestDecimalDivide() {3 BigDecimal a = new BigDecimal(5.4);4 BigDecimal b = new BigDecimal(3.1);5 BigDecimal divide =a.divide(b);6 System.out.println(“divide:” +divide);7 }

出现异常:

1 java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

明明刚刚还好好的,怎么现在出了事?

那是因为 5.4、3.1都是double类型转换的 BigDecimal。

实际上5.4在内存中可能是 5.40000003321546546 的内容。导致BigDecimal内部精度计算的时候,发生错误

这个错误是因为没有指定精度导致的,我们只要指定了结果的精度,就可以避免这个问题。

推荐做法

1 @Test2 public voidtestDecimalStandDivide() {3 BigDecimal a = new BigDecimal(5.4);4 BigDecimal b = new BigDecimal(3.1);5 //保留几位小数

6 int scale = 2;7 //重点:务必是3个参数

8 BigDecimal divide =a.divide(b,scale,RoundingMode.HALF_UP);9 System.out.println(“divide:” +divide);10

11 }

控制台输出:divide:1.74

我们额外传入第二个参数:保留的小数,指定了结果的精度,就可以避免出现这种问题。

所以我们日常用BigDecimal做除法运算的时候,务必写成推荐的形式。避免出现了异常,自己还莫名其妙

默认除法精度

在文章的开头的除法,是用整数转成BigDecimal, 保留的3为小数。 那默认情况下会精确到几位呢?

在跟进到divide函数内部时,发现了构造MathContext的部分内容:

1 MathContext mc = new MathContext( (int)Math.min(this.precision() +

2 (long)Math.ceil(10.0*divisor.precision()/3.0),3 Integer.MAX_VALUE),4 RoundingMode.UNNECESSARY);

整数 12345 的precision 是5

整数 332 的precision 是 3

小数5.4 的precision可能是 5.40000065464698656565454454555 的长度。 值不固定

根据MathContext的第一个参数的计算方式得到默认除法精度:

1. 当被除数为:0x1 最低精度5

2. 当被除数为:0xFFFFFFFF 最高精度36

总结

BigDecimal 精度描述:

模式

描述

CEILING

正无穷大方向取整

FLOOR

负无穷大方向取整

DOWN

向 0 的方向取整

UP

正数向正无穷大取整,负数向负无穷大取整

HALF_UP

5,6,7,8,9 向上取整、 1,2,3,4 向下取整、 常用的4舍5入

HALF_DOWN

6,7,8,9 向上取整 1,2,3,4,5 向下取整

HALF_EVEN

小数位是5时,判断整数部分是奇数就进位、 小数位是5时,判断整数部分是偶数就舍弃、 1,2,3,4, 舍弃、 6,7,8,9, 进位

————————————————

参考链接:https://blog.csdn.net/mz4138/article/details/82708815

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/143880.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • python vimrc[通俗易懂]

    python vimrc[通俗易懂]全局:在/etc/vim/vimrc中添加 本地:~/.vimrcsetfileencodings=utf-8,gbksetambiwidth=double“支持中文setsmartindentsetsmarttabsetexpandtabsettabstop=4setsofttabstop=4setshiftwidth=

    2022年6月13日
    26
  • 32.HttpRequest对象的学习

    32.HttpRequest对象的学习引言——在前面你也跟着本博主编写了那么多的视图函数,但是每个视图函数它都会接收一个名为request的参数。是不是很好奇:视图函数接收到的request到底是个什么对象!!!HttpRequest对象1.我们可以打印这个request对象,看一下:<WSGIRequest:GET’/music/test3/’>我们知道WSGIRequest是一个HTTP请求对象,里面包括了提交的方式和URL路径。综上可知:服务器接收到http协议的请求后,会根据报文创建HttpReq.

    2022年6月30日
    20
  • java怎么增加堆栈_如何增加Java堆栈大小?「建议收藏」

    java怎么增加堆栈_如何增加Java堆栈大小?「建议收藏」如何增加Java堆栈大小?我问了这个问题,以了解如何增加JVM中的运行时调用堆栈大小。我已经得到了一个答案,而且我也得到了很多有用的答案和评论,这些答案和评论与Java如何处理需要大型运行时堆栈的情况相关。我已经回答了问题的总结。最初我想增加JVM堆栈的大小,所以像没有StackOverflowError运行的程序。publicclassTT{publicstaticlongfa…

    2022年7月7日
    20
  • 彻底了解DVD:从入门到精通(三)[转]「建议收藏」

    彻底了解DVD:从入门到精通(三)[转]「建议收藏」第七章 正版与盗版    这一章有两大问题的预备知识需要交待。  第一大问题是最最敏感的问题,也是本文无法在正规刊物上发表的致命原因,对于DVD,我们应该收藏正版还是D版?  第二个问题是,如果要收藏D版,要注意哪些问题。  谈到收藏,先要解释几个常用名词(第九章会有更详细的解释):  D版:盗版,成为这个敏感词的代称。  D商:有两个意思,一是指盗版商,也叫DS,二是泛指碟商。大…

    2022年7月11日
    16
  • 随 机 数 算 法

    随 机 数 算 法一、随机数概述在password技术中,随机序列是非常重要的,比方密钥产生、数字签名、身份认证和众多的password学协议等都要用到随机序列。所以产生高质量的随机数序列对信息的安全性具有十分关键的数

    2022年7月1日
    23
  • Redis学习——Redis持久化之AOF备份方式保存数据

    新技术的出现一定是在老技术的基础之上,并且完善了老技术的某一些不足的地方,新技术和老技术就如同JAVA中的继承关系。子类(新技术)比父类(老技术)更加的强大!在前面介绍了 Redis学习——Redis持久化之RDB备份方式保存数据之后,下面在整理和学习一下Redis的AOF方式保存数据。

    2022年2月26日
    44

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号