4

我知道还有另一个关于随机范围内的问题,但他们的答案都没有完成我想要做的事情。实际上他们有同样的错误。我编写了这个简单的函数来生成随机范围。

Random m_random = new Random();
...
public int RandomWithRange(int min, int max) {
    return m_random.nextInt(max - min + 1) + min;
}

如果范围大于 Integer.MAX_VALUE,则抛出 IllegalArgumentException:n 必须为正。我知道它溢出并变成负数。我的问题是如何处理?

示例范围;

  • [0, 整数.MAX_VALUE]
  • [整数.MIN_VALUE,整数.MAX_VALUE]
  • [-100,整数.MAX_VALUE]

注意: min 和 max 必须包含在内。

4

4 回答 4

6

在这种情况下,您不能使用 int。您需要使用BigInteger。以下构造函数可以满足您的需求(当然需要根据您的需要进行一些调整):

BigInteger(int numBits, Random rnd) 

构造一个随机生成的 BigInteger,均匀分布在 0 到 (2numBits - 1) 的范围内,包括 0 到 (2numBits - 1)。

于 2012-05-27T11:31:15.940 回答
4

您遇到的问题是(max - min)溢出并给您一个负值。

您可以使用 along代替。

public int randomWithRange(int min, int max) {
    return (int) ((m_random.nextLong() & Long.MAX_VALUE) % (1L + max - min)) + min;
}
于 2012-05-27T11:40:38.453 回答
2

您是否考虑过获得随机双精度然后再转换回 int

return (int)(m_random.nextDouble() * ((double)max - (double)min) + min);
于 2012-05-27T11:33:51.587 回答
0

我能想到的最“愚蠢但绝对正确”的解决方案:

if (max - min + 1 > 0) // no overflow
  return delta + random.nextInt(max - min + 1);
else {
  int result;
  do {
    result = random.nextInt();
  } while (result < min || result > max);
  // finishes in <= 2 iterations on average
  return result;
}
于 2012-05-27T11:41:42.393 回答