引入

众所周知,Math.random()方法可以以double类型等概率返回[0,1)[0,1)上的小数。也就是说,如果xx[0,1)[0,1)范围内的小数,那么[0,x)[0,x)上的数出现的概率是xx

现在提出一个要求:如果xx[0,1)[0,1)范围内的小数,那么[0,x)[0,x)上的数出现的概率调整为x2x^2

思路

原来的概率是xx,现在要求调整为x2x^2,乍一看真的很让人摸不着头脑,但是看到思路的时候可能会有“哦原来是这样的”的感慨。调用一次Math.random()方法,[0,x)[0,x)上的数出现的概率是xx,那再调用一次Math.random()方法,还是落在[0,x)[0,x)上的概率不就成了x2x^2吗?第一步似乎迈了出去。

那这个“还是落在[0,x)[0,x)上”怎么体现呢?这里要用到Math.max()方法,返回两次Math.random()方法结果的最大值,那最大值仍在[0,x)[0,x)上的概率就是x2x^2

代码实现

package com.test;

public class Test {
    public static double xToPower2(){
        return Math.max(Math.random(), Math.random());
    }
    public static void main(String[] args) {
        int count = 0;
        int testTime = 1000000;
        double x = 0.3;
        for(int i = 0; i < testTime; i++){
            if(xToPower2() < x){
                count++;
            }
        }
        System.out.println((double)count / (double)testTime);
        System.out.println(Math.pow(x,2));
    }
}

举一反三

按照这个思路,还可以进行扩展,例如将[0,x)[0,x)上的数出现的概率调整为x3x^3,调用三次Math.random()方法即可。代码实现为:

package com.test;

public class Test {
    public static double xToPower3(){
        return Math.max(Math.random(), Math.max(Math.random(), Math.random()));
    }
    public static void main(String[] args) {
        int count = 0;
        int testTime = 1000000;
        double x = 0.3;
        for(int i = 0; i < testTime; i++){
            if(xToPower3() < x){
                count++;
            }
        }
        System.out.println((double)count / (double)testTime);
        System.out.println(Math.pow(x,3));
    }
}