数学操作类

  • 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的底层储存,参考下链接

详情参见:https://www.cnblogs.com/swtaa/p/16933888.html

posted @ 2022-12-17 11:45  一往而深,  阅读(48)  评论(0编辑  收藏  举报