数学处理类之 Math&BigDecimal

1、Math类的概述:

(1)、基本概念

java.lang.Math类主要用于提供执行数学运算的方法,如:对数、平方根等。

(2)常用方法

方法声明功能介绍
static int max(int a,int b)返回两个参数中的最大值
static int min(int a,int b)返回两个参数中的最小值
static double pow(double a,double b)返回第一个参数的幂
static int abs(int a)返回参数指定数值的绝对值
static long roud(double a)返回参数四舍五入的结果
static double sqrt(double a)返回参数的平方根
static double random()返回0.0~1.0的随机数

案例代码:

    System.out.println("获取两个整数中的最大值的结果:"+Math.max(10, 20));
	System.out.println("获取两个整数中的最小值的结果:"+Math.min(10, 20));
	System.out.println("获取次方的结果:"+Math.pow(2, 3));
	System.out.println("获取绝对值的结果:"+Math.abs(-10));
	System.out.println("获取四舍五入的结果:"+Math.round(3.67));
	System.out.println("该整数平方根结果:"+Math.sqrt(4*4));
	System.out.println("生成随机数:"+Math.random());

 运行结果:

获取两个整数中的最大值的结果:20
获取两个整数中的最小值的结果:10
获取次方的结果:8.0
获取绝对值的结果:10
获取四舍五入的结果:4
该整数平方根结果:4.0
生成随机数:0.6784107016787293

【更多Math方法可以在eclipse/IDEA中按住CTRL+鼠标左键点击Math进行查看;或者自行查阅jdkAPI文件进行搜索查看】


2、BigDecimal类的概述

(1)基本概念

由于float类型和double类型在运算时可能会产生误差,若希望实现精确运算需要使用java.math.BigDecimal类型加以描述。

(2)常用方法

方法声明介绍
BigDecimal(String val)根据参数指定的字符串构造对象
BigDecimal add(BigDecimal augend)用于实现加法运算
BigDecimal subtract(BigDecimal  subtrahend)用于实现减法运算
BigDecimal multiply(BigDecimal  multiplicand)用于实现乘法运算
BigDecimal divide(BigDecimal  divisor)用于实现除法运算

案例代码:

	BigDecimal bd1=new BigDecimal("5.2");
		BigDecimal bd2=new BigDecimal("1.3");
		//使用构造完毕的对象实现加减乘除运算
		System.out.println("实现加法运算的结果:"+bd1.add(bd2));//6.5
		System.out.println("实现加法运算的结果:"+bd1.subtract(bd2));//3.9
		System.out.println("实现乘法运算的结果:"+bd1.multiply(bd2));//6.76
		System.out.println("实现除法运算的结果:"+bd1.divide(bd2));//4
		//实现精确运算
		System.out.println(0.1+0.2);
		BigDecimal bd3=new BigDecimal("0.1");
		BigDecimal bd4=new BigDecimal("0.2");
		System.out.println("精确计算的结果:"+bd3.add(bd4));//0.3
		//4、注意事项
		BigDecimal bd5=new BigDecimal("2");
		BigDecimal bd6=new BigDecimal("0.3");
		System.out.println("除法运算的结果是:"+bd5.divide(bd6));

看到这里的你是不是会想这不就是简单的调用一下,然后进行运算结果的输出吗?也没什么特别之处吖,别捉急,运行结果在下边:

实现加法运算的结果:6.5
实现加法运算的结果:3.9
实现乘法运算的结果:6.76
实现除法运算的结果:4
0.30000000000000004
精确计算的结果:0.3
Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
	at java.math.BigDecimal.divide(BigDecimal.java:1693)
	at day01_Api.BigDecimalTest.main(BigDecimalTest.java:22)

你会发现2个问题!

第一个问题:System.out.println(0.1+0.2)结果并不是0.3!!!

第二个问题:这里怎么还有个Exception!!!

先来解决一下问题一:

别捉急看这里~~~这里需要了解一些基础知识:(计算机组成原理中会涉及到~)

  1. 计算机将所有数据以二进制的形式存储
  2. 计算机用有限的大小来存储数据(因为现实生活中不存在无限大的内存或硬盘)

如果你对十进制转二进制有兴趣可以看下图:

计算机是以二进制存储数值的,浮点数也不例外。Java 采用的是IEEE754标准实现浮点数的表达和运算。

比如,0.1 的二进制表示为 0.0 0011 0011 0011… (0011 无限循环),再转换为十进制就是 0.1000000000000000055511151231257827021181583404541015625。对于计算机而言,0.1 无法精确表达,这是浮点数计算造成精度损失的根本原因!!!

但是你又会想以 0.1 为例,其十进制和二进制间转换后相差非常小,不会对计算产生什么影响。但是我们假想一下如果你每天有一百万次交易,每次交易都差一分钱,一个月下来就差 30 万。这样的话你可能就不愿意了吧~~~

这里就涉及到浮点数精确表达和运算的场景,我们的主人公BigDecimal 就出场了。于是你输入代码:

System.out.println(new BigDecimal(0.1).add(new BigDecimal(0.2)));
0.3000000000000000166533453693773481063544750213623046875

但是你发现结果仍然。。。。。不是0.3!只不过是精度高了而已。这里给出浮点数运算避坑第一原则:使用 BigDecimal 表示和计算浮点数,务必使用字符串的构造方法来初始化 BigDecimal:

System.out.println(new BigDecimal("0.1").add(new BigDecimal("0.2")));

0.3终于出来了!!!

0.3

至此第一个问题就解决了。

再来看一下问题二:

异常原因:

算数异常,“ Non-terminating decimal expansion”–“无终止的小数扩展”:除法计算出了无限不循环小数

解决方案:

    public BigDecimal divide(BigDecimal divisor,int scale, int roundingMode)

第一个参数是除数,第二个参数代表保留几位小数,第三个代表的是使用的模式。

使用如下:

BigDecimal.ROUND_DOWN:直接省略多余的小数,比如1.28如果保留1位小数,得到的就是1.2

BigDecimal.ROUND_UP:直接进位,比如1.21如果保留1位小数,得到的就是1.3

BigDecimal.ROUND_HALF_UP:四舍五入,2.35保留1位,变成2.4

BigDecimal.ROUND_HALF_DOWN:四舍五入,2.35保留1位,变成2.3

后边两种的区别就是如果保留的位数的后一位如果正好是5的时候,一个舍弃掉,一个进位。

注:同时也可以对小数点进行格式化:【BigDecimal.setScale()方法】

setScale(1)表示保留一位小数,默认用四舍五入方式 
setScale(1,BigDecimal.ROUND_DOWN)直接删除多余的小数位,如2.35会变成2.3 
setScale(1,BigDecimal.ROUND_UP)进位处理,2.35变成2.4 
setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35变成2.4
setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35变成2.3,如果是5则向下舍

好了~今天的问题就解决喽~明天也要继续加油吖~~~~~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值