我遇到Javas Random
课时遇到问题,如果我这样做的话:
Random rng = new Random(seed) // seed == 29 in this example
String ss = "";
for(int i = 0; i < 10; i++)
{
int s = rng.nextInt();
ss += Integer.toString(s);
ss +="\n";
}
这就是我的回忆:
-1169335537
-2076183625
1478047223
1914482305
722089687
2094672350
-1234724057
-1614953544
-321574001
1000360613
根据我的阅读,这只应该返回正数才能开始?
这可能有点牵强,但它与在Windows 7 64位上运行64位机器无关?
任何帮助都是非常需要今天完成任务的完成!
答案 0 :(得分:59)
所有2 32 可能的int值以(近似)相等的概率产生。
一种方法是使用以下转换:
s = rng.nextInt() & Integer.MAX_VALUE; // zero out the sign bit
需要这样的东西(与使用绝对值或否定相反)的原因是Integer.MIN_VALUE
的绝对值太大而无法变成正整数。也就是说,由于溢出,Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE
和Integer.MIN_VALUE == -Integer.MIN_VALUE
。上面的转换保留了近似均匀的分布属性:如果你编写了一个只丢弃Integer.MIN_VALUE
的生成和测试循环并返回其他所有内容的绝对值,那么正整数将是零的两倍。通过将Integer.MIN_VALUE
映射到零,可以使零概率与正整数成一致。
这是另一种方法,实际上可能会更快一点(虽然我没有对它进行基准测试):
int s = rng.next(Integer.SIZE - 1); // Integer.SIZE == 32
这将生成一个包含31个随机低位的整数(0为32 nd 位,保证非负值)。但是(正如jjb的评论中所指出的),由于next(int)
是protected
的{{1}}方法,因此您必须将Random
子类化以公开该方法(或为该方法提供合适的代理):
Random
另一种方法是使用包含4字节数组的public class MyRandom extends Random {
public MyRandom() {}
public MyRandom(int seed) { super(seed); }
public int nextNonNegative() {
return next(Integer.SIZE - 1);
}
}
。然后,您可以生成随机的四个字节(通过调用ByteBuffer
),将符号位置零,然后将该值读取为nextBytes(byte[])
。我不相信这提供了超过上述任何优势,但我想我会把它扔出去。它与我的第一个解决方案基本相同(用int
掩盖。)
在这个答案的早期版本中,我建议使用:
Integer.MAX_VALUE
然而,根据the docs,这将生成0(包括)到int s = rng.nextInt(Integer.MAX_VALUE);
(不包括)范围内的整数。换句话说,它不会生成值Integer.MAX_VALUE
。此外,事实证明Integer.MAX_VALUE
总是比next(int)
更快。
答案 1 :(得分:13)
由于正数或负数的概率相等,为什么不只是:
Math.abs(rand.nextInt())
很好,很容易!
答案 2 :(得分:8)
允许使用负数 - 也许您已经读过类似的随机方法nextInt( int ),其中 将返回值限制为零或更大。
答案 3 :(得分:1)
查看java.util.Random的文档:
http://download.oracle.com/javase/6/docs/api/java/util/Random.html
你是否想要从0到28获得随机数?如果是这样,您需要使用前面提到的nextInt(int)。种子与可能的产出范围或其相对可能性无关。
答案 4 :(得分:0)
根据文档http://download.oracle.com/javase/6/docs/api/java/util/Random.html#nextInt():
从此随机数生成器的序列中返回下一个伪随机数,均匀分布的int值。 nextInt的一般契约是伪随机生成并返回一个int值。所有2 ^ 32个可能的int值都以(近似)相等的概率生成。
如果值为负
,则乘以-1答案 5 :(得分:0)
您还可以使用Math.random()返回0到1之间的值
答案 6 :(得分:0)
int s = rng.nextInt(seed); //seed 29 in this case
这将 0 绑定到 29 。
答案 7 :(得分:0)
如果您碰巧使用可能具有负值的数字,您可以通过将值乘以负值自动使用条件声明将其转换为正值。您也可以使用相同的方法将正值转换为负值。
示例如下。
// Turn a negative value into its positive correspondent value.
// If the value is already a positive value, nothing will happen to it.
int a = -5;
a = a < 0? a * -1 : a;
// Turn a positive value into its negative correspondent value.
// If the value is already a negative value, nothing will happen to it.
int b = 5;
b = b > 0? b * -1 : b;
答案 8 :(得分:0)
int randomNumber = new Random().newInt(10);
这将返回0到9之间的随机数。