C语言 如何在 ANSI C 中生成 NaN、-Infinity 和 +Infinity?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6235847/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to generate NaN, -Infinity and +Infinity in ANSI C?
提问by Amir Saniyan
I use ANSI C89 (not C++), and I want to generate NaN, -Infinityand +Infinity.
我使用 ANSI C89(不是 C++),我想生成NaN,-Infinity和+Infinity.
Is there any standard way (eg. standard macro)? Or is there any platform and compiler independent way to generate these numbers?
有没有标准方法(例如标准宏)?或者是否有任何平台和编译器独立的方式来生成这些数字?
float f = 0.0 / 0.0; // Is f ALWAYS in any platform is NaN?
采纳答案by Mat
There is in C99, but not in previous standards AFAIK.
在 C99 中有,但在以前的标准 AFAIK 中没有。
In C99, you'll have NANand INFINITYmacros.
在 C99 中,您将拥有NAN和INFINITY宏。
From "Mathematics <math.h>"(§7.12) section
来自“数学<math.h>”(第 7.12 节)部分
The macro INFINITYexpands to a constant expression of type float representing positive or unsigned in?nity, if available; ...
宏INFINITY扩展为 float 类型的常量表达式,表示正数或无符号无穷大(如果可用);...
If you're stuck with ANSI C89, you're out of luck. See C-FAQ 14.9.
如果您坚持使用 ANSI C89,那您就不走运了。参见C-FAQ 14.9。
回答by jcomeau_ictx
I don't know if this is standard or portable, but here's a start:
我不知道这是标准的还是便携的,但这是一个开始:
jcomeau@intrepid:/tmp$ cat test.c; make test; ./test
#include <stdio.h>
int main() {
printf("%f\n", 1.0 / 0);
printf("%f\n", -1.0 / 0);
printf("%f\n", 0.0 / 0);
return 0;
}
cc test.c -o test
test.c: In function ‘main':
test.c:3: warning: division by zero
test.c:4: warning: division by zero
test.c:5: warning: division by zero
inf
-inf
-nan
Strangely enough, I can't get positive NaN using this naive approach.
奇怪的是,我无法使用这种幼稚的方法获得正 NaN。
另请参阅: http://www.gnu.org/s/hello/manual/libc/Infinity-and-NaN.htmlhttp://www.gnu.org/s/hello/manual/libc/Infinity-and-NaN.html
回答by mlel
If you use an old compiler where INFINITYdoes not exists you can also use the macro HUGE_VALinstead, also defined in the <math.h>library.
如果您使用INFINITY不存在的旧编译器,您也可以使用宏HUGE_VAL,也可以在<math.h>库中定义。
HUGE_VALshould be available in C89/C90 standard (ISO/IEC 9899:1990).
HUGE_VAL应在 C89/C90 标准 (ISO/IEC 9899:1990) 中可用。
References: http://en.cppreference.com/w/c/numeric/math/HUGE_VAL
回答by Clayton L
There is an actual way to create infinity and negative infinity. Based on the IEEE 754 standard, which C89 follows, infinity is defined as a floating point number containing all zeroes in the mantissa (first twenty-three bits), and all ones in the exponent (next eight bits). nanis defined as any number with all ones in the exponent, and anything but all zeroes in the mantissa (because that's infinity). The difficult part is generating this number, but this can be accomplished with the following code:
有一种创造无穷大和负无穷大的实际方法。根据 C89 遵循的 IEEE 754 标准,无穷大被定义为一个浮点数,包含尾数中的所有零(前 23 位)和指数中的所有 1(接下来的 8 位)。 nan被定义为指数中全为 1 且尾数中全为 0 以外的任何数字(因为它是无穷大)。困难的部分是生成这个数字,但这可以通过以下代码来完成:
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;
However, simply casting an unsignedto a floatwould result in the compiler creating a floatof the same value. So, what we have to do is force the compiler to read the memory as a float, which gives us the desired result.
但是,简单地将 an 转换unsigned为 afloat会导致编译器创建具有float相同值的 a。所以,我们要做的就是强制编译器将内存读取为浮点数,这给了我们想要的结果。

