数学操作类
- Math
- Random
- 大数处理类
Math
Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。
隶属于java.lang包,该包由JVM自动导入
- 类定义
public final class Math(该类为最终类,不可被继承)
其构造方法被private 外部不能创建它的对象,按照这个类的作用也没有必要创建它的对象
其提供的方法的特点:它所提供的所有方法都是静态的,只用类名就可以调用,方便了我们的使用
- 常用方法
- abs
注意:在取值范围之内,没有对应的负数与之对应,所取绝对值的结果将有误
如:byte:-128--127 当求-128的绝对值将会出现有误(但是会得到错误的数值,但是编译器并不报错)
可以使用Math.absExct()方法进行调用,如果调用到这种情况,编译器将抛出错误(jdk15)
//Math类的方法的用法
/*
* max min 返回最大最小值
* abs 取绝对值 absExact
* ceil 向上取值
* floor向下取值
* round 四舍五入
* pow 求a的b次幂
* random 产生区间[0.0,1.0)的随机数
*/
public class MathTest{
public static void main(String[]args){
System.out.println(Math.abs(-2.34));// 2.34该方法重载 可以返回所有整形的绝对值
int a=-2147483648;
//System.out.println(Math.abs(a));//-2147483648 当没有对应的正数与之对应,答案将错
//System.out.println(Math.absExact(a));2147483648
System.out.println(Math.max(2,3));//返回2个数的最大值
System.out.println(Math.min(-2,-4));//返回2个数的较小值
System.out.println(Math.ceil(9.23));//10.0向上取值
System.out.println(Math.floor(-1.23));//-2.0 向下取值
System.out.println(Math.round(9.51));//10 四色五入返回接近整数的long
System.out.println(Math.pow(2,3));//a的b次方 要求第二个参数尽量传入大于1的整数
System.out.println(Math.sqrt(4));//返回传入数的根号2次方
System.out.println(Math.cbrt(8));//返回传入数的根号3次方
System.out.println(Math.random());//返回[0.0,1.0)的double数
for(int i=0;i<20;i++){
System.out.println((Math.floor(Math.random()*100))+1);//得到0-100的整数
}
}
}
Random类
Random是java.util包中提供的一个专门产生随机数的类
- 常用方法
public Random()构造方法
public boolean nextBoolean()随机产生boolean值
public double nextDouble()随机产生double值
public float nextFloat()随机产生float值
public int nextInt()随机产生int值
public long nextLong()随机产生long值
public int nextInt(int n)随机产生最大值为n的int值
package Test;
import java.util.Random;
public class RandomTest {
public static void main(String[] args) {
Random r=new Random();//实例化对象
//获取[0,10)的随机数,但不包含10
for (int i = 0; i < 10; i++) {
System.out.print(r.nextInt(10)+" ");//9 7 3 7 0 9 6 9 6 1
}
}
}
大数类
BigInteger
我们知道我们的基础数据类型的储存范围是有限的,当我们储存的数据超出了这一范围将会造成数据溢出的现象,从而使得我们的运算造成错误,对于这个问题java提供了BigInteger类和BigDecimal类用于解决整形和浮点型的大数问题
BigInteger类和String类一样具有对象不可变,但是没有String的常量池的特点
构造方法
package Test;
import java.math.BigInteger;
import java.util.Random;
//测试BigInteger类的构造方法
public class BigIntegerTest {
public static void main(String[] args) {
//获取一定范围的随机大整数
Random r1=new Random();
BigInteger b1=new BigInteger(2,r1);//将会获取0-2^2-1的大整数
for (int i = 0; i <10 ; i++) {
System.out.print(b1+" ");//2 2 2 2 2 2 2 2 2 2(对象不可变)
}
//获取指定的大整数
BigInteger b2=new BigInteger("222222222222222222222222222222222222222222");
System.out.println(b2);//222222222222222222222222222222222222222222
//获取指定进制的大整数
BigInteger b3=new BigInteger("100",16);//获取16进制的100
System.out.println(b3);//变成十进制输出
}
}
- 构造方法使用细节
1.构造方法里面的字符串参数,字符串的具体值必须为整形,写成别的类型将会在运行期间报NumberFormatException
2.用构造方法获取指定进制的大整数时,给定的数必须是改进型的数,如2进制数,给定的数必须由0和1构成,要不然也将NumberFormatException**
静态方法获取对象
package Test;
import java.math.BigInteger;
import java.sql.SQLOutput;
import java.util.Random;
//测试BigInteger类的构造方法
public class BigIntegerTest {
public static void main(String[] args) {
BigInteger b = BigInteger.valueOf(13454L);
System.out.println(b);//13454
}
}
构造方法创建对象和静态方法创建对象的比较
1.用valueOf方法只能创建long的范围内的对象
2.静态方法对常用的对象-16-16进行了优化,利用缓冲池提前把-16-16的对象创建好了(和包装类一样)如果创建的对象是在这个范围内的,将直接在缓冲池内寻找相应的对象,而不会直接new
使用建议:
以后创建BigInteger的对象,如果是在long范围之内的建议用静态方法创建,如果超过了long或者不确定对象的大小,用pubilc BigInteger (String val)进行创建
理解BigInteger对象不可变
package Test;
import java.math.BigInteger;
import java.util.Random;
//测试BigInteger类的构造方法
public class BigIntegerTest {
public static void main(String[] args) {
//没有常量池
BigInteger b1=new BigInteger("14");
BigInteger b2=new BigInteger("14");
System.out.println(b1==b2);//false 没有常量池重新new对象
//BigInteger缓冲池
BigInteger b3= BigInteger.valueOf(16L);
BigInteger b4=BigInteger.valueOf(16L);
System.out.println(b3==b4);//true 没有new对象直接在缓冲池里寻找对象
BigInteger b5=BigInteger.valueOf(17L);
BigInteger b6=BigInteger.valueOf(17L);
System.out.println(b5==b6);//超i出-16-16范围 直接new对象
}
}
BigInteger的常用成员方法
BigInteger是一个对象,对象不能直接加减乘除的,对于对象的的计算,我们需要用方法去完成
注意:方法divideAndRemainder方法返回的是一个BigInteger数组数组,索引0表示商,索引1表示余数
注意:在调用 max或者min方法的时候,将不会创建新的对象,将会将较大的或者较小的对象返回
package com.cn.java;
import java.math.BigInteger;
import java.util.Random;
public class BigIntegerTest {
public static void main(String[] args) {
//创建对象:-16-16的对象用静态方法更好
BigInteger r1=BigInteger.valueOf(3);
BigInteger r2=BigInteger.valueOf(4);
//加法
BigInteger r3=r1.add(r2);
System.out.println(r3);
//减法
BigInteger r4=r1.subtract(r2);
System.out.println(r4);
//乘法
BigInteger r5=r1.multiply(r2);
System.out.println(r5);
//除法
BigInteger r6=r2.divide(r1);
System.out.println(r6);
//获取商和余数
BigInteger arr[]=r2.divideAndRemainder(r1);//该方法返回对象数组
System.out.println(arr[0]);//下标为0 为商
System.out.println(arr[1]);//下标为1 为余数
//比较对象时候相同:equals也被BigInteger类重写 比较的是对象
Boolean a=r1.equals(r2);
System.out.println(a);//false 如果数值相同将会返回ture
//次幂:该方法的参数为int型的整数
BigInteger r7=r2.pow(4);
System.out.println(r7);
//max min
BigInteger r8=r1.max(r2);
System.out.println(r8);//4
//该处不会创建新的对象 会将较大的对象进行返回
System.out.println(r8==r1);//false
System.out.println(r8==r2);//true
//将BigInteger变回基本数据类型:但是超出范围将会报错
BigInteger b=BigInteger.valueOf(23);
int i=b.intValue();
}
}
BigDecimal类
double的储存空间很大,但是由于其特殊的储存方式,其留给小数部分的储存空间有限,当一个浮点数的小数部分位数很多时,如果储存不下,将会把超出的部分丢弃,这就造成了数据不精确。而BigDecimal类的出现就是为了解决浮点数的精度问题
计算机会将我们写的数据以二进制的形式储存起来,当我们的小数部分的二进制位数超出了double的范围,将会被舍弃,在将此数据表现出来时,将会造成不精确
在银行等金融行业或一些精密仪器制造行业,会要求数据的准确
注意:对于构造方法public BigDecimal(double val)创建的对象可能还是不精确的,具体缘由参见java文档
- 构造方法演示
package com.cn.java;
import java.math.BigDecimal;
public class BigDecimalTest {
public static void main(String[] args) {
//第一种构造方式:传递double的数值构造出来的对象的数值并不精确
BigDecimal r1=new BigDecimal(0.1);
BigDecimal r2=new BigDecimal(0.09);
//System.out.println(r1);//0.1000000000000000055511151231257827021181583404541015625
//System.out.println(r2);//0.0899999999999999966693309261245303787291049957275390625
//传递字符串进行构造:创建出来的对象精确
BigDecimal r3=new BigDecimal("0.1");
BigDecimal r4=new BigDecimal("0.09");
System.out.println(r3);//0.1
System.out.println(r4);//0.09
System.out.println(r3.add(r4));//0.19
System.out.println(0.09+0.01);//0.09999999999999999与上述代码形成对比 没有用大数对于部分的小数的一些数值将会被舍弃
}
}
通过静态方法创建对象
public BigDecimal valueOf(long val)
public BigDecimal valueOf(double val)
package Test;
import java.math.BigDecimal;
public class BigDecimalTest {
public static void main(String[] args) {
BigDecimal sd1=BigDecimal.valueOf(23L);
BigDecimal sd2 =BigDecimal.valueOf(45.6);
System.out.println(sd1);//23
System.out.println(sd2);//45.6
}
}
细节
1.用double的数值创建对象,的对象数值不精确,以后不建议使用
用String和静态方法创建对象的区别
1.如果要表示的数字不大,没有超过double的取值范围,建议使用静态方法
2.如果我们表示的数值比较大,超出了double的取值范围,建议使用构造方法
3.如果我们传递的数值是0-10的整数,包含0 和10(但是如果传入的是小数也会重新new对象),那么方法会返回已经创建好的对象,不会重新New(具体实现请参见源码)即public BigDecimal valueOf(long val)
**常用方法**
![](https://img2023.cnblogs.com/blog/2942946/202212/2942946-20221217153826433-710702229.png)
package com.cn.java;
import java.math.BigDecimal;
public class BigDecimalTest {
public static void main(String[] args) {
BigDecimal r1=BigDecimal.valueOf(10.0);
BigDecimal r2= BigDecimal.valueOf(2.0);
//加法
BigDecimal r3=r1.add(r2);//12.0
System.out.println(r3);
//减法
BigDecimal r4=r1.subtract(r2);
System.out.println(r4);//8.0
//乘法
BigDecimal r5=r1.multiply(r2);
System.out.println(r5);//20.00
}
}
package com.cn.java;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class BigDecimalTest {
public static void main(String[] args) {
BigDecimal r1=BigDecimal.valueOf(10.0);
BigDecimal r2= BigDecimal.valueOf(3.0);
//除法
// BigDecimal r3= r1.divide(r2);//如果数值为循环小数 用这个方法将会出现异常
//System.out.println(r3);//ArithmeticException
BigDecimal r3=r1.divide(r2,2,BigDecimal.ROUND_HALF_UP);//此时第三个属性为BigDecimal类里面的一个属性
System.out.println(r3);//3.33
//java认为将这种计算的舍入模式写在BigDecimal类中不太好,所以另外编写了枚举为舍入模式
//如下是新的写法
// BigDecimal r3 =r1.divide(r2,2, RoundingMode.HALF_UP);
}
}
关于舍入模式参见文档
和BigDeciaml的底层储存,参考下链接