如何在c中生成NaN浮点数?

发布于 2024-12-01 10:41:21 字数 361 浏览 2 评论 0 原文

float f = (float)'a';
if(f < 0){ 
}   
else if(f == 0){ 
}   
else if(f > 0){ 
}   
else{
    printf("NaN\n");                                                          
}   

如果 fNaN,则它不会大于/等于/小于 0

但首先如何产生这样的 f 呢?

我尝试了各种方法来产生 NaN,但没有任何效果。

float f = (float)'a';
if(f < 0){ 
}   
else if(f == 0){ 
}   
else if(f > 0){ 
}   
else{
    printf("NaN\n");                                                          
}   

f won't be greater/equal/less than 0 if it's a NaN.

But how to produce such a f in the first place?

I tried various ways to produce a NaN,but none work..

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

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

发布评论

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

评论(9

情深已缘浅 2024-12-08 10:41:21

使用浮点数时,0.0 / 0.0 不是“除以零”错误;而是错误。它的结果是NaN

此 C 程序打印 -nan

#include <stdio.h>

int main()
{
    float x = 0.0 / 0.0;
    printf("%f\n", x);
    return 0;
}

NaN 对计算机而言,两个“无效”数字被保留用于“signaling”和“quiet”NaN(类似于为正无穷和负无穷保留的两个无效数字)。 维基百科条目提供了有关 NaN 如何表示为 IEE 浮点数的更多详细信息。

Using floating point numbers, 0.0 / 0.0 isn't a "divide by zero" error; it results in NaN.

This C program prints -nan:

#include <stdio.h>

int main()
{
    float x = 0.0 / 0.0;
    printf("%f\n", x);
    return 0;
}

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.

抽个烟儿 2024-12-08 10:41:21

要生成 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.h

The 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)

同展鸳鸯锦 2024-12-08 10:41:21

您可以使用 NAN 宏,或仅使用 nan/nanf 函数之一将 nan 值分配给变量。
要检查您是否正在处理 nan 值,可以使用 isnan() 。
下面是一个示例:

#include <stdio.h>
#include <math.h>

int main(void) {

    float a = NAN;//using the macro in math.h
    float f = nanf("");//using the function version 
    double d = nan("");//same as above but for doubles!

    printf("a = %f\nf = %f\nd = %f\n",a,f,d);

    if(isnan(a))
        puts("a is a not a number!(NAN)\n");

    return 0;
}

运行上面的代码片段将为您提供以下输出:

a = nan
f = nan
d = nan
a is a not a number!(NAN)

自己运行代码: http://ideone.com/ WWZBl8
阅读更多信息:http://www.cplusplus.com/reference/cmath/NAN/

You can either use NAN macro, or simply one of nan/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:

#include <stdio.h>
#include <math.h>

int main(void) {

    float a = NAN;//using the macro in math.h
    float f = nanf("");//using the function version 
    double d = nan("");//same as above but for doubles!

    printf("a = %f\nf = %f\nd = %f\n",a,f,d);

    if(isnan(a))
        puts("a is a not a number!(NAN)\n");

    return 0;
}

Running the code snippet above will give you this output:

a = nan
f = nan
d = nan
a is a not a number!(NAN)

Run the code yourself : http://ideone.com/WWZBl8
read more information : http://www.cplusplus.com/reference/cmath/NAN/

无语# 2024-12-08 10:41:21

根据 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

傲影 2024-12-08 10:41:21

对于托管 C 实现,可以执行 #include 并使用 NAN 宏(如果已定义)。例如,对于 GCC,它是通过内置函数实现的:(__builtin_nanf (""))

对于独立的 C 实现( 标头可能不可用)或未定义 NAN 宏时(即使 NaN 可能会发生这种情况)支持),可以通过浮点运算(例如 0.0 / 0.0)生成 NaN。然而,它可能存在几个问题。

首先,这样的操作也会生成异常,在某些 C 实现上可能会出现陷阱。我们可以确保它是在编译时计算的:

static double my_nan = 0.0 / 0.0;

另一个问题是 Microsoft Visual C++(至少某些版本)尝试在编译时计算 0.0 / 0.0 (即使当此表达式位于代码中的任意位置)并抱怨其有效性。因此,这里的解决方案是相反的:确保编译器不会在编译时评估它,方法是:

static double zero = 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 the NAN 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 the NAN 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 as 0.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:

static double my_nan = 0.0 / 0.0;

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:

static double zero = 0.0;

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.

糖果控 2024-12-08 10:41:21

还可以通过将浮点变量的所有 32 位设置为 1 来生成 -nan,如下所示:

float nan_val = 0xffffffff;

此外,您还可以显式比较浮点变量是否为 -nan通过检查与自身的比较是否失败。

if (nan_val != nan_val) {
// executes iff nan_val is -nan
}

这种比较方法应该适用于使用 IEEE 浮点数的编译器。

A -nan can also be produced by setting all 32 bits of a float variable as 1, as shown below:

float nan_val = 0xffffffff;

Also, you can compare if a float variable is -nan explicitly by checking if comparison with itself fails.

if (nan_val != nan_val) {
// executes iff nan_val is -nan
}

This method of comparison should work for compilers that use IEEE floats.

佞臣 2024-12-08 10:41:21

这也适用于常量(0/0 将在 vs 上给出编译器错误):

const unsigned maxU = ~0;
const float qNan =  *((float*)&maxU);

This works for constants too (0/0 will give a compiler error on vs):

const unsigned maxU = ~0;
const float qNan =  *((float*)&maxU);
梦境 2024-12-08 10:41:21

以下 C 程序将产生 NaN。第二条语句将产生 NaN。

#include <stdio.h>
#include <tchar.h>
#include "math.h"

int _tmain(int argc, _TCHAR* argv[])
{
    double dSQRTValue = sqrt( -1.00 ); 
    double dResult = -dSQRTValue;  // This statement will result in a NaN.
    printf( "\n %lf", dResult );

    return 0;
}

以下是程序的输出。

1.#QNAN0

Following C program will produce a NaN. The second statement will result in a NaN.

#include <stdio.h>
#include <tchar.h>
#include "math.h"

int _tmain(int argc, _TCHAR* argv[])
{
    double dSQRTValue = sqrt( -1.00 ); 
    double dResult = -dSQRTValue;  // This statement will result in a NaN.
    printf( "\n %lf", dResult );

    return 0;
}

Following will be the output of the program.

1.#QNAN0

烈酒灼喉 2024-12-08 10:41:21

当我们编程包含像 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).

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