ANSI C89(C++ではない)を使用し、NaN、-Infinity、および+ Infinityを生成したい。
標準的な方法(標準マクロなど)はありますか?または、これらの数値を生成するプラットフォームとコンパイラに依存しない方法はありますか?
float f = 0.0 / 0.0; // Is f ALWAYS in any platform is NaN?
C99にはありますが、以前の標準にはありません。
C99では、NAN
およびINFINITY
マクロがあります。
From "Mathematics <math.h>
"(§7.12)セクション
マクロ[〜#〜] infinity [〜#〜]は、利用可能な場合、正または符号なしの無限大を表すfloat型の定数式に展開されます。 ...
ANSI C89にこだわっている場合は、運が悪いです。 C-FAQ 14.9 を参照してください。
INFINITY
が存在しない古いコンパイラを使用する場合は、代わりにHUGE_VAL
ライブラリで定義されているマクロ<math.h>
も使用できます。
HUGE_VAL
は、C89/C90規格(ISO/IEC 9899:1990)で利用可能です。
無限大と負の無限大を作成する実際の方法があります。 C89が準拠するIEEE 754標準に基づき、無限大は、仮数部にすべてゼロ(最初の23ビット)、指数部にすべて1(次の8ビット)を含む浮動小数点数として定義されます。 nan
は、指数がすべて1で、仮数がすべてゼロである任意の数値として定義されます(無限大であるため)。難しいのはこの番号を生成することですが、これは次のコードで実現できます。
unsigned int p = 0x7F800000; // 0xFF << 23
unsigned int n = 0xFF800000; // 0xFF8 << 20
unsigned int pnan = 0x7F800001; // or anything above this up to 0x7FFFFFFF
unsigned int nnan = 0xFF800001; // or anything above this up to 0xFFFFFFFF
float positiveInfinity = *(float *)&p;
float negativeInfinity = *(float *)&n;
float positiveNaN = *(float *)&pnan;
float negativeNaN = *(float *)&nnan;
ただし、単にunsigned
をfloat
にキャストすると、コンパイラーは同じ値のfloat
を作成します。ですから、私たちがしなければならないことは、コンパイラにメモリをフロートとして読み取らせることです。これにより、望ましい結果が得られます。