私のコメントを参照してください。
これは明確に定義されています。の中間式はz
に広がりdouble
、式y * z
になりdouble
ます。暗黙のナローイング変換は、float
に保存するために変換しres2
ます。これと同じナローイングがに適用されres1
ます。
これは、C++11標準の§5¶9式[expr]に反映されています。
算術型または列挙型のオペランドを期待する多くの二項演算子は、同様の方法で変換を引き起こし、結果型を生成します。目的は、結果のタイプでもある共通のタイプを生成することです。このパターンは通常の算術変換と呼ばれ、次のように定義されます。
..。
- それ以外の場合、一方のオペランドが
double
、の場合、もう一方はに変換されdouble
ます。
- それ以外の場合、一方のオペランドが
float
、の場合、もう一方はに変換されfloat
ます。
..。
ただし、これは平等が維持されることを保証するものではありません。
そうは言っても、res1
必ずしも同等である必要はありません-それは環境の精度と環境res2
に大きく依存します。2つのリテラルは、等しくない可能性もあります。。と同等である必要はありません。に等しくなるかどうかはわかりません。float
double
4.23423451f
4.23423451
static_cast<double>(static_cast<float>(4.23423451))
4.23423451
§5.17¶3代入および複合代入演算子[expr.ass]を参照してください。
左のオペランドがクラス型でない場合、式は暗黙的に左のオペランドのcv非修飾型に変換されます(第4節)。
§4標準変換[conv]は次のように述べています。
標準変換は、組み込みの意味を持つ暗黙の変換です。条項4は、そのような変換の完全なセットを列挙しています。標準変換シーケンスは、次の順序での標準変換のシーケンスです。
..。
- 次のセットからのゼロまたは1つの変換:積分プロモーション、浮動小数点プロモーション、積分変換、浮動小数点変換、浮動小数点変換、ポインター変換、メンバーへのポインター変換、およびブール変換。
§4.6浮動小数点プロモーション[conv.fpprom]で詳しく説明されているように、
- タイプのprvalueは、タイプの
float
prvalueに変換できますdouble
。値は変更されません。
- この変換は浮動小数点プロモーションと呼ばれます。
...および§4.8浮動小数点変換[conv.double]、
浮動小数点型のprvalueは、別の浮動小数点型のprvalueに変換できます。ソース値を宛先タイプで正確に表すことができる場合、変換の結果はその正確な表現になります。ソース値が2つの隣接する宛先値の間にある場合、変換の結果は、これらの値のいずれかの実装定義の選択になります。それ以外の場合、動作は未定義です。
浮動小数点プロモーションとして許可されている変換は、浮動小数点変換のセットから除外されます。
ここでの問題は、変換がプロモーションではなく、潜在的に低精度のタイプ(double
to float
)に絞り込まれる複数のケースがあることです。
double
基本的に、に変換するときはいつでも、float
精度が失われる可能性があります。