![](/img/trans.png)
[英]Random negative number when converting numbers from string to int in Java
[英]Java Random giving negative numbers
我在使用 Java Random
class 時遇到問題,如果我這樣做:
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 位機器沒有任何關系?
任何幫助都將是非常棒的,需要完成今天的作業!
所有 2 32 個可能的 int 值都是以(大約)相等的概率產生的。
一種方法是使用以下變換:
s = rng.nextInt() & Integer.MAX_VALUE; // zero out the sign bit
需要這樣的東西(而不是使用絕對值或否定)的原因是Integer.MIN_VALUE
的絕對值太大而無法轉換為正 integer。 也就是說,由於溢出, Math.abs(Integer.MIN_VALUE) == 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 個隨機低位的integer (第 32 位為 0,保證非負值)。 但是(正如 jjb 在評論中指出的那樣),由於next(int)
是Random
的protected
方法,因此您必須將Random
子類化以公開該方法(或為該方法提供合適的代理):
public class MyRandom extends Random {
public MyRandom() {}
public MyRandom(int seed) { super(seed); }
public int nextNonNegative() {
return next(Integer.SIZE - 1);
}
}
另一種方法是使用包裝 4 字節數組的ByteBuffer
。 然后,您可以生成一個隨機的四個字節(通過調用nextBytes(byte[])
),將符號位清零,然后將值讀取為int
。 我不相信這比上述有任何優勢,但我想我會把它扔在那里。 它與我的第一個解決方案基本相同(使用Integer.MAX_VALUE
進行掩碼)。
在此答案的早期版本中,我建議使用:
int s = rng.nextInt(Integer.MAX_VALUE);
但是,根據文檔,這將生成 0(含)到Integer.MAX_VALUE
(不含)范圍內的整數。 換句話說,它不會生成值Integer.MAX_VALUE
。 此外,事實證明next(int)
總是比nextInt(int)
快。
由於正數或負數的機會均等,為什么不只是:
Math.abs(rand.nextInt())
好,易於!
允許使用負數 - 也許您已經閱讀過類似的 Random 方法nextInt( int ) ,它確實將返回值限制為 0 或更大。
查看 java.util.Random 的文檔:
http://download.oracle.com/javase/6/docs/api/java/util/Random.html
您是否要獲取 0 到 28 之間的隨機數? 如果是這樣,您需要使用前面提到的 nextInt(int)。 種子與可能輸出的范圍或其相對可能性無關。
int s = rng.nextInt(bound); //bound 29 in this case
這將具有0到29的界限。
如果您碰巧使用可能具有負值的數字,您可以使用條件聲明自動將其轉換為正值,方法是將值乘以負值。 您也可以使用相同的方法將正值變為負值。
示例如下。
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;
根據文檔http://download.oracle.com/javase/6/docs/api/java/util/Random.html#nextInt ():
從該隨機數生成器的序列中返回下一個偽隨機、均勻分布的 int 值。 nextInt 的一般約定是偽隨機生成並返回一個 int 值。 所有 2^32 個可能的 int 值都是以(大約)相等的概率產生的。
如果值為負,只需乘以 -1
您還可以使用Math.random()返回 0 到 1 之間的值
int randomNumber = new Random().newInt(10);
這將返回一個介於 0 和 9 之間的隨機數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.