在一个范围内生成一个随机数。无溢出。在 Java 中
Posted
技术标签:
【中文标题】在一个范围内生成一个随机数。无溢出。在 Java 中【英文标题】:Generating a random number within a range. Without Overlflow. In Java 【发布时间】:2014-05-18 00:33:51 【问题描述】:请不要将此视为与以下内容的重复: How to generate random positive and negative numbers in java
我需要使用带有种子的随机数生成器。所以,我使用了 java.util.Random 类和带有种子的 constructor。
Random random = new Random(System.currentTimeMillis());
然后我使用了上面线程中给出的解决方案
int randomValue = random.nextInt(max - min + 1) + min;
但是,上述方案的问题是,如果min是一个很大的负数,max是一个很大的正数,那么(max - min + 1)会导致溢出。
应该有更好的解决方案。谁能指点我。
谢谢!
【问题讨论】:
确实是重复的除非您提供更多信息。 您好 devnull,我确实提供了为什么它不是重复的信息。原因是 (max - min + 1) 可能导致溢出。 @devnull:除非我弄错了,否则链接的答案不会涉及涉及Integer.MIN_VALUE
和Integer.MAX_VALUE
的假设情况,这看起来是一个有效的问题。
您可以将 max - min + 1 的结果分配给一个名为 range 的变量。然后使用 if 语句检查范围是否为负数或太大或任何导致溢出的原因
我强烈建议您学习 java.util.Random
的 Javadoc 和源代码。那里有丰富的信息可以让你轻松处理这个问题。如果max
和min
是int
s,那么max-min
必须 适合long
,而您真正想要做的就是生成64 个随机位,然后使用来自nextInt()
的技术应用于生成long
值。
【参考方案1】:
如何使用BigInteger
来避免int
溢出。你也可以使用
new BigInteger(int numBits, Random rnd)
用随机位创建一些BigInteger
(直到numBits
指定的位)。
所以只需计算您需要多少位(range.bitLength()
可能有用)检查随机值是否在指定范围内,因此如果值再次大于随机范围,如果一切正常,则返回随机值增加 min
.
这是一些代码示例
public static int myRandom(int min, int max, Random r)
if (max <= min)
throw new RuntimeException("max value must be greater than min value: max="+max +", min="+min);
BigInteger maxB = BigInteger.valueOf(max);
BigInteger minB = BigInteger.valueOf(min);
BigInteger range = maxB.subtract(minB);
do
BigInteger result = new BigInteger(range.bitLength(), r);
if (result.compareTo(range)<=0)
return result.add(minB).intValueExact();
while(true);
【讨论】:
生成的随机函数可能不统一。 @assylias 我不确定我是否理解你所说的制服是什么意思(我不是以英语为母语的人:/),但从我在BigInteger(int numBits, Random rnd) constructor“... 均匀分布在 0 到 (2^numBits - 1) 的范围内,所以您能多说一下这段代码的问题吗?我真的犯了什么错误吗? "如果值再次大于随机范围" =>您可能会通过这样做在分布中引入偏差。不过,这对 OP 来说可能不是问题。以上是关于在一个范围内生成一个随机数。无溢出。在 Java 中的主要内容,如果未能解决你的问题,请参考以下文章