次のコードは、ANSI 準拠の C コンパイラを備えたすべての環境で機能すると期待できますか?
double n = 0;
assert(n == 0);
C++はどうですか?
次のコードは、ANSI 準拠の C コンパイラを備えたすべての環境で機能すると期待できますか?
double n = 0;
assert(n == 0);
C++はどうですか?
C標準では、浮動小数点値の表現方法にいくつかの制限があります。§5.2.4.2.2浮動小数点型の特性では、浮動小数点数は、モデルによって定義されているかのように特性を示す必要があります。
x = sbeΣk = 1..pf k b -k
どこ:
このモデルでは、ゼロは常に正確に表すことができます。つまり、すべての仮数桁fkがゼロである必要があります。
§6.3.1.4で次の制限があります。
整数型の値が実際の浮動型に変換されるときに、変換される値が新しい型で正確に表現できる場合、それは変更されません。
したがって、整数0から浮動小数点型に変換する場合、ゼロは常に変更されない必要があります。したがって、アサーションは常に保持される必要があります。
0.0
が常に正確に表現されているかどうかを尋ねているわけではありません。
ステートメントassert(n == 0)
では、比較が行われる前に に0
変換されます。double
したがって、0
からint
への変換double
が再現できない場合にのみ、アサートをトリガーできます。これは、あなたが求めているものよりもはるかに弱い制限であり、ほぼ確実に保持されます (ただし、頭の中でそれを保証するための標準参照は考えられません)。
あなたが尋ねようとしていた質問に対して:
他の人が述べたように、C 標準では浮動小数点型を IEEE-754 にマップする必要はありませんが、ゼロの正確な表現を持たない C コンパイラで使用される浮動小数点表現については知りません。そうは言っても、C 実装がdouble
正確なゼロを持たない形式を使用することは「合法」です。
比較により、整数が double に昇格されます。あなたが求めているのは、コンパイラが同一の整数を double に変換するたびに同一の変換を行うことが保証されているかどうかです。そうだと思います。
それだけでなく、十分に小さい整数は double で正確に表すことができます。その場合、正確ではない変換を行うコンパイラーは想像できません。
C99 は IEEE754 を義務付けておらず、推奨しているだけです。IEEE 754 準拠のコンパイル プラットフォームが定義できるシンボルがあります (付録 F)。コンパイラがこのシンボルを定義する場合、はい、アサーションが保持されることが保証されます。リテラル定数が浮動小数点数として正確に表現できる場合、この浮動小数点数をコンパイル済みプログラムで取得する必要があります。
ゼロを持たないIEEE 754以外の浮動小数点システム、または0
ソースコードのリテラルをそれにマップしない理由は考えられません。