我们为什么需要Math类与Random类?
当时我开培训机构,教小朋友图形化编程时,大多数家长来咨询都会问:“编程是不是对数学的要求很高?学编程是不是有助于学数学呀?”编程与数学,确实有着很深的联系,特别是编程算法方面。可以简单这么看,数学是理科,编程是工科,数学的理论知识支持着编程的实现。
既然在编程中数学这么重要,所以Java为我们提供了数学类:Math。方便编程开发过程的使用。
随机数问题,是一个数学问题,也可以说是一个哲学问题,上帝掷骰子吗?有兴趣可以看看《上帝掷骰子吗》这本关于量子物理的书。最近“遇事不决,量子力学”这句话也是被少儿量子培训带的相当的火。额,扯远了。关于随机数的问题,Java里没有讨论,但是给我们提供了Random类,让我们可以在程序中产生一个随机数。
Math类
Java 的 Math 包含了用于执行基本数学运算的属性和方法,如初等指数、对数、平方根和三角函数。
Math 的方法都被定义为 static 形式,通过 Math 类可以在主函数中直接调用。
Math常用方法:
方法 | 说明 |
---|---|
long abs(long a) | 取a的绝对值 |
sin\cos\tan\acos\asin | 三角函数 |
double sqrt(double a) | 计算a的平方根 |
double pow(double a, double b) | a的b次方 |
double max(double a, double b) | 取a、b中最大值 |
double min(double a, double b) | 取a、b中最小值 |
double ceil(double a) | 大于a的最小整数 |
double floor(double a) | 小于a的最大整数 |
long round(double a) | 四舍五入,返回值为long型 |
double toRadians(double angdeg) | 角度转弧度 |
double toDegrees(double angrad) | 弧度转角度 |
double random() | 返回0到1的一个随机数 |
使用实例:
public class Test {
public static void main(String[] args) {
System.err.println("π:"+Math.PI);
System.out.println("-5的绝对值:"+Math.abs(-5));
System.out.println("cos0的值:"+Math.cos(0));
System.out.println("sin60°:"+Math.sin(Math.PI/3)); // Math.PI/3 60°
System.out.println("2的平方根:"+Math.sqrt(2));
System.out.println("2的三次方:"+Math.pow(2, 3));
System.out.println("8.25四舍五入:"+Math.round(8.25));
System.out.println("小于8.25的最大整数:"+Math.floor(8.25));
System.out.println("大于8.25的最小整数:"+Math.ceil(8.25));
System.out.println("角度转弧度:"+Math.toRadians(Math.PI));
System.out.println("弧度转角度:"+Math.toDegrees(0.05483113556160755));
System.out.println("生成0到1之间的一个随机数:"+Math.random());
}
}
----------------------------------------------------------------------------
输出结果:
π:3.141592653589793
-5的绝对值:5
cos0的值:1.0
sin60°:0.8660254037844386
2的平方根:1.4142135623730951
2的三次方:8.0
8.25四舍五入:8
小于8.25的最大整数:8.0
大于8.25的最小整数:9.0
角度转弧度:0.05483113556160755
弧度转角度:3.141592653589793
生成0到1之间的一个随机数:0.29750526502240815
今天可能是我使用Math类最多的一天了,一般不会刻意去背这些方法,用的到时再查API或看源码解释就行。
Random类
在Math类当中,其实已经提供了random()方法,提供[0,1)的随机数,我们通过一些数学运算,可以得到任何我们想要的随机数范围。比如得到[10,150)的随机整数:
int a = (int)(Math.random()*140)+10;
如果觉得(int)(Math.random()*140)这样写太麻烦,那Java提供了Random类,调用类中有方法可以直接得到,得到[0,140)的实例:
Random random = new Random();
System.out.println(random.nextInt(140));
Random中还有很多其他方法,用来产生float、double、long等类型的随机数。
需要注意的是,当调用Random带参数的构造器时,相当于定义了一个种子。有相同种子的Random会产生相同的一系列数字,每次调用next时,取下一个数字。所以Java中的随机数都是伪随机数。实例:
public class Test {
public static void main(String[] args) {
Random random = new Random(100);
for (int i = 0; i < 5; i++) {
System.out.println(random.nextInt(10));
}
}
}
------------------------------------------------------
运行结果:
5
0
4
8
1
这个实例,不论怎么执行,结果都是一样。当我们不传入“种子”时,Random就不是伪随机数了吗?不,它还是。不带参数的构造器源码如下:
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
可以看到,不传入“种子”时,会获取一个和系统时间相关的参数作为种子。
其实“随机”这个词很玄妙,现实中有随机吗?现代物理学中认为量子出现的位置是随机的,可再过几百年,这个观点会不会被推翻呢?如果不存在随机,我们将宇宙所有参数和规则,编程为一个系统,是不是可以演算整个宇宙的过去与未来了呢?那如何证明,现在的我们不是正在被计算机演算的产物呢?细思极恐,哈哈,皮一下。