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!!!
先来解决一下问题一:
别捉急看这里~~~这里需要了解一些基础知识:(计算机组成原理中会涉及到~)
- 计算机将所有数据以二进制的形式存储
- 计算机用有限的大小来存储数据(因为现实生活中不存在无限大的内存或硬盘)
如果你对十进制转二进制有兴趣可以看下图:
计算机是以二进制存储数值的,浮点数也不例外。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则向下舍
好了~今天的问题就解决喽~明天也要继续加油吖~~~~~~