printfの%fと%lfについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
きょう

printfの%fと%lfについて

#1

投稿記事 by きょう » 7年前

こんばんは。
先ほど、C言語についていろいろと調べていたら、printf関数内でdouble型の変数を表示させたいときに、%lfではなく%fを使うと知りました。
「printfではfloat型を受け取ったとしてもdouble型に格上げされて計算されるので、printfに渡った時点でfloatの値はあり得ない。」
これについてはなんとなくわかります。
ですが、%fはfloat型への、%lfはdouble型への書式指定子ですよね?
もしfloat型がdouble型に格上げされるのであれば、%lfで取るのではないでしょうか。
なぜ、%fで取るのか、反対な気がしてなりません。
どなたかご解答よろしくお願いします。

あんどーなつ
記事: 171
登録日時: 7年前
連絡を取る:

Re: printfの%fと%lfについて

#2

投稿記事 by あんどーなつ » 7年前

floatもdoubleも小数点表記で印字した時点で正確な数値でなくなってます。
つまり、浮動小数点型を文字列にして浮動小数点型に入力すると、厳密に値が一致しない場合がありえます。

だからfloatもdoubleも%fでOKだと思います。

シリアライズしたいときは16進表記で出力しています。

hide

Re: printfの%fと%lfについて

#3

投稿記事 by hide » 7年前

オフトピック
%fはfloat型への、%lfはdouble型への書式指定子ですよね?
もともと仕様的にわける必要がないものです。
なので、%fがfloat用である という認識が正しくないと思われます。(間違ってもいないのですが)

YuO
記事: 947
登録日時: 13年前
住所: 東京都世田谷区

Re: printfの%fと%lfについて

#4

投稿記事 by YuO » 7年前

きょう さんが書きました:ですが、%fはfloat型への、%lfはdouble型への書式指定子ですよね?
fprintf系列において,%lfは%fと同じ意味です。
fscanf系列において,%lfと%fは異なる意味です。
後者で使い分けないといけないという認識が,前者に波及してしまっているのだと思います。

歴史的に見ると,ISO/IEC 9899:1990 (標準Cの初版, C90) では,fprintf系列でlを前置可能な変換指定子はd, i, o, u, x, X, nだけでした。
それ以外の変換指定子に使うと未定義の振る舞いとされていました。
その後、ワイド文字系のライブラリが増加した,ISO/IEC 9899:1990/Amd.1:1995 (C90の追補,C95) でsとcについて使えるようになりました。
元々,fprintf等で書式化されるオブジェクトは既定の実引数拡張(汎整数拡張およびfloatをdoubleに拡張)がなされるため,floatについて定義する必要が無いためです。

しかし,あまりにもみんなが%lfと書くためか,ISO/IEC 9899:1999 (標準Cの第2版, C99) にて,変換指定子fについてもlを許すようになりました。
C99のForeword(前書き)のMajor changesにも,
%lf conversion specifier allowed in printf
と書かれています。
つまり,C99で初めて%lfが許された,ということです。
ただ,意味合いは,7.19.6.1 The fprintf functionに,
l (ell) (省略) or has no effect on a following a, A, e, E, f, F, g, or G conversion specifier.
とあり,lが付くことによる効果はなにもない,となります。

ref)
C言語FAQ 12.9 C90時代の文書ですが,このあたりのことがいくつかの項目に書いてあります。
[迷信] double の出力書式は "%lf" | 株式会社きじねこ たかぎさんによる説明。

閉鎖

“C言語何でも質問掲示板” へ戻る