簡體   English   中英

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 位機器沒有任何關系?

任何幫助都將是非常棒的,需要完成今天的作業!

來自nextInt()的 Java 文檔

所有 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_VALUEInteger.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)Randomprotected方法,因此您必須將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

這將具有029的界限。

如果您碰巧使用可能具有負值的數字,您可以使用條件聲明自動將其轉換為正值,方法是將值乘以負值。 您也可以使用相同的方法將正值變為負值。

示例如下。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM