Java随机给出负数 [英] Java Random giving negative numbers
问题描述
我遇到Javas 随机
类的问题,如果我这样做:
I'm having trouble with Javas Random
class, if i do this:
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
据我所读这应该只是为了一个开始返回正数?
From what I have read this should only be returning positive numbers for a start?
这可能有点牵强但它无法与在Windows 7 64上运行64位机器有任何关系比特?
This may be a bit far fetched but it couldnt have anything to do with running a 64 bit machine on Windows 7 64 bit?
任何帮助都是非常需要今天完成任务的完成!
Any help at all would be awesome need to get this finished for an assignment hand in today!
推荐答案
来自 的Java文档nextInt()
:
所有2 32 可能的int值以(近似)相等的概率产生。
All 232 possible int values are produced with (approximately) equal probability.
On方法是使用以下转换:
One approach is to use the following transform:
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
映射到零,可以将零概率与正整数对齐。
The reason something like this is needed (as opposed to using absolute value or negation) is that Integer.MIN_VALUE
is too large in absolute value to be turned into a positive integer. That is, due to overflow, Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE
and Integer.MIN_VALUE == -Integer.MIN_VALUE
. The above transformation preserves the approximately uniform distribution property: if you wrote a generate-and-test loop that just threw away Integer.MIN_VALUE
and returned the absolute value of everything else, then the positive integers would be twice as likely as zero. By mapping Integer.MIN_VALUE
to zero, that brings the probability of zero into line with the positive integers.
这里是另一种方法,实际上可能更快一点(虽然我没有对它进行基准测试):
Here is another approach, which may actually be a tiny bit faster (although I haven't benchmarked it):
int s = rng.next(Integer.SIZE - 1); // Integer.SIZE == 32
这将生成一个包含31个随机低位的整数(和0作为32 nd 位,保证非负值)。但是(正如jjb的评论中指出的那样),因为 next(int)
是一个 protected
方法随机
,你必须继承 Random
来公开方法(或为方法提供合适的代理): / p>
This will generate an integer with 31 random low-order bits (and 0 as the 32nd bit, guaranteeing a non-negative value). However (as pointed out in the comment by jjb), since next(int)
is a protected
method of Random
, you'll have to subclass Random
to expose the method (or to provide a suitable proxy for the method):
public class MyRandom extends Random {
public MyRandom() {}
public MyRandom(int seed) { super(seed); }
public int nextNonNegative() {
return next(Integer.SIZE - 1);
}
}
另一种方法是使用 ByteBuffer
包装一个4字节的数组。然后,您可以生成一个随机的四个字节(通过调用 nextBytes(byte [])
),将符号位置零,然后将该值读作 INT
。我不相信这提供了超过上述任何优势,但我想我会把它扔出去。它与我的第一个解决方案基本相同(使用 Integer.MAX_VALUE
进行掩码)。
Another approach is to use a ByteBuffer
that wraps a 4-byte array. You can then generate a random four bytes (by calling nextBytes(byte[])
), zero out the sign bit, and then read the value as an int
. I don't believe this offers any advantage over the above, but I thought I'd just throw it out there. It's basically the same as my first solution (that masks with Integer.MAX_VALUE
).
在早期版本的这个答案,我建议使用:
In an earlier version of this answer, I suggested using:
int s = rng.nextInt(Integer.MAX_VALUE);
然而,根据文档这将生成0(含)到范围内的整数Integer.MAX_VALUE
(不包括)。换句话说,它不会生成值 Integer.MAX_VALUE
。另外,事实证明 next(int)
总是比 nextInt(int)
更快。
However, according to the docs this will generate integers in the range 0 (inclusive) to Integer.MAX_VALUE
(exclusive). In other words, it won't generate the value Integer.MAX_VALUE
. In addition, it turns out that next(int)
is always going to be faster than nextInt(int)
.
这篇关于Java随机给出负数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!