文章目录

  • 1.Math类常用方法
  • 1.1 静态常量
  • 1.2 求最大值、最小值和绝对值
  • 1.3 求整运算
  • 1.4 三角函数运算
  • 1.5 指数运算
  • 2.随机数的使用(Math.random、Random)
  • 2.1 Random类(能产生更多类型随机数)
  • 2.2 Math.random方法(只能产生double类型)
  • 3.控制输出数字的格式(DecimalFormat类)
  • 4.大数字处理(BigInteger、BigDecimal)
  • 4.1 BigInteger 类
  • 4.2 BigDecimal 类


1.Math类常用方法

Java 中的 +、-、*、/ 和 % 等基本算术运算符不能进行更复杂的数学运算,例如,三角函数、对数运算、指数运算等。于是 Java 提供了 Math 工具类来完成这些复杂的运算。

在 Java 中 Math 类封装了常用的数学运算,提供了基本的数学操作,如指数、对数、平方根和三角函数等。Math 类位于 java.lang 包,它的构造方法是 private 的,因此无法创建 Math 类的对象,并且 Math 类中的所有方法都是类方法,可以直接通过类名来调用它们。

1.1 静态常量

Math 类中包含 E 和 PI 两个静态常量,正如它们名字所暗示的,它们的值分别等于 e(自然对数)和 π(圆周率)。

例 1
调用 Math 类的 E 和 PI 两个常量,并将结果输出。代码如下:

System.out.println("E 常量的值:" + Math.E);
System.out.println("PI 常量的值:" + Math.PI);

执行上述代码,输出结果如下:

E 常量的值:2.718281828459045
PI 常量的值:3.141592653589793

1.2 求最大值、最小值和绝对值

在程序中常见的就是求最大值、最小值和绝对值问题,如果使用 Math 类提供的方法可以很容易实现。这些方法的说明如表 1 所示。

java math计算角度 java math._java


例 2

求 10 和 20 的较大值、15.6 和 15 的较小值、-12 的绝对值,代码如下:

public class Test02 {
    public static void main(String[] args) {
        System.out.println("10 和 20 的较大值:" + Math.max(10, 20));
        System.out.println("15.6 和 15 的较小值:" + Math.min(15.6, 15));
        System.out.println("-12 的绝对值:" + Math.abs(-12));
    }
}

该程序的运行结果如下:

10和20的较大值:20
15.6和15的较小值:15.0
-12的绝对值:12

1.3 求整运算

Math 类的求整方法有很多,详细说明如表 2 所示。

方法

说明

static double ceil(double a)

返回大于或等于 a 的最小整数

static double floor(double a)

返回小于或等于 a 的最大整数

static double rint(double a)

返回最接近 a 的整数值,如果有两个同样接近的整数,则结果取偶数

static int round(float a)

将参数加上 1/2 后返回与参数最近的整数

static long round(double a)

将参数加上 1/2 后返回与参数最近的整数,然后强制转换为长整型

例 3
下面的实例演示了 Math 类中取整函数方法的应用:

import java.util.Scanner;
public class Test03 {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.outprintln("请输入一个数字:");
        double num = input.nextDouble();
        System.out.println("大于或等于 "+ num +" 的最小整数:" + Math.ceil(num));
        System.out.println("小于或等于 "+ num +" 的最大整数:" + Math.floor(num));
        System.out.println("将 "+ num +" 加上 0.5 之后最接近的整数:" + Math.round(num));
        System.out.println("最接近 "+num+" 的整数:" + Math.rint(num));
    }
}

执行结果如下:

请输入一个数字:
99.01
大于或等于 99.01 的最小整数:100.0
小于或等于 99.01 的最大整数:99.0
将 99.01 加上 0.5 之后最接近的整数:100
最接近 99.01 的整数:99.0

1.4 三角函数运算

Math 类中包含的三角函数方法及其说明如表 3 所示。

java math计算角度 java math._Math_02

例 4
计算 90 度的正弦值、0 度的余弦值、1 的反正切值、120 度的弧度值,代码如下:

public class Test04 {
    public static void main(String[] args) {
        System.out.println{"90 度的正弦值:" + Math.sin(Math.PI/2));
        System.out.println("0 度的余弦值:" + Math.cos(0));
        System.out.println("1 的反正切值:" + Math.atan(l));
        System.out.println("120 度的弧度值:" + Math.toRadians(120.0));
    }
}

在上述代码中,因为 Math.sin() 中的参数的单位是弧度,而 90 度表示的是角度,因此需要将 90 度转换为弧度,即 Math.PI/180*90,故转换后的弧度为 Math.PI/2,然后调用 Math 类中的 sin() 方法计算其正弦值。

该程序的运行结果如下:

90 度的正弦值:1.0
0 的余弦值:1.0
1 的反正切值:0.7853981633974483
120 度的弧度值:2.0943951023931953

1.5 指数运算

指数的运算包括求方根、取对数及其求 n 次方的运算。在 Math 类中定义的指数运算方法及其说明如表 4 所示。

java math计算角度 java math._Math_03


例 5

使用 Math 类中的方法实现指数的运算,main() 方法中的代码如下:

public class Test05 {
    public static void main(String[] args) {
        System.out.println("4 的立方值:" + Math.pow(4, 3));
        System.out.println("16 的平方根:" + Math.sqrt(16));
        System.out.println("10 为底 2 的对数:" + Math.log1O(2));
    }
}

该程序的运行结果如下:

4 的立方值:64.0
16 的平方根:4.0
10 为底 2 的对数:0.3010299956639812

2.随机数的使用(Math.random、Random)

在 Java 中要生成一个指定范围之内的随机数字有两种方法:一种是调用 Math 类的 random() 方法,一种是使用 Random 类。

2.1 Random类(能产生更多类型随机数)

Random 类提供了丰富的随机数生成方法,可以产生 boolean、int、long、float、byte 数组以及 double 类型的随机数,这是它与 random() 方法最大的不同之处。random() 方法只能产生 double 类型的 0~1 的随机数。

Random 类位于 java.util 包中,该类常用的有如下两个构造方法。

  1. Random():该构造方法使用一个和当前系统时间对应的数字作为种子数,然后使用这个种子数构造 Random 对象。
  2. Random(long seed):使用单个 long 类型的参数创建一个新的随机数生成器。

Random 类提供的所有方法生成的随机数字都是均匀分布的,也就是说区间内部的数字生成的概率是均等的,下面列出了 Random 类中常用的方法。

java math计算角度 java math._Math_04

Demo
下面编写一个 Java 程序,演示如何使用 Random 类提供的方法来生成随机数。具体代码如下:

package java基础;
import java.util.Random;
import java.lang.Math;

public class random_demo {
    public static void main(String[]args){
        Random rng = new Random();//该构造方法使用一个和当前系统时间对应的数字作为种子数,然后使用这个种子数构造 Random 对象。
        int a_int = rng.nextInt(2);//不指定范围产生的数值范围很大,现指定2,即[0,2)不包括2的整数
        System.out.println("无参构造方法产生的随机整数为:(均匀分布)"+a_int);
        double a_double = rng.nextDouble();
        System.out.println("无参构造方法产生的随机双精度的浮点数为:(均匀分布)"+a_double);

        //使用另外的构造方法
        Random rang = new Random(123456);//设置了其他随机种子,发现不加L也行
        int a_int_rang = rng.nextInt(2);//所以产生的随机整数可能与上面的不同。
        System.out.println("有参构造方法产生的随机整数为:(均匀分布)"+a_int_rang);

        //重新设置随机种子
        rang.setSeed( System.nanoTime());//设置为与系统时间对应的数字,得到的Random对象与第一次的对象一致。
        int a_int_ = rng.nextInt(2);//所以产生的随机整数可能与上面的不同。
        System.out.println("重新设置随机种子为系统时间产生的随机整数为:(均匀分布)"+a_int_);
    }

}

java math计算角度 java math._字符串_05

2.2 Math.random方法(只能产生double类型)

Math 类的 random() 方法没有参数,它默认会返回大于等于 0.0、小于 1.0 的 double 类型随机数,即 0<=随机数<1.0。对 random() 方法返回的数字稍加处理,即可实现产生任意范围随机数的功能。

下面使用 random() 方法实现随机生成一个 2~100 偶数的功能。具体代码如下:

public class random_Demo {
    public static void main(String[] args) {
        int min = 2; // 定义随机数的最小值
        int max = 102; // 定义随机数的最大值
        // 产生一个2~100的数
        int s = (int) min + (int) (Math.random() * (max - min));
        if (s % 2 == 0) {
            // 如果是偶数就输出
            System.out.println("随机数是:" + s);
        } else {
            // 如果是奇数就加1后输出
            System.out.println("随机数是:" + (s + 1));
        }
    }
}

由于 m+(int)(Math.random()*n) 语句可以获取 m~m+n 的随机数,所以 2+(int)(Math. random()*(102-2)) 表达式可以求出 2~100 的随机数。在产生这个区间的随机数后还需要判断是否为偶数,这里使用了对 2 取余数,如果余数不是零,说明随机数是奇数,此时将随机数加 1 后再输出。

该程序的运行结果如下:

随机数是:20

3.控制输出数字的格式(DecimalFormat类)

DecimalFormat 是 NumberFormat 的一个子类,用于格式化十进制数字。DecimalFormat 类包含一个模式和一组符号

java math计算角度 java math._Math_06

java math计算角度 java math._字符串_07


Demo

package java基础;

import java.text.DecimalFormat;

/**
 * 需求:练习DecimalFormat如何使用来控制输出的十进制格式
 */

public class decimal_test {
    public static void main(String[]args){
        //首先先创建对象
        DecimalFormat dec = new DecimalFormat();
        int a = 52;
        double d = 12345.66790;
        float f = 12345.444321f;
        System.out.println("dec格式"+dec.format(a));//默认国际标准每3位加,号
        System.out.println("dec格式"+dec.format(d));//默认国际标准每3位加,号,小数部分只支持3位,并且四舍五入。
        System.out.println("dec格式"+dec.format(f));

        //设置格式,使用有参构造函数
        DecimalFormat dec_params = new DecimalFormat("000.00");//只保留2位小数,不足补0
        System.out.println("dec_params:"+dec_params.format(a));//四舍五入
        System.out.println("dec_params:"+dec_params.format(d));//
        System.out.println("dec_params:"+dec_params.format(f));

        /*
        格式的含义:
        0	显示数字,如果位数不够则补 0
        #	显示数字,如果位数不够不发生变化
        .	小数分隔符
        -	减号
        ,	组分隔符
        E	分隔科学记数法中的尾数和小数
        %	前缀或后缀,乘以 100 后作为百分比显示
        ?	乘以 1000 后作为千进制货币符显示。用货币符号代替。如果双写,
         */

        
    }
}

运行结果:

java math计算角度 java math._Math_08


我们使用DecimalFormat对象的format方法来控制数字输出的格式!

4.大数字处理(BigInteger、BigDecimal)

在 Java 中提供了用于大数字运算的类,即 java.math.BigInteger 类和 java.math.BigDecimal 类。这两个类用于高精度计算,其中 BigInteger 类是针对整型大数字的处理类,而 BigDecimal 类是针对(很大或者很小的)数的处理类。

4.1 BigInteger 类

如果要存储比 Integer 更大的数字,Integer 数据类型就无能为力了。因此,Java 中提供 BigInteger 类来处理更大的数字。

BigInteger 类型的数字范围较 Integer 类型的数字范围要大得多。BigInteger 支持任意精度的整数,也就是说在运算中 BigInteger 类型可以准确地表示任何大小的整数值。

除了基本的加、减、乘、除操作之外,BigInteger 类还封装了很多操作,像求绝对值、相反数、最大公约数以及判断是否为质数等。

要使用 BigInteger 类,首先要创建一个 BigInteger 对象。BigInteger 类提供了很多种构造方法,其中最直接的一种是参数以字符串形式代表要处理的数字。这个方法语法格式如下:

BigInteger(String val)//参数是字符串!

这里的 val 是数字十进制的字符串。例如,要将数字 5 转换为 BigInteger 对象,语句如下:

BigInteger bi = new BigInteger("5")

注意:这里数字 5 的双引号是必需的,因为 BigInteger 类构造方法要求参数是字符串类型。

创建 BigInteger 对象之后,便可以调用 BigInteger 类提供的方法进行各种数学运算操作。

BigInteger 类的常用运算方法。

方法名称

说明

add(BigInteger val)

做加法运算

subtract(BigInteger val)

做减法运算

multiply(BigInteger val)

做乘法运算

divide(BigInteger val)

做除法运算

remainder(BigInteger val)

做取余数运算

divideAndRemainder(BigInteger val)

做除法运算,返回数组的第一个值为商,第二个值为余数

pow(int exponent)

做参数的 exponent 次方运算

negate()

取相反数

shiftLeft(int n)

将数字左移 n 位,如果 n 为负数,则做右移操作

shiftRight(int n)

将数字右移 n 位,如果 n 为负数,则做左移操作

and(BigInteger val)

做与运算

or(BigInteger val)

做或运算

compareTo(BigInteger val)

做数字的比较运算

equals(Object obj)

当参数 obj 是 Biglnteger 类型的数字并且数值相等时返回 true, 其他返回 false

min(BigInteger val)

返回较小的数值

max(BigInteger val)

返回较大的数值

Demo
编写一个 Java 程序,将用户输入的数字作为 BigInteger 对象,然后调用该对象的各种方法实现加、减、乘、除和其他运算,并输出结果。具体实现代码如下:

package java基础;

import java.math.BigInteger;
import java.util.Scanner;

/**
 * 目的:实现大数据整数的运算。
 */

public class BigInteger_Test {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入一个整型数字:");
        // 用户输入的数字
        int num = input.nextInt();

        // 使用输入的数字创建BigInteger对象
        BigInteger bi = new BigInteger(num + "");//参数必须为字符串

        // 计算大数字加上99的结果
        System.out.println("加法操作结果:" + bi.add(new BigInteger("99")));

        // 计算大数字减去25的结果
        System.out.println("减法操作结果:" + bi.subtract(new BigInteger("25")));

        // 计算大数字乘以3的结果
        System.out.println("乘法橾作结果:" + bi.multiply(new BigInteger("3")));

        // 计算大数字除以2的结果
        System.out.println("除法操作结果:" + bi.divide(new BigInteger("2")));

        // 计算大数字除以3的商
        System.out.println("取商操作结果:" + bi.divideAndRemainder(new BigInteger("3"))[0]);//返回BigInteger数组,[0]是商,[1]是余数

        // 计算大数字除以3的余数
        System.out.println("取余操作结果:" + bi.divideAndRemainder(new BigInteger("3"))[1]);

        // 计算大数字的2次方
        System.out.println("取 2 次方操作结果:" + bi.pow(2));

        // 计算大数字的相反数
        System.out.println("取相反数操作结果:" + bi.negate());
    }
}

上述代码将用户输入的整型数字保存到 num 变量中,由于 BigInteger 类的构造方法只接收字符串类型的参数,所以使用“new BigInteger(num+"")”代码来创建 BigInteger 对象。接下来的代码演示了如何调用 BigInteger 类提供的运算方法,运行效果下所示。

java math计算角度 java math._数据分析_09


我们来看一下divideAndRemainder函数的定义:

public BigInteger[] divideAndRemainder(BigInteger val) {//返回BigInteger[]数组类型
        if (val.mag.length < BURNIKEL_ZIEGLER_THRESHOLD ||
                mag.length - val.mag.length < BURNIKEL_ZIEGLER_OFFSET) {
            return divideAndRemainderKnuth(val);
        } else {
            return divideAndRemainderBurnikelZiegler(val);
        }
    }
    //divideAndRemainderKnuth
 private BigInteger[] divideAndRemainderKnuth(BigInteger val) {
        BigInteger[] result = new BigInteger[2];
        MutableBigInteger q = new MutableBigInteger(),
                          a = new MutableBigInteger(this.mag),
                          b = new MutableBigInteger(val.mag);
        MutableBigInteger r = a.divideKnuth(b, q);
        result[0] = q.toBigInteger(this.signum == val.signum ? 1 : -1);
        result[1] = r.toBigInteger(this.signum);
        return result;
    }
    //divideAndRemainderBurnikelZiegler
     private BigInteger[] divideAndRemainderBurnikelZiegler(BigInteger val) {
        MutableBigInteger q = new MutableBigInteger();
        MutableBigInteger r = new MutableBigInteger(this).divideAndRemainderBurnikelZiegler(new MutableBigInteger(val), q);
        BigInteger qBigInt = q.isZero() ? ZERO : q.toBigInteger(signum*val.signum);
        BigInteger rBigInt = r.isZero() ? ZERO : r.toBigInteger(signum);
        return new BigInteger[] {qBigInt, rBigInt};//返回的数组类型
    }

4.2 BigDecimal 类

BigInteger 和 BigDecimal 都能实现大数字的运算,不同的是 BigDecimal 加入了小数的概念。一般的 float 和 double 类型数据只能用来做科学计算或工程计算,但由于在商业计算中要求数字精度比较高,所以要用到 BigDecimal 类。BigDecimal 类支持任何精度的浮点数,可以用来精确计算货币值。

BigDecimal 常用的构造方法如下。

BigDecimal(double val):实例化时将双精度型转换为 BigDecimal 类型。
BigDecimal(String val):实例化时将字符串形式转换为 BigDecimal 类型。

BigDecimal 类的方法可以用来做超大浮点数的运算,像加、减、乘和除等。在所有运算中,除法运算是最复杂的,因为在除不尽的情况下,末位小数的处理方式是需要考虑的。

下面列出了 BigDecimal 类用于实现加、减、乘和除运算的方法。

BigDecimal add(BigDecimal augend)    // 加法操作
BigDecimal subtract(BigDecimal subtrahend)    // 减法操作
BigDecimal multiply(BigDecimal multiplieand)    // 乘法操作
BigDecimal divide(BigDecimal divisor,int scale,int roundingMode )    // 除法操作
其中,divide() 方法的 3 个参数分别表示除数、商的小数点后的位数和近似值处理模式。

表 2 列出了 roundingMode 参数支持的处理模式。

模式名称

说明

BigDecimal.ROUND_UP

商的最后一位如果大于 0,则向前进位,正负数都如此

BigDecimal.ROUND_DOWN

商的最后一位无论是什么数字都省略

BigDecimal.ROUND_CEILING

商如果是正数,按照 ROUND_UP 模式处理;如果是负数,按照 ROUND_DOWN模式处理

BigDecimal.ROUND_FLOOR

与 ROUND_CELING 模式相反,商如果是正数,按ROUND_DOWN 模式处理;如果是负数,按照 ROUND_UP 模式处理

BigDecimal.ROUND_HALF_ DOWN

对商进行五舍六入操作。如果商最后一位小于等于 5,则做舍弃操作,否则对最后一位进行进位操作

BigDecimal.ROUND_HALF_UP

对商进行四舍五入操作。如果商最后一位小于 5,则做舍弃操作,否则对最后一位进行进位操作

BigDecimal.ROUND_HALF_EVEN

如果商的倒数第二位是奇数,则按照 ROUND_HALF_UP 处理;如果是偶数,则按照 ROUND_HALF_DOWN 处理

例 2
编写一个 Java 程序,演示如何使用 BigDecimal 类提供的方法对数字执行运算,并输出结果。具体实现代码如下:

import java.math.BigDecimal;
import java.util.Scanner;
public class Test10 {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.println("请输入一个数字:");
        // 保存用户输入的数字
        double num = input.nextDouble();
        // 使用输入的数字创建BigDecimal对象
        BigDecimal bd = new BigDecimal(num);
        // 计算大数字加上99.154的结果
        System.out.println("加法操作结果:" + bd.add(new BigDecimal(99.154)));
        // 计算大数字减去-25.157904的结果
        System.out.println("减法操作结果:" + bd.subtract(new BigDecimal(-25.157904)));
        // 计算大数字乘以3.5的结果
        System.out.println("乘法操作结果:" + bd.multiply(new BigDecimal(3.5)));
        // 计算大数字除以3.14的结果,并保留小数后2位
        System.out.println("除法操作结果(保留 2 位小数):" + bd.divide(new BigDecimal(3.14), 2, BigDecimal.ROUND_CEILING));
        // 计算大数字除以3.14的结果,并保留小数后5位
        System.out.println("除法操作结果(保留 5 位小数):" + bd.divide(new BigDecimal(3.14), 5, BigDecimal.ROUND_CEILING));
    }
}

上述代码将用户输入的数字保存到 num 变量中,然后调用“newBigDecimal(num)”方法来创建 BigDecimal 对象。接下来的代码演示了如何调用 BigDecimal 类提供的运算方法,运行效果如下所示。

请输入一个数字:
100
加法操作结果:199.15399999999999636202119290828704833984375
减法操作结果:125.157903999999998490011421381495893001556396484375
乘法操作结果:350.0
除法操作结果(保留 2 位小数):31.85
除法操作结果(保留 5 位小数):31.84714