Java Math.abs random vs.nextInt()

Java Math.abs random vs.nextInt(),java,random,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;

在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);

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

所以在1到8之间

int num2 = rand.nextInt(8) + 1;
这意味着你的第二个就是你需要的


更新:

Math.abs(Integer.MIN\u值)
返回负值

根据SO:

Integer.MIN_值为-2147483648
,但最高值为32位 整数可以包含is
+2147483647
。试图代表 32位整数中的
+2147483648
将有效地“滚动”到
-2147483648
。这是因为,当使用有符号整数时,
+2147483648
-2147483648
的两个补码二进制表示是 完全相同的但是,这不是问题,正如
+2147483648
所示 被认为超出范围

关于这件事的更多阅读,你可能想看看

第一个方法只包含一个罕见的角案例。这就是为什么最好使用第二个,因为它是安全的

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

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

(rand.nextInt() & 7) + 1;
这将始终是非负的,并且会稍微快一点

兰德耐克斯汀(8)+1

这不仅更快,而且更重要的是,更清楚地知道你想要实现什么。出于后一个原因,这是一个更好的选择,而不仅仅是速度

注意:如果您真的喜欢,可以使用
abs
。但是,这并不像
nextInt
调用那样干净

Math.abs(rand.nextInt() % 8) + 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。但是,对于第二个版本,您不必这样做。另一件事是,因为我们必须使用更少的方法和更少的计算,第二种方法会快得多。总而言之,这两种方法都有效,但第二种方法是最好的,因为它占用的内存更少,整体速度更快。

你能补充一个解释吗?为什么第一种方法不起同样的作用?他没有说
Math.abs(Integer.MIN\u VALUE)
返回负数是一个错误。他说
Math.abs(rand.nextInt())%8+1
有一个错误,因为
Math.abs(Integer.MIN\u VALUE)
可以(正确地)返回负数。@shmosel my bad。我不是以英语为母语的人。因为你想要一个[1,9]范围内的整数,所以你应该使用rand.nextInt,因为它能更好地描述你的意图。除非您知道其他情况,否则更具体函数的内部实现往往比从现有函数中组合它们要好。也就是说,Java是一种编译语言,它利用静态分析将两种模式Math.abs(Math.random)和random.nextInt规范化为几乎相同的表达式,从而使这些决策变得无关。