- ベストアンサー
pop()関数について
pop関数にて、15と15を入力し、15の15乗を計算しようとすると、正しい計算がされずに、 15 の 15 乗は: 437893890380859392 と表示されます。 (正しい計算は437893890380859375となります) 14の累乗、13の累乗の時は正しく計算されるのですが、 これはなぜこうなるのでしょうか? 回答宜しくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
15の15乗はdoubleの精度を超えます。 doubleの精度は52ビットで、10進数で15桁です。 なので、頭から15桁の「437893890380859xxx」までは保証されますが、下位3桁は不正確になります。 Borland BCCでは、long doubleの精度は64ビット、10進数で19桁ですから、long double型のpowl()関数を使いましょう。 Borland BCCで #include <math.h> #include <stdlib.h> #include <stdio.h> void main(void) { long double d; d=powl(15.0L,15.0L); printf("%.20Lg\n",d); } をコンパイルして実行すると 437893890380859375 と表示されます。 そして #include <math.h> #include <stdlib.h> #include <stdio.h> void main(void) { double d; d=pow(15.0,15.0); printf("%.20g\n",d); } をコンパイルして実行すると 437893890380859392 と表示され、精度が不足しているのが判ります。 なお、VC++では、doubleとlong doubleは「同じ精度」ですので、上記のプログラムはどちらも 437893890380859392 と表示されます。
その他の回答 (3)
- chie65536
- ベストアンサー率41% (2512/6032)
訂正と補足。 >doubleの精度は52ビットで、10進数で15桁です。 >Borland BCCでは、long doubleの精度は64ビット、10進数で19桁です 内部的なデータのビット数はそれぞれ、52ビット、64ビットですが、精度はもう1ビットあります(仮数部の最上位ビットは常に1なので、内部データから削除されている) なので、精度はdoubleは53ビット、long doubleは65ビットです。 この精度は、10進数ではそれぞれ、約15.95桁、約19.57桁になります。 この桁数は「2の53乗≒10の15.95乗」と「2の65乗≒10の19.57乗」と言う式が根拠です。 よく「doubleの精度は10進で16桁」と言う資料を目にしますが、実際は15.95桁なので「たま~に16桁目が嘘をつく」事があります(95%は正しく、5%は嘘) なので、当方の回答では「doubleの精度は10進数で15桁」「long doubleの精度は10進数で19桁」と書いています。
- mtaka2
- ベストアンサー率73% (867/1179)
popでなくpowですね。 powは整数ではなく、浮動小数点で結果を返す関数です。 そのため、浮動小数点演算の精度的な問題で、整数として見ると正しくない答えが出る場合もあります。 浮動小数点型 double の有効数字は53bit=10進16桁です。 誤: 43789 38903 80859 392 正: 43789 38903 80859 375 と見比べればわかるとおり、16桁までは正しい答えとなっています。 つまり、pow 以前に、そもそも double 型では、18桁の整数を正確に表現することができないのです。
お礼
回答ありがとうございます! powでしたね間違えてすみませんでした。
- asuncion
- ベストアンサー率33% (2127/6289)
とりあえず、ソースを全部見せてください。 お話はそれからです。
お礼
補足も含めてわかりやすい説明をありがとうございました!