如何在c中生成NaN浮点数?
float f = (float)'a';
if(f < 0){
}
else if(f == 0){
}
else if(f > 0){
}
else{
printf("NaN\n");
}
如果 f
是 NaN
,则它不会大于/等于/小于 0
。
但首先如何产生这样的 f
呢?
我尝试了各种方法来产生 NaN
,但没有任何效果。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
使用浮点数时,
0.0 / 0.0
不是“除以零”错误;而是错误。它的结果是NaN
。此 C 程序打印
-nan
:就
NaN
对计算机而言,两个“无效”数字被保留用于“signaling”和“quiet”NaN(类似于为正无穷和负无穷保留的两个无效数字)。 维基百科条目提供了有关 NaN 如何表示为 IEE 浮点数的更多详细信息。Using floating point numbers,
0.0 / 0.0
isn't a "divide by zero" error; it results inNaN
.This C program prints
-nan
:In terms what
NaN
looks like to the computer, two "invalid" numbers are reserved for "signaling" and "quiet" NaN (similar to the two invalid numbers reserved for positive and negative infinity). The Wikipedia entry has more details about how NaN is represented as an IEE floating point number.要生成 nan,有几种方法:
1) 手动生成它(读取 ieee754 来正确设置位)
2) 使用宏。 GCC 公开了一个宏
NAN
。它在 math.h 中定义。检查 nan 的一般方法是检查
if (f == f)
(这对于 nan 值应该失败)对于 nan,浮点表示中的指数位应该全部设置为 1(浮点数由一个有符号位、一组指数位和一组尾数位组成)
To produce a nan, there are a few ways:
1) generate it manually (read
ieee754
to set up the bits properly)2) use a macro. GCC exposes a macro
NAN
. It's defined in math.hThe general way to check for a nan is to check
if (f == f)
(which should fail for nan values)For nan, the exponent bits in the float representation should all be set to 1 (float consists of a signed bit, a set of exponent bits and a set of mantissa bits)
您可以使用
NAN
宏,或仅使用nan/nanf
函数之一将 nan 值分配给变量。要检查您是否正在处理 nan 值,可以使用 isnan() 。
下面是一个示例:
运行上面的代码片段将为您提供以下输出:
自己运行代码: http://ideone.com/ WWZBl8
阅读更多信息:http://www.cplusplus.com/reference/cmath/NAN/
You can either use
NAN
macro, or simply one ofnan/nanf
functions to assign a nan value to a variable.to check if you are dealing with a nan value, you can use
isnan()
.Here is an example:
Running the code snippet above will give you this output:
Run the code yourself : http://ideone.com/WWZBl8
read more information : http://www.cplusplus.com/reference/cmath/NAN/
根据 GNU GCC 手册,
math.h
定义了允许您将变量显式设置为无穷大或 NaN 的宏。由于这是 C99 的一部分,我希望您可以将以下宏与其他符合 c99 的编译器一起使用。— 宏:float INFINITY
表示正无穷的表达式。它等于 1.0 / 0.0 等数学运算产生的值。 -INFINITY 表示负无穷大。
您可以通过将浮点值与该宏进行比较来测试浮点值是否是无限的。但是,不建议这样做;你应该使用 isfinite 宏来代替。请参阅浮点类。
该宏是在 ISO C99 标准中引入的。
— 宏:浮动 NAN
表示“不是数字”的值的表达式。该宏是一个 GNU 扩展,仅在支持“非数字”值的机器上可用,也就是说,在所有支持 IEEE 浮点的机器上可用。
您可以使用'#ifdef NAN'来测试机器是否支持NaN。 (当然,您必须安排 GNU 扩展可见,例如通过定义 _GNU_SOURCE,然后您必须包含 math.h。)
有关更多信息,您可以在此处查看:
http://www.gnu.org/s/hello /manual/libc/Infinity-and-NaN.html
From the GNU GCC manual
math.h
defines macros that allow you to explicitly set a variable to infinity or NaN. Since this is a part of C99 you can use the following macros with other c99 compliant compilers i hope.— Macro: float INFINITY
An expression representing positive infinity. It is equal to the value produced by mathematical operations like 1.0 / 0.0. -INFINITY represents negative infinity.
You can test whether a floating-point value is infinite by comparing it to this macro. However, this is not recommended; you should use the isfinite macro instead. See Floating Point Classes.
This macro was introduced in the ISO C99 standard.
— Macro: float NAN
An expression representing a value which is “not a number”. This macro is a GNU extension, available only on machines that support the “not a number” value—that is to say, on all machines that support IEEE floating point.
You can use ‘#ifdef NAN’ to test whether the machine supports NaN. (Of course, you must arrange for GNU extensions to be visible, such as by defining _GNU_SOURCE, and then you must include math.h.)
for further information you can see here:
http://www.gnu.org/s/hello/manual/libc/Infinity-and-NaN.html
对于托管 C 实现,可以执行
#include
并使用NAN
宏(如果已定义)。例如,对于 GCC,它是通过内置函数实现的:(__builtin_nanf (""))
。对于独立的 C 实现(
标头可能不可用)或未定义NAN
宏时(即使 NaN 可能会发生这种情况)支持),可以通过浮点运算(例如0.0 / 0.0
)生成 NaN。然而,它可能存在几个问题。首先,这样的操作也会生成异常,在某些 C 实现上可能会出现陷阱。我们可以确保它是在编译时计算的:
另一个问题是 Microsoft Visual C++(至少某些版本)尝试在编译时计算
0.0 / 0.0
(即使当此表达式位于代码中的任意位置)并抱怨其有效性。因此,这里的解决方案是相反的:确保编译器不会在编译时评估它,方法是:然后使用
zero / zero
。由于这些解决方案是冲突的,因此可以使用 特定宏。也可以选择基于NaN编码的解决方案,但也存在可移植性问题。首先,IEEE 754标准没有完全定义NaN的编码,特别是区分安静和信令NaN的方式(并且硬件在实践中有所不同);发出 NaN 信号将产生未定义的行为。此外,IEEE 754标准没有定义如何在存储器中表示位串,即可能需要检测字节序。如果这些问题得到解决,则可以使用带有指针转换的联合或无符号字符数组来获取浮点类型。不要使用地址上带有指针的整数来进行类型双关,因为这会破坏 C 别名规则。
For hosted C implementations, one can do a
#include <math.h>
and use theNAN
macro if defined. For instance, with GCC, it is implemented by a builtin:(__builtin_nanf (""))
.For freestanding C implementations (on which the
<math.h>
header may not be available) or when theNAN
macro is not defined (which might happen even though NaN's may be supported), one can generate a NaN with a floating-point operation such as0.0 / 0.0
. However, there may be several issues with it.First, such an operation also generates an exception, with a possible trap on some C implementations. One can make sure that it is computed at compile time with:
Another issue is that Microsoft Visual C++ (at least some versions) attempts to evaluate
0.0 / 0.0
at compile time (even when this expression is in an arbitrary place in the code) and complains about its validity. So, the solution here is the opposite one: make sure that the compiler will not evaluate it at compile time, by doing:and then use
zero / zero
. Since these solutions are conflicting, one can test the compiler with preprocessor directives (#if
...) on specific macros.One may also choose a solution based on the NaN encoding, but there are also portability issues. First, the IEEE 754 standard does not completely define the encoding of a NaN, in particular the way to distinguish quiet and signaling NaNs (and hardware differs in practice); signaling NaNs will yield undefined behavior. Moreover, the IEEE 754 standard does not define how the bit string is represented in memory, i.e. the endianness may need to be detected. If these problems are solved, a union or an array of
unsigned char
with a pointer cast is fine to get the floating-point type. Do not use an integer with a pointer cast on its address to do type punning as this will break the C aliasing rules.还可以通过将浮点变量的所有 32 位设置为 1 来生成
-nan
,如下所示:此外,您还可以显式比较浮点变量是否为
-nan
通过检查与自身的比较是否失败。这种比较方法应该适用于使用 IEEE 浮点数的编译器。
A
-nan
can also be produced by setting all 32 bits of a float variable as 1, as shown below:Also, you can compare if a float variable is
-nan
explicitly by checking if comparison with itself fails.This method of comparison should work for compilers that use IEEE floats.
这也适用于常量(0/0 将在 vs 上给出编译器错误):
This works for constants too (0/0 will give a compiler error on vs):
以下 C 程序将产生 NaN。第二条语句将产生 NaN。
以下是程序的输出。
1.#QNAN0
Following C program will produce a NaN. The second statement will result in a NaN.
Following will be the output of the program.
1.#QNAN0
当我们编程包含像 0.0/0.0 这样的值时,就会产生 nan,正如 @Dan Cecile OR sqrt(-1) 所说。
nan is produced when we program contain value like 0.0/0.0 as said by @Dan Cecile OR sqrt(-1).