2012-01-21 15 views
0

Javaプログラムを書いて、1.0/1.0 + 1.0/2.0 + 1.0/3.0 .... + 1.0/15,000,000.0の順番で並び替えます。再び1.0/15,000,000.0 + 1.0/14,999,999から始まり、32ビット浮動小数点を使用して1.0/1.0に降下します。私はこれを行う方法を把握するのには苦労しているが、これまでに何があったかは分かりません(それがうまくいくかどうかは分かりません)。浮動小数点数の増加をJavaで計算する

EDIT:この事をバックアップして申し訳ありませんが、両方の答えと私はかなり間違っていると確信しています。誰かが私が間違ったことを知っていますか?

public class FloatSum { 

public static float increasingSum (float numbers1){ 
float sum1 = 0; 
for (int i = 1; i <= 15000000; i++){ 
    sum1 = sum1 + 1/i; 
    } 
return sum1; 
} 

public static float decreasingSum (float numbers2){ 
float sum2 = 0; 
for (int i = 15000000; i >= 1; i--){ 
    sum2 = sum2 + 1/i; 
    } 
return sum2; 
} 

public static void main(String[] args) { 
float sum1 = 0; 
float sum2 = 0; 

System.out.println(increasingSum(sum1)); 
System.out.println(increasingSum(sum2)); 
} 
} 
+0

私が問題を正しく理解していれば、あなたは_really_最後に '2/1 + 2/2 + 2/3 + ... + 2/14999999' +' 1/15000000'を追加しています。 –

+0

'1/i'は整数除算を行うため、結果は常に0です。 – Voo

+0

ニースキャッチ。私は "int i = 1"を "float i = 1"に変更し、両方の答えが無限に出るようになりました。それ以外に何が変わる必要がありますか?前もって感謝します。 – Brett

答えて

1

forループのロジックが正しくありません。ハハ、私はあなたが何をするかはよく分かりませんが、私たちがそれを歩くことができるかどうかを見てみましょう...

forループは何ですか?

float変数 'a'を1/xとして初期化します。最終値を配列の長さ(良い)に設定します。変数 'a'を1だけ増やして 'x'を1だけ増やします。

ここで、このように考えると、 'a'を1/xに初期化して1にします。値a = 1。次に、 'x'を1だけインクリメントし、 'a'を1だけインクリメントします。ここでは、あなたのロジックに欠陥があるので難しいと思います。これは実際にはx = 2になりますが、a = 2とすることもできます。 'x'と 'a'は独立変数です。 forループの定義を再読み込みして、実行しようとしていることを調整できるかどうかを確認します。

ここでループを使用すると、繰り返しを実行できます。この場合、あなたは30,000,000人(15,000,000人がカウントアップし、15,000,000人がカウントダウンしています)があります。だから、あなたが一緒に1.0/1.0 + 1.0/2.0 + ... + 1.0/15,000,000.0合計する、のは今15,000,000回の反復

for (int i = 1; i <= 15000000; i++){ 
statements; 
} 

for (int i = 15000000; i >= 1; i--){ 
statements; 
} 

でループのための2つ、それぞれを作りましょう。 0でのsum1の初期化:

float sum1 = 0; 

合計に1/iを加算する各繰り返し。したがって、ループの各内部のあなたの文は

sum1 = sum1 + 1/i; 

そしてそこにあなたがそれを持っていると同じです

sum1 += 1/i; 

のようになります。最初のループでは、各繰り返しは、i = 1からi = 15,000,000までの1/iを加算します。 2番目のループでは、i = 15,000,000から始まりi = 1で停止する1/iを追加します。明らかに、あなたのケースでは、15,000,000を 'numbers1.length'で置き換えることができます。 sum1を返すと、すべてのエラーはそのように消えます。

注:forループをどのように拘束するか注意してください。終了値が含まれていることを確認してください。 (2つのループの中で< = 15,000,000と> = 1に注意してください)これはあなたのコードに大きな違いはなく、答えは同じになるでしょうが、将来的には重要になります。

+0

すべての助けてくれてありがとう!今より多くの意味があります。 – Brett

5

これは宿題ですので、私はヒントのカップルに私の答えを制限します:

  1. あなたは配列を必要としない単一のスカラーアキュムレータ変数で十分です。ゼロに初期化し、すべての項を追加します。
  2. 合計の条件をループしないでください。の分母である(非常に便利な整数です)をループしないでください。
+0

ありがとう、私はそれについて考えると私が思い付くことができます参照してください。 – Brett

+0

15,000,000のものがあれば、どの用語を効率的に追加するのですか? – Brett

+1

@ user1157541:現代のコンピュータの場合、1500万回の簡単な繰り返しは子供の遊びです。私があなたの靴の中にいたのであれば、まずは正確さに焦点を当て、後で性能について心配します。 – NPE

2

完全にaixに同意します。 あなたのコードがコンパイルされない理由:変数 "a"は浮動小数点型ですが、配列にアクセスするためにそれを使用しようとします(intを必要とします)。浮動小数点をintとして使用することは不正ですコンパイルエラー。あなたはint型

numbers1[(int)a] 

にフロートをキャストして、エラーを解決する可能性がありますが、プログラムはまだ間違っているので、これは、無用になります。すべての要素から、

  • アレイにアクセスするにはポイントがありませんforのテスト条件がa < numbers1.lengthであるため、
  • です。最後の繰り返しでは、コードnumbers1[a+1]ArrayOutOfBoundExceptionが表示されます(あなたは配列を正しく作成しましたが、すべての要素は0に初期化されています) 15000001番目の要素にアクセスしようとします)

あり、あなたのプログラムが失敗することはありません別の問題は、ですが、forループがどのように動作するかのいくつかの誤解を公開しているようだ:具体的には、あなたが各繰り返しでx変数をインクリメントが、それは、変数以来無駄ですxは、初期化のためにのみ使用されます。a = 1/x部分は、ループを実行する前に、一度だけ実行されます。ここで 、簡単forプライマー:

for(Initializer; TestExpr; CountExpr){ Body } 

ループは以下を実行します実行するマシン:

  1. TestExprfalseと評価された場合Initializerコード
  2. を実行し、後藤6
  3. Bodyコード
  4. を実行してを実行します。code
  5. goto 2
  6. finish!

私はあなたを与えることができますアドバイスは、Javaへのソリューションを通常の数学の構文を使用して、あなたのタスクを実行する方法を紙にをうまくしようとした後、「ポート」することです。

+0

すべての助けてくれてありがとう!今より多くの意味があります。 – Brett

0

利用フロートあなたが望むが、これを見れば:Java:Why should we use BigDecimal instead of Double in the real world?

をそれは精密の損失と呼ばれています。

+0

フロートを使うのは好きではありませんが、それは割り当てです。私は、教授が私たちに教えようとしていることは、正確さの喪失に関する貴重な点だと考えています。 – Brett

+0

ああ、大丈夫です。それは理にかなっている。 – Jimmt

関連する問題