2017-02-12 10 views
0

Javaで適切な疑似乱数を作成するために、指定した日付を使用して乱数生成を実行しようとしています。私はCalendarクラスを使用し、その日のミリ秒数をカウントすることに決めました。これはある程度はうまくいきましたが、私がプログラムを始めると、私は異なるランダムな値しか得られません。プログラムでこれ以上実行すると、私には同じ番号が与えられます。私はThread.sleep()を使用して実際の時間に違いがあることを確認していますが、同じ数字が得られます。 私はここにカレンダークラスと生成番号のエラー

public long genRNG() 
{ 
    long mask = 0xFFFF000000000000L; 
    long randomValue = seed & mask; 
    seed = 0x5D588B656C078965L * cal.get(Calendar.MILLISECOND) + 0x0000000000269EC3; 
    return randomValue; 
} 

(別のクラスから)を呼び出すとしていますHERESに私の方法は、私の主な方法

public static void main(String[] args) throws InterruptedException 
{ 
    Seed key = new Seed(); 
    for (int x = 0; x <=10; x++) 
    { 
     Thread.sleep(200); 
     System.out.println(key.genRNG()); 
    } 
} 

だと与えられた出力:

-7389844038561562624 
-7389844038561562624 
-7389844038561562624 
-7389844038561562624 
-7389844038561562624 
-7389844038561562624 
-7389844038561562624 
-7389844038561562624 
-7389844038561562624 
+0

'seed'変数の値を変更し、' randomValue'を返しています。 – Andremoniy

+1

もっと重要なことに、あなたは 'cal'を変更していません。 –

+0

randomValueはSeed but Andreで構成されています –

答えて

1

あなたが設定しているようですmaskを毎回同じ値に、seedを毎回同じ値にするため、seed & maskは毎回同じ値を返します。 A Calendarオブジェクトは、インスタンス化された後に自動的にその値を変更しません。つまり、明示的に変更するまでは、構築時の時間(通常はの場合はです)を保持します。したがって、genRNG()を呼び出すたびにcalを再初期化することをお勧めします。ここで

私はローカル変数にcalを変更した:最初の0が初期化されなかったseedから来

0 
8430738502437568512 
-2453898846963499008 
2916080758722396160 
3291568377654411264 
-1326873040214032384 
-951385421282017280 
1212312724692795392 
-3406128693175648256 
-1298444067566256128 
-5916885485434699776 

:よう

long mask = 0xFFFF000000000000L; 
    long randomValue = seed & mask; 
    Calendar cal = Calendar.getInstance(); 
    seed = 0x5D588B656C078965L * cal.get(Calendar.MILLISECOND) + 0x0000000000269EC3; 
    return randomValue; 

今、私は出力を得ることができます。私はそれがあなたのコードの問題ではないことを収集します。

私はあなたがまだそこにいるとは思わない。 Calendar.get(Calendar.MILLISECOND)は常に0〜999の間隔で値を返しますので、最大1000の異なる「ランダム」値を取得しています。 longに保存するためにたくさんありません。あなたはこのようにインスタンスの多くを得ることができます:

seed = 0x5D588B656C078965L * System.currentTimeMillis() + 0x0000000000269EC3; 

場合は、現在の時間のためにオブジェクトではなく、あなたがSystem.currentTimeMillis()から取得するだけでlongをしたい何らかの理由で、あなたは、Java 8を使用することができる場合、私はInstant.now().toEpochMilli()を提案します。それは同じlongの値を与えますが、Instant.now()は、Calendar.getInstance()とよく似た、現在の時刻を表すオブジェクトを提供します。他の目的に使用したい場合は、よりモダンで多目的です。

マスクのために、値は常にバイナリ表現で48のゼロで終わります(すべての値が偶数であることは容易です)。多分これは設計通りですか?

また、java.util.Randomを使用していない理由があるとします。

+0

うわー、これは本当に良い答えです!ありがとう、私はupvoteしたいと思いますが、私は時間を追跡するための他の方法を知らなかったので、私はカレンダーを使用して十分な評判を持っていない、はい、私は自分のバージョンの線形合同乱数発生器。 –

関連する問題