- 締切済み
float double の範囲
javaのサイト見てます データ型にfloat doubleというのがあるのですが、 範囲が float 3.40282347E+38 double 1.79769313486231570E+388 と記載されているのですが これはどうゆう意味でしょうか? 小数点38桁388桁までという意味でしょうか?
- みんなの回答 (11)
- 専門家の回答
みんなの回答
- amanojaku1
- ベストアンサー率54% (265/488)
>なんと衝撃の事実、doubleの誤差でループが正しく3回になっています(^_^;マジか?)。 >あくまでも誤差によるものなので、そんなものは当てにしてはいけません。 所詮doubleの誤差によるモノなので簡単に破綻します。 13回ループしたい場合(実際は14回ループしている)。 double start,stop,stride,step; start = 0; stop = 1; step = 13; stride = (stop-start)/step; int loop = 0; for(double l = start; l<stop; l+=stride){ loop++; System.out.println("l="+l); } System.out.println("loop="+loop); 【実行結果】 l=0.0 l=0.07692307692307693 l=0.15384615384615385 l=0.23076923076923078 l=0.3076923076923077 l=0.38461538461538464 l=0.46153846153846156 l=0.5384615384615385 l=0.6153846153846154 l=0.6923076923076923 l=0.7692307692307692 l=0.846153846153846 l=0.9230769230769229 l=0.9999999999999998 loop=14
- amanojaku1
- ベストアンサー率54% (265/488)
>回答No.9 amanojaku1 古いソースをコピペしてしまいました。 double start,stop,stride,step; start = 0; stop = 1; step = 3; stride = (stop-start)/step; int loop = 0; for(double l = start; l<stop; l+=stride){ loop++; System.out.println("l="+l); } System.out.println("loop="+loop); 【実行結果】 l=0.0 l=0.3333333333333333 l=0.6666666666666666 loop=3
- amanojaku1
- ベストアンサー率54% (265/488)
>回答No.8 amanojaku1 訂正ですm(_ _)m、forの条件「l<=stop」が間違っておりました。 なんと衝撃の事実、doubleの誤差でループが正しく3回になっています(^_^;マジか?)。 あくまでも誤差によるものなので、そんなものは当てにしてはいけません。 double start,stop,stride,step; start = 0; stop = 1; step = 3; stride = (stop-start)/step; int loop = 0; for(double l = start; l<=stop; l+=stride){ loop++; System.out.println("l="+l); } System.out.println("loop="+loop); 【実行結果】 l=0.0 l=0.3333333333333333 l=0.6666666666666666 loop=3
- amanojaku1
- ベストアンサー率54% (265/488)
>回答No.7 amanojaku1 例えば3回ループしたかったとする。 下記はdoubleの誤差でループが4回になっている。 実際に どうしても浮動小数でループしたい場面はあるが、初め(プログラムの設計時)から整数が使えないか熟考してみた方が良い(できるだけ整数にできないか熟考することをオススメします)。 double start,stop,stride,step; start = 0d; stop = 1d; step = 3d; stride = (stop-start)/step; int loop = 0; for(double l = start; l<=stop; l+=stride){ loop++; } System.out.println("loop="+loop); 【実行結果】 loop=4
- amanojaku1
- ベストアンサー率54% (265/488)
>回答No.6 amanojaku1 floatの誤差は酷過ぎるが、doubleでも誤差は出る。 演算の回数が増えるごとに どんどん誤差は大きくなるので、シビアな計算が必要な場合は誤差が最小になるように工夫が必要になる。 内部的に2進で演算しているので(浮動小数点表示の小数部と言う意味ではなく)実際の数値の小数部でも誤差は出る。 例えば消費税の計算で端数の処理(切捨て、切上げ、四捨五入など)があるが、実際の会計処理で切捨てで誤差が出た場合、法律に抵触する事になる(これは「切上げ、四捨五入」で誤差が出ないと言う事ではない)。 内部的に2進で演算している場合(float、double)は要注意。
- amanojaku1
- ベストアンサー率54% (265/488)
>回答No.5 amanojaku1 >回答No.2 amanojaku1 例えば「String.format(~)」で浮動小数点表示の小数部を20桁表示させてみると。 (例1).System.out.println(String.format("%1.20e", 2042f/125f*375f*10000000000000000000f)); 【実行結果】 6.12599977585250600000e+22 ↑(誤差があると言う前提で)8桁目から おかしな数字になっている、また最後の方にゼロが続いているが、内部的に表示上の数字を切り捨てているだけで実際はゼロではない。 (例2).System.out.println(String.format("%1.20e", 2042d/125d*375d*10000000000000000000d)); 【実行結果】 6.12599999999999900000e+22 ↑(誤差があると言う前提で)16桁目から数字がゼロになっているが、内部的に表示上の数字を切り捨てているだけで実際はゼロではない。 (例3).System.out.println(String.format("%1.20e", 2042d/125d*375d*10000000000000000000d-6.12500000e+22)); 【実行結果】※(例2)は16桁目から数字がゼロになっているが、16桁目からも数字が存在すると言う証明。 9.99999999998479600000e+18 ↑(例2)から「6.12500000e+22」を引いている、(誤差があると言う前提で)結果として12桁目から おかしな数字になっている、また最後の方にゼロが続いているが、内部的に表示上の数字を切り捨てているだけで実際はゼロではない。
- amanojaku1
- ベストアンサー率54% (265/488)
>回答No.2 amanojaku1 内部的に2進で演算しているので演算誤差がでます。 System.out.println(2042d/125d*375d); System.out.println(2042d/666d*375d*777d); 【実行結果】 6125.999999999999 893375.0000000001
- bunjii
- ベストアンサー率43% (3589/8249)
>float >3.40282347E+38 >double >1.79769313486231570E+388 >と記載されているのですが 違うでしょう。 概数ですが次のようになります。 3.40282347E+38 → 3.4E +/- 38 → 3.4E-38~3.4E38 1.79769313486231570E+388 → 1.7E +/- 308 → 1.7E-308~1.7E308 >小数点38桁388桁までという意味でしょうか? 0を挟んで+側と-側の桁数がfloatは38桁でdoubleが308桁まで扱える範囲です。 有効な数値は夫々7桁と15桁のようです。 扱える数値と有効桁数で矛盾を感じるかも知れませんがソロバンで計算するのと計算尺で計算することを比較すれば理解できると思います。
- notnot
- ベストアンサー率47% (4900/10358)
388じゃなくて308ですね。 floatで表せる最大値が 3.40282347 x 10の38乗、 doubleで表せる最大値が 1.7976931348623157 x 10の308乗 ということです。 有効数値は、floatが7桁強、doubleが16桁強です。それ以降の桁は誤差です。 数字が半端なのは、2進数データを10進数換算したからです。
- amanojaku1
- ベストアンサー率54% (265/488)
>小数点38桁388桁までという意味でしょうか? 違います。 System.out.println(Math.sqrt(2f)); System.out.println(Math.sqrt(200000000000000000000f)); 【実行結果】 1.4142135623730951 1.4142135765441353E10 floatの有効桁数:約6~7桁 ※上記の実行結果は9桁目から数字が一致してない。 System.out.println(Math.sqrt(2d)); System.out.println(Math.sqrt(200000000000000000000d)); 【実行結果】 1.4142135623730951 1.4142135623730951E10 doubleの有効桁数:15桁 ※上記の実行結果は17桁目まで数字が一致している。
- 1
- 2