BigDecimal详解 BigDecimal加减乘除运算 BigDecimal比较大小 BigDecimal保留两位小数

BigDecimal详解 BigDecimal加减乘除运算 BigDecimal比较大小 BigDecimal保留两位小数文章目录1、为什么要用BigDecimal?2、BigDecimal初始化赋值3、BigDecimal的加减乘除运算4、BigDecimal比较大小5、BigDecimal保留两位小数及舍入模式6、BigDecimal其他方法及常量1、为什么要用BigDecimal?工作中我们通过浮点数进行运算时,好像时不时的会出现一些小误差。例如:publicstaticvoidmain(String[]args){System.out.println(1.9-1.2);Sys

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

1、为什么要用BigDecimal ?

工作中我们通过浮点数进行运算时,好像时不时的会出现一些小误差。例如:

public static void main(String[] args) { 
   
    System.out.println(1.9 - 1.2);
    System.out.println(1.9 - 1.5);
    System.out.println(100 - 99.8);
}

在这里插入图片描述
大致搜了一下原因,网上说我们的计算机是二进制的,而浮点数是没有办法通过二进制精准的表示出来。
也就导致在运算的时候,float类型和double类型很容易丢失精度。
所以在开发中,如果我们需要精确计算的结果,可以使用java.math包中提供的BigDecimal类来进行操作。

2、BigDecimal初始化赋值

方法 类型 描述
public BigDecimal(int val) 构造函数 int类型的值生成BigDecimal对象
public BigDecimal(long val) 构造函数 long类型的值生成BigDecimal对象
public BigDecimal(String val) 静态方法 String类型的值转换为BigDecimal类型
public static BigDecimal valueOf(double val) 静态方法 double类型的值转换为BigDecimal类型
public static BigDecimal valueOf(long val) 静态方法 long类型(包含int类型)的值转换为BigDecimal类型
  • 代码示例:
BigDecimal b = new BigDecimal("33");
BigDecimal c = BigDecimal.valueOf(4.7);
  • 注意:不建议使用public BigDecimal(double val)方式初始化值,编码时idea提示禁止使用构造方法BigDecimal(double),描述如下:
使用了new BigDecimal(double)构造函数 less... (Ctrl+F1) 
Inspection info: 
禁止使用构造方法BigDecimal(double)的方式把double值转化为BigDecimal对象 说明:反编译出的字节码文件显示每次循环都会new出一个StringBuilder对象,然后进行append操作,最后通过toString方法返回String对象,造成内存资源浪费。
            
Negative example(不建议使用):
    BigDecimal good1 = new BigDecimal(0.1);

Positive example(建议使用):
    BigDecimal good1 = new BigDecimal("0.1");
    BigDecimal good2 = BigDecimal.valueOf(0.1);

在这里插入图片描述

3、BigDecimal的加减乘除运算

运算法则 对应方法
加法 public BigDecimal add(BigDecimal value)
减法 public BigDecimal subtract(BigDecimal value)
乘法 public BigDecimal multiply(BigDecimal value)
除法 public BigDecimal divide(BigDecimal value)
  • 代码示例:
public static void main(String[] args) { 
   
    System.out.println("计算加法: " + BigDecimal.valueOf(1.9).add(BigDecimal.valueOf(0.2)));
    System.out.println("计算减法: " + BigDecimal.valueOf(1.9).subtract(BigDecimal.valueOf(1.5)));
    System.out.println("计算乘法: " + BigDecimal.valueOf(1.9).multiply(BigDecimal.valueOf(0.2)));
    System.out.println("计算除法: " + BigDecimal.valueOf(1.9).divide(BigDecimal.valueOf(0.2)));
}

在这里插入图片描述

  • 注意1:BigDecimal的运算结果都是返回了一个新的BigDecimal对象,并不是在原有的对象上进行操作。
public static void main(String[] args) { 
   
    BigDecimal a = BigDecimal.valueOf(5);
    System.out.println("a的地址:" + System.identityHashCode(a));
    a = a.add(BigDecimal.valueOf(3));
    System.out.println("计算后a的地址:" + System.identityHashCode(a));
}

在这里插入图片描述

  • 注意2:使用divide除法函数除不尽,出现无线循环小数的时候,就需要使用另外精确的小数位数以及舍入模式,不然会出现报错。例如:
public static void main(String[] args) { 
   
    BigDecimal a = BigDecimal.valueOf(10), b = BigDecimal.valueOf(3);
    System.out.println(a.divide(b));
}

// 该程序运行会出现以下错误
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
    at java.math.BigDecimal.divide(BigDecimal.java:1690)
    at com.fivesix._05_bigdecimal.Demo01.main(Demo01.java:31)

解决方法如下(此处舍入模式使用四舍五入的方式,其他模式在该文章后面有讲解):

public static void main(String[] args) { 
   
    BigDecimal a = BigDecimal.valueOf(10), b = BigDecimal.valueOf(3);
    System.out.println(a.divide(b, 3, BigDecimal.ROUND_HALF_UP));
}
// 该程序运行后输出:
3.33

4、BigDecimal比较大小

public int compareTo(BigDecimal val)

BigDecimal类提供的比较值的方法,注意比较的两个值均不能为空
a.compareTo(b)得到结果 1, 0, -1。

比较结果 描述
1 a 大于b
0 a 等于b
-1 a 小于b
  • 代码示例:
public static void main(String[] args) { 
   
    BigDecimal a = BigDecimal.valueOf(1);
    BigDecimal b = BigDecimal.valueOf(2);
    BigDecimal c = BigDecimal.valueOf(1);
    BigDecimal d = BigDecimal.ZERO;
    System.out.println("1和2比较结果:" + a.compareTo(b));
    System.out.println("1和1比较结果:" + a.compareTo(c));
    System.out.println("1和0比较判断:" + (a.compareTo(d) > 0) );
}

在这里插入图片描述

5、BigDecimal保留两位小数及舍入模式

public BigDecimal setScale(int newScale, int roundingMode)

用于格式化小数的方法,第一个值表示保留几位小数,第二个值表示格式化的类型。
8种类型如下:

格式化类型 描述
ROUND_DOWN 舍弃多余位数,如1.55会格式化为1.5,-1.55会格式化为-1.5
ROUND_UP 进位处理,如1.52会格式化为1.6,-1.52会格式化为-1.6
ROUND_HALF_UP 四舍五入,如果舍弃部分>= .5,则进位
ROUND_HALF_DOWN 五舍六入,如果舍弃部分> .5,则进位
ROUND_CEILING 正无穷大方向舍入模式。如果值为正数,则与ROUND_UP模式相同;如果值为负数,则与ROUND_DOWN模式相同
ROUND_FLOOR 负无穷大方向舍入模式。如果值为正数,则与ROUND_DOWN模式相同;如果值为负数,则与ROUND_UP模式相同
ROUND_UNNECESSARY 确认值的小数位数是否与传入第一个参数(保留小数的位数)相等,如果符合则返回值,如果不符抛出异常
ROUND_HALF_EVEN 如果舍弃部门左边的数字为奇数,则与ROUND_HALF_UP模式相同,如果为偶数则与ROUND_HALF_DOWN模式相同
  • 代码示例:
public static void main(String[] args) { 
   
    BigDecimal a = BigDecimal.valueOf(5.445);
    System.out.println("5.445舍弃多余位数:" + a.setScale(2, BigDecimal.ROUND_DOWN));
    System.out.println("5.445进位处理:" + a.setScale(2, BigDecimal.ROUND_UP));
    System.out.println("5.445四舍五入(舍弃部分>= .5,进位):" + a.setScale(2, BigDecimal.ROUND_HALF_UP));
    System.out.println("5.445四舍五入(舍弃部分未> .5,舍弃):" + a.setScale(2, BigDecimal.ROUND_HALF_DOWN));
    System.out.println("5.446四舍五入(舍弃部分> .5,进位):" + BigDecimal.valueOf(5.446).setScale(2, BigDecimal.ROUND_HALF_DOWN));
}

在这里插入图片描述

6、BigDecimal其他方法及常量

代码 类型 描述
BigDecimal.ZERO 常量 初始化一个为0的BigDecimal对象
BigDecimal.ONE 常量 初始化一个为1的BigDecimal对象
BigDecimal.TEN 常量 初始化一个为10的BigDecimal对象
public BigDecimal abs() 方法 求绝对值,不管正数还是负数,都得到正数
public BigDecimal negate() 方法 求相反数,正变负,负变正
public BigDecimal pow(int n) 方法 求乘方,如BigDecimal.valueOf(2).pow(3)的值为8
public BigDecimal max(BigDecimal val) 方法 两值比较,返回最大值
public BigDecimal min(BigDecimal val) 方法 两值比较,返回最小值
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

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

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


相关推荐

  • docker端口映射失效解决方法[通俗易懂]

    docker端口映射失效解决方法[通俗易懂]docker端口映射失效解决方法

    2022年10月17日
    0
  • 快速排序基本思路(通俗易懂+例子)「建议收藏」

    快速排序基本思路(通俗易懂+例子)「建议收藏」快速排序今天看到大神写的一篇快速排序的博客,肃然起敬,觉得原来快速排序这么简单下面进行简单的试试快速排序的基本思想是1、先从数列中取出一个数作为基准数2、分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边3、再对左右区间重复第二步,直到各区间只有一个数概括来说为挖坑填数+分治法下面举例来进行说明,主要有三个参数,i为区间的开始地址,j为区间

    2022年6月15日
    25
  • 一文看懂Uart和USART的区别「建议收藏」

    一文看懂Uart和USART的区别「建议收藏」UART通用异步收发传输器(UniversalAsynchronousReceiver/Transmitter),通常称作UART,是一种异步收发传输器,是电脑硬件的一部分。它将要传输的资料在串行通信与并行通信之间加以转换。作为把并行输入信号转成串行输出信号的芯片,UART通常被集成于其他通讯接口的连结上。具体实物表现为独立的模块化芯片,或作为集成于微处理器中的周边设备。一般是RS-232C规格的,与类似Maxim的MAX232之类的标准信号幅度变换芯片进行搭配,作为连接外部设备的接口。在UART上追

    2022年5月19日
    51
  • dhcp option 67_DHCP HOST

    dhcp option 67_DHCP HOST1)DHCP客户端在初始化时广播发送请求报文,这时的请求报文并不包含option82选项。2)DHCP中继代理将option82选项添加到接收到的请求报文尾部后中继转发给DHCP服务器。DHCPOPTION82选项的子选项1(代理电路ID)默认是DHCP客户端所连接的交换机的接口信息(VLan名加物理端口名),也可以由用户自己配置代理电路ID,option82选项的子选项2(代理远程ID)是DHCP中继设备本身的MAC地址。3)DHCP服务器收到DHCP中继设备转发的DHCP请求…

    2022年10月16日
    0
  • Deep Boltzmann Machines

    Deep Boltzmann Machines转载自:http://blog.csdn.net/win_in_action/article/details/25333671 http://blog.csdn.net/zouxy09/article/details/8775518深度神经网络(Deepneuralnetwork)   深度学习的概念源于人工神经网络的研究。含多隐层的多层感知器就是一种深度学习结构

    2022年7月13日
    12
  • 锁定屏幕相关知识「建议收藏」

    锁定屏幕相关知识「建议收藏」  (1)LockWorkStation()锁定当前用户返回到登录界面 (2)HKEY_CURRENT_USER/Software/Microsoft/Windows/CurentVersion/Polioies/Explores下的”NoSaveSetting”值为1则禁止修改桌面(需要重启) (3)HKEY_CURRENT_USER/Software//microsof

    2022年7月21日
    16

发表回复

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

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