Java Math.abs 随机与 nextInt()
Posted
技术标签:
【中文标题】Java Math.abs 随机与 nextInt()【英文标题】:Java Math.abs random vs. nextInt() 【发布时间】:2016-08-27 00:00:52 【问题描述】:在 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);
【问题讨论】:
因为你想要一个在 [1, 9] 范围内的整数,你应该使用 rand.nextInt 因为它更好地描述了你的意图。除非您另有了解,否则更具体功能的内部实现往往比从现有功能中组合它们更好。也就是说,Java 是一种编译语言,它利用静态分析通过将 Math.abs(Math.random) 和 random.nextInt 这两种模式规范化为几乎相同的表达式来使大部分决策变得无关紧要。 【参考方案1】:nextInt(n)
在0
和n-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
将有效地“翻转”到-2147483648
。这是因为,当使用有符号整数时,+2147483648
和-2147483648
的二进制补码二进制表示是 完全相同的。然而,这不是问题,因为+2147483648
是 认为超出范围。如需更多了解此问题,您可能需要查看 Wikipedia article on Two's complement.
第一种方法只包含一个罕见的极端情况。这就是为什么最好使用第二个,因为它是安全的。
【讨论】:
你能添加一个解释吗?为什么不是第一个看起来做同样事情的选项? 他没有说Math.abs(Integer.MIN_VALUE)
返回负数是一个错误。他说Math.abs(rand.nextInt()) % 8 + 1
有一个错误,因为Math.abs(Integer.MIN_VALUE)
可以(正确)返回负数。
@shmosel 我的错。我不是以英语为母语的人。【参考方案2】:
Math.abs(rand.nextInt()) % 8 + 1;
这有一个微妙的错误。 Math.abs(Integer.MIN_VALUE) 返回负数 MIN_VALUE。一个更简单的解决方案是
(rand.nextInt() & 7) + 1;
这将始终是非负的,并且会稍微快一些。
rand.nextInt(8) + 1
这既更快,但更重要的是,更清楚您想要实现的目标。出于后一个原因,与其单靠速度,它是更好的选择。
注意:如果你真的想要这个,你可以使用abs
。但是,这不像nextInt
调用那样干净。
Math.abs(rand.nextInt() % 8) + 1;
【讨论】:
【参考方案3】:问题来了:
int num1 = Math.abs(rand.nextInt()) % 8 + 1;
意味着您将首先从“所有 2^32 个可能的 int 值以(大约)相等的概率产生”中选择一个数字,然后您将答案修改为 8。因为,我们使用的是 Math.abs() ,一个问题是它可能返回一个负数。
int num2 = rand.nextInt(8) + 1;
不过,这个版本不会返回负数,而是会返回一个从 0 到 8 的数字。
这两种代码都适合实现您想要做的事情。然而,第二行代码更利于记忆,在第一个版本中最坏的情况是你必须记住一个数字 2^32。但是,您不必为第二个版本。另一件事是,因为我们必须使用更少的方法和更少的计算,所以第二种方法会快很多。总而言之,这两种方法都有效,但第二个版本是最好的版本,因为它占用的内存更少,整体速度更快。
【讨论】:
以上是关于Java Math.abs 随机与 nextInt()的主要内容,如果未能解决你的问题,请参考以下文章