• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:double型の足し算について)

double型の足し算でおかしな答えになる事例

このQ&Aのポイント
  • double型の足し算において、一部の数値でおかしな答えになるケースがあることがわかりました。
  • 例えば、4.1と3.8を足し算すると7.899999999999995となる場合や、1.8と2.1を足し算すると3.9000000000004となる場合があります。
  • このような問題が起きるのは、double型が2進数で数値を表現するために正確に表現しきれないことが原因です。小数部分のみで表される値は、有限桁の2進数では正確に表現できないので、微小な誤差が発生することがあります。

質問者が選んだベストアンサー

  • ベストアンサー
  • jjon-com
  • ベストアンサー率61% (1599/2592)
回答No.4

次のJavaプログラムを実行してみてください。 class Q7461149 { public static void main(String[] args) { double d1 = 10.5; double d2 = 1.5; System.out.println(d1); System.out.println(d2); System.out.println(d1 + d2); System.out.println(Double.toHexString(d1)); System.out.println(Double.toHexString(d2)); System.out.println(Double.toHexString(d1 + d2)); } } ---------------------------------------- 10進数の 10.5 をdouble型変数に格納したとき, その変数の内部データは 16進文字列(HexString)書式で 0x1.5p3, これは2進表記で (1.0101)2 × 2の3乗を表しています。 (1+ 1/4 + 1/16)×8 = 10.5ということです。 10進数の 1.5 をdouble型変数に格納したとき, その変数の内部データは 16進文字列(HexString)書式で 0x1.8p0, これは2進表記で (1.1000)2 × 2の0乗を表しています。 (1+ 1/2)×1 = 1.5ということです。 両者の和は,指数を2の3乗に統一することで計算でき, {(1.0101)2 + (0.0011000)2}×2の3乗 = (1.1)2 × 2の3乗です。 10進数の10.5 と 10進数の1.5,どちらも, 1,1/2,1/4,1/8,1/16 といった有限長の2進数の組合せで びったり正確に表現できる数だったということです。 ---------------------------------------- 次に d1,d2 の値を次のように変更してみます。 double d1 = 4.1; double d2 = 3.8; 10進数の 4.1 をdouble型変数に格納したとき, その変数の内部データは 16進文字列(HexString)書式で 0x1.0666666666666p2 となります。これは2進表記で (1.0000 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110 0110)2 × 2の2乗 となる「循環無限小数」であり,同パターンの繰り返しがどこまでも続きます。 つまり10進数の 4.1 は,1,1/2,1/4,1/8,1/16 …といった 有限長の2進数の組合せでは,ぴったり正確に表現できないのです。 10進数の 3.8 も同様であり,d1+d2 に誤差が生じる理由はこれです。 ---------------------------------------- このような例を「おかしな答え」だとお感じになるのなら, double型の変数の中身全体をそのまま出力するのではなく, 小数点以下の桁数を若干短くして出力してみてください。 例えば次のように書くと, 小数点以下の表示を15けたまでに限定できます。 System.out.printf("%.15f", d1 + d2);

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (4)

回答No.5

double 型は IEEE754の倍精度浮動小数点 という形式で 数値を保持します。この形式は、10進で書いたリテラルの実数値を 誤差なく保持できない場合が多々あるのでこうなります。 http://ja.wikipedia.org/wiki/IEEE_754 これは Java というよりプログラミングの基本ですが、 不思議なことに、ちゃんと勉強している人がなぜか非常に少ないんですよね。 頑張ってください。

全文を見る
すると、全ての回答が全文表示されます。
  • bajutsu
  • ベストアンサー率20% (139/693)
回答No.3

浮動小数点だから。 Excelでの例だけど、浮動小数点の誤差について解説されています。 http://pc.nikkeibp.co.jp/pc21/special/gosa/eg4.shtml

全文を見る
すると、全ての回答が全文表示されます。
  • wormhole
  • ベストアンサー率28% (1622/5659)
回答No.2

「浮動小数点」を調べてみてください。

全文を見る
すると、全ての回答が全文表示されます。
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

double型の値が内部的にどのように表現されているかを調べてみてはどうでしょうか.

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • プログラミングは初心者なため、doubleについての問題がまったく分か

    プログラミングは初心者なため、doubleについての問題がまったく分かりません・・・。できるだけ初心者にも分かりやすく簡単に回答していただけると幸いです。 1、double型の変数で扱える桁数を超えた桁数の数値を、double型の変数に入れると、制限を超えた桁数の部分がどのように扱われるか答えよ。 2、なぜ上記の1、ようにdoubleに制限があるかについて理由を答えよ。 回答お願いします!!

  • 文字列連結中の足し算

    JAVA初心者です。 表記の通り、文字列連結中の足し算はどの様にすれば良いのでしょうか。 System.out.println("現在のカウンター値は" + cnt + 1 + "です。"); 上記の様な場合、cntが0だと、 "現在のカウンター値は01です。" と表示されますよね。これを、 "現在のカウンター値は1です。" としたいのです。やはり一旦、別変数で計算後、出力するべきなのでしょうか。

    • ベストアンサー
    • Java
  • エクセルで表計算の答がダブルクリックしないと出ません

    エクセルで、例えば 「=SUM(A1+A2)」とA3のセルに打ち込みますよね? で、A1やA2の数値を変更すると、 答の出るA3のセルも自動的に数値が変更されていたのですが、 気付いたら、A3(答)のセルをダブルクリックして、 enterを押さないと数値が変更されなくなっていました。 計算式は上のバーに表示もされるし問題ないようですが、 どうしたら元に戻せるでしょうか? どうぞよろしくお願い致します。

  • C#のTextboxについて

    string a; a="Textbox1" double b =double.Parse(a)-10.0 上記のようにプログラムを書きました。 bという変数に(Textbox1に記載してある数値-10)を代入したいのですがエラーが出てしまいました。 間違いがわかりません。 わかるかたがいましたら、教えていただけないでしょうか? よろしくお願いいたします。

  • クラス変数について質問

    Javaのオブジェクト指向を解説した参考書で現在勉強しているのですが、その参考書のある問題の答えの解説として「クラス変数は参照変数なので参照以外を代入できません」と書いてありました。 でも、例えば、static int n=0と書けば、0をnに代入できます。 因みに、「クラス型の変数」は参照しか代入できないのはわかっています。 よって「クラス変数」は誤植で、正しくは「クラス型変数」なのでしょうか?

    • ベストアンサー
    • Java
  • VBA "double"から0.1を引くと・・・

    エクセルVBAですが、double型で変数を定義し、-80を代入します。 そこから0.1ずつを引いていきます。すると、途中から桁がおかしくなってしまいます。 (注:別に-80からでなくても、どの値からでも、また、引いていっても足していっても、遅かれ早かれ どこかから桁がおかしくなってしまいます。) -80 -80.1 -80.2 …中略 -80.8 -80.8999999999999 -80.9999999999999 … といった感じです。 どうしてこのようになってしまうのでしょうか。 また、このようにならないためにはどうしたらよいのでしょうか。 いかにサンプルプログラムを載せます。 ------------------------------------------ Sub test() Dim test As Double Dim i As Integer test = -80 For i = 1 To 100 test = test - 0.1 Cells(i, 1) = test Next i End Sub ----------------------------------

  • ラッパークラスのvalueOfメソッドについて

    あるテキストで、「int i = Integer.valueOf("10");」はvalueOfメソッドの戻り値型がIntegerであるにも関わらずint型変数に代入しようとしているためにコンパイルエラーになると解説されていました。 しかし、実際にコードを書いてみると、上記のコードはコンパイルが通ります。(代入時にアンボクシングされているということでしょうか) テキストはJava2 Platform5.0のものなので、Java SE6で何かしら仕様が変更されているのかと思ったのですが、どなたか詳しい方、解説をお願いします。

    • ベストアンサー
    • Java
  • プラス演算子の使い方

    このサイトでjavascriptを勉強中です。 http://www.red.oit-net.jp/tatsuya/java/alert.htm 掛け算の出題フォームにランダムな整数(1~9)を入れて 入力された値の可否をアラートで出すというプログラムです。 不正解だった場合、 「はずれ ! こたえは "+myKotae+" です!」 と表示されるのですが、なぜ myKotae の前後に 『 + 』がついているのかわかりません。 確かに + を取って、"myKotae"だけにすると正しく動作しません。 javascriptで『 + 』がどんな働きをするのか調べたら 数値を足したり文字列をつなげたりするとありました。 使い方の例には変数や数値の前に + を付けているものはありましたが 前後につけているものはなかったので混乱しています。 なぜ"myKotae"だとダメなんですか? 初心者にもやさしく解説してくださる方からの回答お待ちしております。 よろしくお願いいたします。

  • C++ インラインアセンブラでdoubleの計算

    プログラム初心者です。 インラインアセンブラで浮動小数点を計算したいのですが、 計算出来ません。fmov、faddで浮動小数点演算が可能との事ですが。 整数の演算と同様では計算できないのでしょうか? 下記の様にまず、aとbを足し算をしてみました。 double a=2.1; double b=1.1; __asm{ fmov st1,a fmov st2,b fadd st1,st2 fmov a,st1 } cout << a << endl;

  • Javaで、変数をつなげて表示することは可能ですか?

    Javaで、変数をつなげて表示することは可能ですか? 最近Javaを学び始めた、Java初心者です。 PHPで、二つの変数(数値)を echo $変数1.$変数2; で、変数1と変数2をつなげて表示できるように Javaで変数(int型やdouble型)をつなげて表示(変数の結合?)することは可能でしょうか? もしくは  System.out.println(変数1+""+変数2); や System.out.println(変数1+" "+変数2); または、 print を二回使う のようなやり方でないとできないのでしょうか? 特にこれを使ってやりたいということがあるわけではありませんが 気になったので質問させて頂きました。    

    • ベストアンサー
    • Java