web-dev-qa-db-ja.com

ANSI CでNaN、-Infinity、+ Infinityを生成する方法は?

ANSI C89(C++ではない)を使用し、NaN、-Infinity、および+ Infinityを生成したい。

標準的な方法(標準マクロなど)はありますか?または、これらの数値を生成するプラットフォームとコンパイラに依存しない方法はありますか?

float f = 0.0 / 0.0; // Is f ALWAYS in any platform is NaN?
45
Amir Saniyan

C99にはありますが、以前の標準にはありません。

C99では、NANおよびINFINITYマクロがあります。

From "Mathematics <math.h> "(§7.12)セクション

マクロ[〜#〜] infinity [〜#〜]は、利用可能な場合、正または符号なしの無限大を表すfloat型の定数式に展開されます。 ...

ANSI C89にこだわっている場合は、運が悪いです。 C-FAQ 14.9 を参照してください。

41
Mat

INFINITYが存在しない古いコンパイラを使用する場合は、代わりにHUGE_VALライブラリで定義されているマクロ<math.h>も使用できます。

HUGE_VALは、C89/C90規格(ISO/IEC 9899:1990)で利用可能です。

参照: http://en.cppreference.com/w/c/numeric/math/HUGE_VAL

0
mlel

無限大と負の無限大を作成する実際の方法があります。 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;

ただし、単にunsignedfloatにキャストすると、コンパイラーは同じ値のfloatを作成します。ですから、私たちがしなければならないことは、コンパイラにメモリをフロートとして読み取らせることです。これにより、望ましい結果が得られます。

0
Clayton L