- ベストアンサー
実数型の変数に値を入力した計算結果がおかしくなる理由
こんばんは。 以下のプログラムで値がおかしくなる理由、改善方法を教えて頂けませんでしょうか。 double a,b,c; scanf("%f",&a); scanf("%f",&b); c = a + b; printf("%f",c); これを実行すると、正しい値が出力されません。 int型で宣言し、整数表示の%dに変更すると問題なく値が出力されます。 また、予めdouble型で宣言した変数a,bに実数の初期値(8.5等)を格納しておくと正しい値が出力されます。 どなたかご回答よろしくお願い致します。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
printfではdouble、floatどちらでも%fですが、 scanfではdoubleは%lf、floatは%fです。
その他の回答 (1)
%f は float型(単精度浮動小数点型)を扱うフォーマット指定子なので、 %lf と長さ修飾子 l(エル) を付加して倍精度浮動小数点型(=double)であることを示さなければいけません。小数点数型はビットを 符号部・仮数部・基数部 に分けて考えます。float型とdouble型では仮数部と基数部のビット数が違うので、double型をfloat型として扱うと変な結果になるのです。が、C言語では可変長引数で渡される値は暗黙的に精度の高い方に変換されるんです(floatならdoubleに)。なので、可変個引数でfloatが渡されようがdoubleが渡されようがかわらないので、printfでは%fでも%lfでも同じように扱われ、printfでは%fとしていしてもOKなわけです。scanfでは普通に%fだと&a,&bはfloat型へのポインタとして扱われるので、%lfを指定しないとなりません。というわけで、 double a,b,c; scanf("%lf",&a); scanf("%lf",&b); c = a + b; printf("%f",c); //printf("%lf",c); でも結果は同じ とすれば正しく表示されると思います。 長さ修飾子について http://ja.wikipedia.org/wiki/Printf#.E9.95.B7.E3.81.95.E4.BF.AE.E9.A3.BE.E5.AD.90 printfとscanfの違い (可変個引数の扱われ方) について http://www.ei.fukui-nct.ac.jp/~t-saitoh/edu/ProgAppl/pa-faq-float.html 浮動小数点数型について http://ja.wikipedia.org/wiki/%E6%B5%AE%E5%8B%95%E5%B0%8F%E6%95%B0%E7%82%B9%E6%95%B0#IEEE.E6.96.B9.E5.BC.8F.EF.BC.88IEEE_754_.E5.BD.A2.E5.BC.8F.EF.BC.89