9

this other QUESTIONから、彼らは Bjarne Stroustrup が、int(eg short) よりも狭い整数データ型が an に昇格されるのと同じようにintfloats が a に昇格されると言った方法について話しdoubleます。ただし、 よりも狭い整数の拡大とは異なりint浮動小数点の昇格は同じ方法では発生せず、別の場所で発生します。

二項演算子( )が適用される前に を計算すると、 が に変換されることはわかっていfloat + doubleますfloat。ただし、Learncpp.comによると、これは浮動小数点の昇格ではありません。これは通常の算術変換です。double+

浮動小数点の昇格が実際に行われるのはいつですか?

4

2 に答える 2

16

floatto doubleper [conv.fpprom]の「浮動小数点昇格」というものがあります。

type の prvalue は、 type のfloatprvalue に変換できますdouble。値は変更されません。

この変換は、浮動小数点昇格と呼ばれます。

リンクされた質問への回答は正しいです。float通常の算術変換では浮動小数点オペランドがプロモートされないため、2 つの を追加するときにこのプロモートが自動的に行われることはありません。

のように、 a をオペランドとして省略記号に渡すと、浮動小数点の昇格発生します。そのため、フォーマット指定子は aまたは aを出力します。 aを渡すと、関数は実際に昇格の結果である a を受け取ります。floatprintf%ffloatdoublefloatdouble

整数昇格と浮動小数点昇格は、整数変換、浮動小数点変換、および浮動小数点整数変換よりも暗黙的な変換ランクが高いため、浮動小数点昇格の存在はオーバーロードの解決においても重要です。

例 1:

void f(double);
void f(long double);
f(0.0f);

void f(double)への昇格は へdoubleの変換よりも優れているため、これが呼び出されlong doubleます。対照的に、次の驚くべき例 2 を考えてみましょう。

void f(long double);
void f(int);
f(0.0f);

これはあいまいです。からfloatへの変換は、どちらもプロモーションではないため、からへlong doubleの変換よりも優れているわけではありません。floatint

例 3:

struct S {
    operator float();
    operator int();
};
double d = S();

これは、呼び出して、結果の値を initializeにoperator floatプロモートします。floatdoubled

于 2015-05-27T18:57:37.953 に答える
6

浮動小数点数の昇格が適用される主な (おそらく唯一の) 時間は、可変引数関数 (例: printf) に引数を渡すときです。

この場合、通常の算術変換は適用されません (式の 2 つのオペランド間で共通の型を見つけるためのものです)。

標準の関連部分は [expr.call]/7 です (少なくとも N4296 以降):

与えられた引数のパラメーターがない場合、引数は、受信関数が va_arg (18.10) を呼び出して引数の値を取得できるように渡されます。
[...]
引数が、整数昇格 (4.5) の対象となる整数型または列挙型、または浮動小数点昇格 (4.6) の対象となる浮動小数点型の場合、引数の値は次の値に変換されます。呼び出し前に昇格された型。

于 2015-05-27T18:47:39.357 に答える