Java Math.abs随机与nextInt()

时间:2016-08-27 00:00:52

标签: java random

用Java创建一个随机数生成器 - 查看num1和num2,在哪些实例中我会使用这些方法之一来创建1到8之间的随机数?一个比另一个更有效,还有其他任何好处吗?

import java.util.*;

public class Chpt3 {
  public static void main(String[] args) {
    Random rand = new Random();
    int num1 = Math.abs(rand.nextInt()) % 8 + 1;
    int num2 = rand.nextInt(8) + 1;
    System.out.println(num1);
    System.out.println(num2);

  }
}

3 个答案:

答案 0 :(得分:6)

nextInt(n)0n-1之间返回。

所以要在1到8之间,

int num2 = rand.nextInt(8) + 1;

这意味着你的第二个就是你需要的那个。

<强>更新

Math.abs(Integer.MIN_VALUE)返回负值。

根据this answer SO:

  

Integer.MIN_VALUE is -2147483648,但最高值为32位   整数可以包含+2147483647。试图代表   32位int中的+2147483648将有效地&#34;翻转&#34;到-2147483648。这是因为,当使用有符号整数时,+2147483648-2147483648的二进制补码表示为+2147483648(rand.nextInt() & 7) + 1; 。   相同。但是,这不是问题,因为abs是。{1}}   被认为超出范围。

     

如果想了解更多这方面的内容,您可能需要查看   Wikipedia article on Two's complement.

第一种方法只包含一个罕见的角落案例。这就是为什么使用第二个更安全的原因。

答案 1 :(得分:5)

  

Math.abs(rand.nextInt())%8 + 1;

这有一个微妙的错误。 Math.abs(Integer.MIN_VALUE)返回MIN_VALUE,这是一个负数。一个更简单的解决方案是

nextInt

这将始终是非负面的并且稍快一些。

  

rand.nextInt(8)+ 1

这更快,但更重要的是,更清楚你要实现的目标。由于后来的原因,它不是单独的速度,而是更好的选择。

注意:如果您真的想要这样,可以使用Math.abs(rand.nextInt() % 8) + 1; 。但是,这并不像{{1}}电话一样干净。

{{1}}

答案 2 :(得分:1)

问题在于:

int num1 = Math.abs(rand.nextInt()) % 8 + 1;

意味着您将首先从“所有2 ^ 32个可能的int值以(近似)相等的概率生成”中选择一个数字,然后您将修改答案为8.因为,我们正在使用Math.abs()一个问题是它可能会返回一个负数。

 int num2 = rand.nextInt(8) + 1;

但是,此版本不会返回负数,并会返回0到8之间的数字。

这两个代码都适合实现您的目标。但是,第二行代码对于内存会更好,在第一个版本中,最坏的情况是你必须记住一个数字2 ^ 32。但是,您不必为第二个版本。另一件事是因为我们必须使用更少的方法和更少的计算,第二种方法将更快。总而言之,这两种方法都有效,但第二版是最好的版本,因为它占用的内存更少,整体速度更快。