Java随机给定负数

Java随机给定负数,java,random,Java,Random,我在JavaRandom类中遇到了问题,如果我这样做: 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";

我在Java
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";
        }
据我所知,这应该只是返回正数作为开始

这可能有点牵强,但它与在Windows 7 64位上运行64位计算机没有任何关系


任何帮助都将是了不起的,需要完成这项任务,今天就交上来

允许负数-可能您已经阅读过类似的随机方法,该方法将返回值限制为零或更大。

来自:

所有232个可能的int值以(近似)相等的概率产生

一种方法是使用以下转换:

s =  rng.nextInt() & Integer.MAX_VALUE; // zero out the sign bit
需要这样做的原因(与使用绝对值或求反相反)是
Integer.MIN\u value
的绝对值太大,无法转换为正整数。也就是说,由于溢出,
Math.abs(Integer.MIN\u值)==Integer.MIN\u值
Integer.MIN\u值==-Integer.MIN\u值
。上面的转换保留了近似均匀分布的属性:如果您编写了一个生成和测试循环,该循环刚刚丢弃了
Integer.MIN_VALUE
,并返回了所有其他值的绝对值,那么正整数的可能性将是零的两倍。通过将
Integer.MIN_值
映射为零,使零概率与正整数一致

这里是另一种方法,实际上可能快一点(尽管我还没有对其进行基准测试):

这将生成一个包含31个随机低阶位的整数(0作为第32位,保证非负值)。但是(正如jjb在评论中指出的那样),由于
next(int)
受保护的
随机
方法,您必须将
随机
子类化以公开该方法(或为该方法提供合适的代理):

另一种方法是使用包装4字节数组的
ByteBuffer
。然后,您可以生成一个随机的四个字节(通过调用
nextBytes(byte[])
),将符号位置零,然后将该值读取为
int
。我不认为这比上面提到的有任何优势,但我想我还是放弃吧。它与我的第一个解决方案基本相同(即使用
Integer.MAX_VALUE
屏蔽)

在这个答案的早期版本中,我建议使用:

int s = rng.nextInt(Integer.MAX_VALUE);
但是,根据此命令,将生成0(包括)到
Integer.MAX_VALUE
(排除)范围内的整数。换句话说,它不会生成值
Integer.MAX\u value
。此外,根据文档(),
next(int)
总是比
nextInt(int)
快:

返回此随机数生成器序列中的下一个伪随机、均匀分布的int值。nextInt的一般约定是伪随机生成并返回一个int值。所有2^32个可能的int值以(近似)相等的概率产生


如果值为负数,只需乘以-1即可。您还可以使用它返回0到1之间的值。查看java.util.Random的文档:

你想得到0到28之间的随机数吗?如果是这样,您需要使用前面提到的nextInt(int)。种子与可能产出的范围或其相对可能性无关

int s = rng.nextInt(bound); //bound 29 in this case

这将有一个029

的范围,因为正数或负数的概率相等。为什么不:

Math.abs(rand.nextInt())

又好又简单

如果您使用的数字可能有负值,您可以使用条件声明将其自动转换为正值,方法是将该值乘以负值。也可以使用相同的方法将正值转换为负值

下面是一些例子

int a = -5;
a = a < 0? ( a == -2147483648? 0 : -a ) 
           : a;

int b = -2147483648;
b = b < 0? ( b == -2147483648? 0 : -b ) 
           : b;

int c = 12345;
c = c < 0? ( c == -2147483648? 0 : -c ) 
           : c;
inta=-5;
a=a<0?(a==-2147483648?0:-a)
:a;
INTB=-2147483648;
b=b<0?(b==-2147483648?0:-b)
:b;
int c=12345;
c=c<0?(c==-2147483648?0:-c)
:c;

这将返回一个介于0和9之间的随机数。

只相信您在javadocs中读到的内容。(当然)阅读javadocs.Note
Math.abs
一次也不能用。(祝您测试顺利。提示:不要使用静态可变对象。)乘以-1不是一个好主意。首先,它不起作用:
Integer.MIN\u VALUE
的求反再次是
Integer.MIN\u VALUE
(由于溢出),因此无法通过这种方式消除所有负数。即使它确实起作用,结果也会是一个非均匀分布:零的概率是任何正整数的一半。不过,Random.next()是受保护的,所以不能直接调用它。您可以将Random子类化,并公开类似于nextPositiveInt()的内容,它可以很容易地返回next(31)。
Integer.SIZE-1
会稍微好一点。@CiroSantilli六四事件法轮功纳米比亚胡海峰 - 是的,这会让我们更清楚价值来自何方。我将相应地更新我的答案。
(-1)>>1
只是
整数。最大值
?我可以只使用
rng.nextInt()&Integer.MAX\u VALUE
,或者我遗漏了什么?@aldok-正确。正如我在回答中所解释的,这是一件好事,因为这意味着0的出现频率(大致)与任何正整数值的出现频率相同。(无论是使用secure random还是java.util.random都是如此。)正如Ted所提到的,
nextInt(Integer.MAXVALUE)
省略了
Integer.MAXVALUE
,因此它有点像明显的
Math.abs
一样好,它得到了一个错误的值(
Integer.MAXVALUE
)。这是行不通的。请注意,如果参数等于
Integer.MIN_value
的值,则最负的表示为
int s = rng.nextInt(bound); //bound 29 in this case
Math.abs(rand.nextInt())
int a = -5;
a = a < 0? ( a == -2147483648? 0 : -a ) 
           : a;

int b = -2147483648;
b = b < 0? ( b == -2147483648? 0 : -b ) 
           : b;

int c = 12345;
c = c < 0? ( c == -2147483648? 0 : -c ) 
           : c;
int randomNumber = new Random().newInt(10);