質問

ジョージMarsaglia書に優れた乱数ジェネレータが非常に速く、簡単に、より高い期間以外はメルセンヌツイスター.こちらのコードの記述:

良いC乱数ジェネレータ

たいと思ったポートのCMWC4096コードへのJavaが、複数の符号なしデータ型で、私にしています。ここでは、フルのCコード:

/* choose random initial c<809430660 and */
/* 4096 random 32-bit integers for Q[]   */
static unsigned long Q[4096],c=362436;

unsigned long CMWC4096(void) {
    unsigned long long t, a=18782LL;
    static unsigned long i=4095;
    unsigned long x,r=0xfffffffe;
    i = (i+1) & 4095;
    t = a*Q[i] + c;
    c = (t>>32);
    x = t + c;
    if (x < c) {
        x++;
        c++;
    }
    return (Q[i] = r - x);
}

誰でもできるのでポートするJava?どのようなこのときのみが署名した番号を利用できますか?

編集: さん、迅速に回答!最初の100万人の数がこのjavaコードのように同じ結果として、Cのコードです。で3倍以上にJavaのjava.util.かせとなります。

public class ComplimentaryMultiplyWithCarryRandom {

    /**
     * Choose 4096 random 32-bit integers
     */
    private long[] Q;

    /**
     * choose random initial c<809430660
     */
    private long c = 362436;

    private int i;

    public ComplimentaryMultiplyWithCarryRandom() {
        Random r = new Random(1);
        Q = new long[4096];

        // TODO initialize with real random 32bit values
        for (int i = 0; i < 4096; ++i) {
            long v = r.nextInt();
            v -= Integer.MIN_VALUE;
            Q[i] = v;
        }
        i = 4095;
    }

    int next() {
        i = (i + 1) & 4095;
        long t = 18782 * Q[i] + c;
        c = t >>> 32;
        long x = (t + c) & 0xffffffffL;
        if (x < c) {
            ++x;
            ++c;
        }

        long v = 0xfffffffeL - x;
        Q[i] = v;
        return (int) v;
    }
}
役に立ちましたか?

解決

誰でもできるのでポートするJava?どのような このときのみが署名して 番号を利用できますか?

ストレスなし! a=18782 その最大の t えすることは大きくないでほぼ一様に分布することが署名した対符号なします。ならば""アップグレード"の結果を用いQ値に等しい、32ビット符号無し整数を使用してください。例えばばQが int (32ビット符号付きの)していないことを利用する前に、 t=a*Q[i]+c 決例

t=a*(((long)Q[i])&0xffffffffL)+c

こ(((長)Q[i])&0xffffffffL)事業の推進Q[i]に64ビットの#を高32ビットは0です。(編集:注意:必要なもの0xffffffffLます。Javaは間違ったものをご利用の場合小さいか、0xffffffffバイトで感じられるように"最適化"そのものに間違った答え&ときに負の数の場合Q[i]'sの高ビットが1.)

対応することができるでしょう検証をおこのアルゴリズムのC++とJavaの比較をします。<br></p><

編集:こちらはシュートです。てみました走行うC++およびJava N=100000;います。お場合に使用した悪Javaのイディオムが含まれており、今後ともかなり新しいJava.

C++:

// marsaglia2003.cpp 

#include <stdio.h>
#include <stdlib.h> // for atoi

class m2003
{
    enum {c0=362436, sz=4096, mask=4095};
    unsigned long Q[sz];
    unsigned long c;
    short i;

public:
    m2003()
    {
        // a real program would seed this with a good random seed
        // i'm just putting in something that makes the output interesting
        for (int j = 0; j < sz; ++j)
            Q[j] = j + (j << 16);
        i = 4095;
        c = c0;
    }

    unsigned long next()
    {
        unsigned long long t, a=18782LL;
        unsigned long x;
        unsigned long r=0xfffffffe;
        i = (i+1)&mask;
        t=a*Q[i]+c;
        c=(unsigned long)(t>>32);
        x=(unsigned long)t + c;
        if (x<c)
        {
            x++;
            c++;
        }
        return (Q[i]=r-x);
    }
};

int main(int argc, char *argv[])
{
    m2003 generator;
    int n = 100;
    if (argc > 1)
        n = atoi(argv[1]);

    for (int i = 0; i < n; ++i)
    {
        printf("%08x\n", generator.next());
    }
    return 0;
}

java:(遅めのC++での試合のためのN=100000)

// Marsaglia2003.java

import java.util.*;

class Marsaglia2003
{
    final static private int sz=4096;
    final static private int mask=4095;
    final private int[] Q = new int[sz];
    private int c=362436;
    private int i=sz-1;

    public Marsaglia2003()
    {
        // a real program would seed this with a good random seed
        // i'm just putting in something that makes the output interesting
        for (int j = 0; j < sz; ++j)
            Q[j] = j + (j << 16);
    }

  public int next() 
    // note: returns a SIGNED 32-bit number.
    // if you want to use as unsigned, cast to a (long), 
    // then AND it with 0xffffffffL
    {
        long t, a=18782;
        int x;
        int r=0xfffffffe;
        i = (i+1)&mask;
        long Qi = ((long)Q[i]) & 0xffffffffL; // treat as unsigned 32-bit
        t=a*Qi+c;
        c=(int)(t>>32); 
           // because "a" is relatively small this result is also small

        x=((int)t) + c;
        if (x<c && x>=0) // tweak to treat x as unsigned
        {
            x++;
            c++;
        }
        return (Q[i]=r-x);
    }

    public static void main(String args[])
    {
        Marsaglia2003 m2003 = new Marsaglia2003();

        int n = 100;
        if (args.length > 0)
            n = Integer.parseInt(args[0]);
        for (int i = 0; i < n; ++i)
        {
            System.out.printf("%08x\n", m2003.next());
        }
    }
};

他のヒント

ほとんどの時間がないを使用する必要が数値型の場合をシミュレ符号なし種類がJava.

のために、加算、減算、乗算、シフト左の論理業務等 鋳造の小さい数値タイプ なるかどうかのオペランドが署名または符号なし の結果にかかわらず、同じ閲覧したとしてビットパターンです。

シフト右の利用>>のための署名>>>のための符号なし.

のために署名した鋳造により大きなタイプなっている。

のための符号なし鋳造から小型の長期利用&マスク型の小型タイプです。E.g.) 短長:s&0xffffL.

のための符号なし鋳造から小型int利用&マスクのint型.E.g.) バイトのint:b&0xff.

そのようなので、intの場合、キャスト。E.g.) バイトは短期間:(短)(b&0xff).

の比較演算子 < など。部門最も容易な方法としては、最初にキャストを大きいタイプを作ります。がありその他のオプションなどな比較を追加したとき、適切なオフセットされます。

を実装中の場合は、RNG Java、そのサブクラスの java.util.ランダム クラス以上-の保護 next(int) 方法(ごRNGはそのドjava.util.ランダム).次の(int)メソッドではランダムに生成のビットは何valesこれらのビットがあります。その他(公開)メソッドjava.util.ランダムに使用これらのビットをランダム値の異なる種類です。

にJavaの符号なしの種類通常の店舗数をもっと大きな変数の型(ショーツの取得にint,intにできます。からだを一時的にでも超えない変数、いいステップをBigIntegerには、その難破船を任意の速度差益を取得しているのは、アルゴリズムです。

けとしての参考とする可能性がありません)で、このリンク:

http://darksleep.com/player/JavaAndUnsignedTypes.html

利用できる符号付き数の値がわからないオーバーフローしない---例えば長javaは64ビット符号付き整数.しかし、意図にこのアルゴリズムも使用または64ビット符号なし値がんにおいてのデモインのホテルを表示基本です。

があmultiprecision整数のjavaクラスライブラリ(BigInteger).また実施独自の64ビット符号無しタイプとしてオブジェクトを含むjavaのlong値を表すのにする必要があり、最も重要な言葉となりますので、御了承ください思いの実施を基本の算術演算に身を行っています。-

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top