2017-08-29 9 views
1

私は指定された量のロール(num;)のサイコロをシミュレートし、その結果を印刷するプログラム(以下のコード)を持っています。 何らかの理由で、プログラムが完了できるロールの最大量は2,147,483,583であり、intの上限は2,147,483,647ではありません。ロールの数として2,147,483,647が入力された場合、プログラムは決して出力を生成しません。forループの結果が無限ループで2,147,483,647になるのはなぜですか?

具体的な理由はありますか?

import java.security.SecureRandom; 

public class RollDie { 
// number of rolls 
private static float num = 2147483583; 

public static void main(String[] args) throws InterruptedException { 
    long start = System.currentTimeMillis(); 
    System.out.print("Rolling...\n"); 

    SecureRandom randomNumbers = new SecureRandom(); 
    int frequency1 = 0; 
    int frequency2 = 0; 
    int frequency3 = 0; 
    int frequency4 = 0; 
    int frequency5 = 0; 
    int frequency6 = 0; 

    for (int roll = 1; roll <= num; roll++) { 
     // randomly selecting face ('rolling') 
     int face = 1 + randomNumbers.nextInt(6); 

     switch (face) { 
     case 1: 
      ++frequency1; 
      break; 
     case 2: 
      ++frequency2; 
      break; 
     case 3: 
      ++frequency3; 
      break; 
     case 4: 
      ++frequency4; 
      break; 
     case 5: 
      ++frequency5; 
      break; 
     case 6: 
      ++frequency6; 
      break; 
     } 
    } 

    long end = System.currentTimeMillis(); 
    long totalTime = ((end - start)/1000); 
    // displaying results 
    System.out.println("\nFace\tFrequency"); 
    System.out.printf("1\t%d%n2\t%d%n3\t%d%n4\t%d%n5\t%d%n6\t%d%n", 
      frequency1, frequency2, frequency3, frequency4, frequency5, 
      frequency6); 
    System.out.println("\nTime taken: " + totalTime + " seconds."); 
    } 
} 
+0

ここで何が起こっているのか把握するために少しデバッグし、より具体的な質問(または2つ)を聞いた場合、この質問にはもっと大きな将来価値があったはずです。 – Dukeling

+0

私はそれを改善するために私の投稿を編集する方法についての任意の提案? @Dukeling –

+0

問題は、この質問の理想的なバージョンに到達するためには、あなたの質問に根本的な変更が必要だが、この段階では、回答の一部が無効になります。具体的には、ここでは2つの問題があります:(1)floatを使って大きな整数を表現しようとする、(2)最大2,147,483,647にループしようとする - 理想的には2つの別々の質問であるべきです。あなたは今それを本当に絞り込むことはできません。しかし、あなたができることは[できるだけコードを減らす](https://ideone.com/CVZ0Gr)です。 – Dukeling

答えて

3

forループは決して終了しないため、出力はありません。条件をfor (int roll = 1; roll <= num; roll++)からfor (int roll = 0; roll < num; roll++)に変更する必要があります。

ロールがInteger.MAX_VALUEに達すると、条件はがまだ真のになるので、ループをもう一度入力します。今度はロールが増加し、Integer.MIN_VALUEにオーバーフローし、まだ< = numです。したがって、forループは決して停止しません。

さらに、numfloatである問題が発生します。詳細はEran's answerを参照してください。

2

num変数はfloatタイプです。 floatタイプの精度は限られているため、大きなint値を正確に表すことはできません。

2番目の問題はMalte氏によって指摘されました。オーバーフローのため、制限をInteger.MAX_VALUEに設定するとループが終了しません。

numintに変更し、ループの条件をroll < numに変更すると、ループは正しい繰り返し回数の後に終了します。

+0

'num'の型を変更しても問題は完全には解決されません。これが機能しない理由は、forループの終了条件です。 'roll'がオーバーフローするので決して壊れません。私は浮動小数点数がループ実行の回数が間違っている必要があるかもしれないことに同意します。 –

+0

@MalteHartwigあなたは部分的に正しいと私は部分的に正しいです。完全な答えは両方の答えの組み合わせです。あなたのソリューションは無限ループを防ぎますが、ループは時期尚早に終了します(roll == 2147483584の場合)。 – Eran

+0

うん、私は少し私のコメントを変更しました。浮動小数点を使ったことは一度もありませんでした。 –

関連する問題