Math.random()与Random.nextInt(int)
Math.random() * n
和Random.nextInt(n)
之间的区别是什么,其中n
是一个整数?
下面是为什么“ Random.nextInt(n)
比太阳论坛帖子中的Math.random() * n
”更有效率和更少偏见的详细解释 ,Gili链接到:
Math.random()在内部使用Random.nextDouble()。
Random.nextDouble()使用Random.next()两次生成一个在其尾数大致均匀分布的double,所以它在0到1-(2 ^ -53)范围内均匀分布。
Random.nextInt(n)使用Random.next()平均少于两次 – 它使用一次,如果获得的值高于MAX_INT下的n的最高倍数,则再次尝试,否则返回模n的值(this防止MAX_INT下的n的最高倍数以上的值偏斜分布),所以返回一个均匀分布在0到n-1范围内的值。
在缩放6之前,Math.random()的输出是从均匀分布中绘制的2 ^ 53个可能值中的一个。
通过6进行缩放不会改变可能值的数量,并将其转换为int,然后将这些值强制为六个“桶”(0,1,2,3,4,5)中的一个,每个桶对应于包含1501199875790165或1501199875790166的可能值(因为6不是2 ^ 53的disvisor)。 这意味着,对于足够数量的骰子卷(或者具有足够多的边的骰子)来说,骰子将表现为偏向较大的骰子。
你会等待很长一段时间,这个效果才会出现。
Math.random()也需要约两倍的处理时间,并且需要同步。
另一个重要的一点是Random.nextInt(n)是可重复的,因为你可以用相同的种子创建两个Random对象。 这是Math.random()不可能的。
根据https://forums.oracle.com/forums/thread.jspa?messageID=6594485 Random.nextInt(n)
比Math.random() * n
更有效率,
根据这个例子, Random.nextInt(n)
具有较少的可预测的输出,然后Math.random()* n。 根据[排序阵列比未排序数组快] [1]我认为我们可以说Random.nextInt(n) 很难预测 。
usingRandomClass:time: 328 milesecond。
usingMathsRandom:time: 187 milesecond。
package javaFuction; import java.util.Random; public class RandomFuction { static int array[] = new int[9999]; static long sum = 0; public static void usingMathsRandom() { for (int i = 0; i < 9999; i++) { array[i] = (int) (Math.random() * 256); } for (int i = 0; i < 9999; i++) { for (int j = 0; j < 9999; j++) { if (array[j] >= 128) { sum += array[j]; } } } } public static void usingRandomClass() { Random random = new Random(); for (int i = 0; i < 9999; i++) { array[i] = random.nextInt(256); } for (int i = 0; i < 9999; i++) { for (int j = 0; j < 9999; j++) { if (array[j] >= 128) { sum += array[j]; } } } } public static void main(String[] args) { long start = System.currentTimeMillis(); usingRandomClass(); long end = System.currentTimeMillis(); System.out.println("usingRandomClass " + (end - start)); start = System.currentTimeMillis(); usingMathsRandom(); end = System.currentTimeMillis(); System.out.println("usingMathsRandom " + (end - start)); } }