如何在 ANSI C 中生成 NaN、-Infinity 和 +Infinity?

发布于 2024-11-13 14:50:42 字数 237 浏览 4 评论 0原文

我使用 ANSI C89(不是 C++),我想生成 NaN-Infinity+Infinity

有没有标准的方法(例如标准宏)? 或者是否有任何独立于平台和编译器的方法来生成这些数字?

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

I use ANSI C89 (not C++), and I want to generate NaN, -Infinity and +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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

云柯 2024-11-20 14:50:42

C99 中有,但以前的标准 AFAIK 中没有。

在 C99 中,您将拥有 NANINFINITY 宏。

来自“数学 (§7.12)部分

INFINITY扩展为float类型的常量表达式,表示正或无符号无穷大(如果可用); ...

如果您一直坚持使用 ANSI C89,那么您就不走运了。请参阅C-FAQ 14.9

There is in C99, but not in previous standards AFAIK.

In C99, you'll have NAN and INFINITY macros.

From "Mathematics <math.h>" (§7.12) section

The macro INFINITY expands to a constant expression of type float representing positive or unsigned infinity, if available; ...

If you're stuck with ANSI C89, you're out of luck. See C-FAQ 14.9.

Smile简单爱 2024-11-20 14:50:42

我不知道这是标准的还是可移植的,但这是一个开始:

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

奇怪的是,我无法使用这种幼稚的方法得到正 NaN 。


Also see this: http://www.gnu.org/s/hello/manual/libc/Infinity-and-NaN.html

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.


Also see this: http://www.gnu.org/s/hello/manual/libc/Infinity-and-NaN.html

绻影浮沉 2024-11-20 14:50:42

如果您使用不存在 INFINITY 的旧编译器,您还可以使用宏 HUGE_VAL 代替,该宏也在 中定义> 图书馆。

HUGE_VAL 应适用于 C89/C90 标准 (ISO/IEC 9899:1990)。

参考文献: http://en.cppreference.com/w/c/numeric/数学/HUGE_VAL

If you use an old compiler where INFINITY does not exists you can also use the macro HUGE_VAL instead, also defined in the <math.h> library.

HUGE_VAL should be available in C89/C90 standard (ISO/IEC 9899:1990).

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

妄司 2024-11-20 14:50:42

有一种实际的方法可以创造无穷大和负无穷大。根据 C89 遵循的 IEEE 754 标准,无穷大被定义为尾数(前 23 位)全为 0,指数(接下来的 8 位)全为 1 的浮点数。 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;

但是,简单地将 unsigned 转换为 float 将导致编译器创建一个 >float 具有相同的值。因此,我们要做的就是强制编译器将内存读取为浮点数,这给了我们想要的结果。

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). nan is 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:

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 unsigned to a float would result in the compiler creating a float of 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文