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

时间:2022-05-15 21:24:02
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.

如果是NaN, f不会大于/等于/小于0。

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

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

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

我尝试了各种方法来制作一个奶嘴,但都没有用。

8 个解决方案

#1


17  

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

使用浮点数,0.0 / 0.0不是“除零”错误;它在南结果。

This C program prints -nan:

这个C程序打印-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.

至于NaN在计算机上是什么样子,两个“无效”的数字被保留为“信令”和“安静”的NaN(类似于两个为正无穷和负无穷保留的无效数字)。*条目中有更多关于NaN如何表示为IEE浮点数的详细信息。

#2


17  

To produce a nan, there are a few ways:

要产生一个nan,有几种方法:

1) generate it manually (read ieee754 to set up the bits properly)

1)手动生成(读取ieee754以正确设置位)

2) use a macro. GCC exposes a macro NAN. It's defined in math.h

2)使用宏。GCC公开一个宏NAN。这是math.h中定义

The general way to check for a nan is to check if (f == f) (which should fail for nan values)

检查nan的一般方法是检查是否(f == f) (nan值应该失败)

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,浮点表示法中的指数位应该全部设置为1 (float包含有符号位、一组指数位和一组尾数)

#3


3  

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.

来自GNU GCC手册的数学。h定义宏,允许显式地将变量设置为∞或NaN。由于这是C99的一部分,我希望您可以将以下宏与其他符合C99的编译器一起使用。

— 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.

-宏:浮点无穷大一个表示正无穷大的表达式。它等于像1.0 / 0.0这样的数学运算产生的值。∞代表负无穷。

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.

您可以通过将浮点值与这个宏进行比较来测试它是否为无穷大。然而,这是不推荐的;你应该使用islimited宏。看到浮点类。

This macro was introduced in the ISO C99 standard.

这个宏是在ISO C99标准中引入的。

— 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.

-宏:表示“不是数字”的值的浮点数。这个宏是GNU的扩展,只能在支持“不是数字”值的机器上使用——也就是说,在所有支持IEEE浮点数的机器上。

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

您可以使用“#ifdef NAN”来测试机器是否支持NAN。(当然,您必须安排GNU扩展是可见的,例如通过定义_GNU_SOURCE,然后必须包含math.h)。

for further information you can see here: http://www.gnu.org/s/hello/manual/libc/Infinity-and-NaN.html

要了解更多信息,请参见:http://www.gnu.org/s/hello/manual/libc/infining-andnan.html

#4


2  

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:

您可以使用NAN宏,或者简单地使用一个NAN /nanf函数来为变量赋值。要检查是否处理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;
}

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/

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

#5


1  

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

这也适用于常量(0/0会在vs上产生编译错误):

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

#6


1  

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 ("")).

对于托管的C实现,可以做一个包括 ,定义使用NAN宏。例如,使用GCC时,它是通过内置的:(__builtin_nanf("))实现的。 。h>

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.

对于独立的C实现(在其上 头可能不可用)或当NAN宏没有定义(即使可能支持NAN的)时,可以使用浮点操作(如0.0 / 0.0)生成一个NAN。然而,它可能有几个问题。 。h>

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:

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

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:

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

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.

然后用0 / 0。由于这些解决方案是相互冲突的,我们可以使用预处理器指令(#if…)在特定的宏上测试编译器。

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.

您也可以选择基于NaN编码的解决方案,但是还有可移植性问题。首先,IEEE 754标准没有完全定义NaN的编码,特别是区分安静和信令NaNs的方式(实际上硬件不同);发送NaNs信号将产生未定义的行为。此外,IEEE 754标准没有定义如何在内存中表示位字符串,也就是说,可能需要检测到endianness。如果解决了这些问题,那么使用指针强制转换的联合或无符号字符数组就可以获得浮点类型。不要使用一个带指针在地址上的整数来做双关语,因为这会打破C别名规则。

#7


0  

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

遵循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;
}

Following will be the output of the program.

下面是程序的输出。

1.#QNAN0

1 . # QNAN0

#8


0  

nan is produced when we program contain value like 0.0/0.0 as said by @Dan Cecile OR sqrt(-1).

nan是在我们的程序包含值时产生的,如@Dan Cecile或sqrt(-1)所说的0/0.0。

#1


17  

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

使用浮点数,0.0 / 0.0不是“除零”错误;它在南结果。

This C program prints -nan:

这个C程序打印-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.

至于NaN在计算机上是什么样子,两个“无效”的数字被保留为“信令”和“安静”的NaN(类似于两个为正无穷和负无穷保留的无效数字)。*条目中有更多关于NaN如何表示为IEE浮点数的详细信息。

#2


17  

To produce a nan, there are a few ways:

要产生一个nan,有几种方法:

1) generate it manually (read ieee754 to set up the bits properly)

1)手动生成(读取ieee754以正确设置位)

2) use a macro. GCC exposes a macro NAN. It's defined in math.h

2)使用宏。GCC公开一个宏NAN。这是math.h中定义

The general way to check for a nan is to check if (f == f) (which should fail for nan values)

检查nan的一般方法是检查是否(f == f) (nan值应该失败)

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,浮点表示法中的指数位应该全部设置为1 (float包含有符号位、一组指数位和一组尾数)

#3


3  

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.

来自GNU GCC手册的数学。h定义宏,允许显式地将变量设置为∞或NaN。由于这是C99的一部分,我希望您可以将以下宏与其他符合C99的编译器一起使用。

— 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.

-宏:浮点无穷大一个表示正无穷大的表达式。它等于像1.0 / 0.0这样的数学运算产生的值。∞代表负无穷。

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.

您可以通过将浮点值与这个宏进行比较来测试它是否为无穷大。然而,这是不推荐的;你应该使用islimited宏。看到浮点类。

This macro was introduced in the ISO C99 standard.

这个宏是在ISO C99标准中引入的。

— 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.

-宏:表示“不是数字”的值的浮点数。这个宏是GNU的扩展,只能在支持“不是数字”值的机器上使用——也就是说,在所有支持IEEE浮点数的机器上。

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

您可以使用“#ifdef NAN”来测试机器是否支持NAN。(当然,您必须安排GNU扩展是可见的,例如通过定义_GNU_SOURCE,然后必须包含math.h)。

for further information you can see here: http://www.gnu.org/s/hello/manual/libc/Infinity-and-NaN.html

要了解更多信息,请参见:http://www.gnu.org/s/hello/manual/libc/infining-andnan.html

#4


2  

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:

您可以使用NAN宏,或者简单地使用一个NAN /nanf函数来为变量赋值。要检查是否处理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;
}

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/

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

#5


1  

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

这也适用于常量(0/0会在vs上产生编译错误):

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

#6


1  

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 ("")).

对于托管的C实现,可以做一个包括 ,定义使用NAN宏。例如,使用GCC时,它是通过内置的:(__builtin_nanf("))实现的。 。h>

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.

对于独立的C实现(在其上 头可能不可用)或当NAN宏没有定义(即使可能支持NAN的)时,可以使用浮点操作(如0.0 / 0.0)生成一个NAN。然而,它可能有几个问题。 。h>

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:

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

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:

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

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.

然后用0 / 0。由于这些解决方案是相互冲突的,我们可以使用预处理器指令(#if…)在特定的宏上测试编译器。

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.

您也可以选择基于NaN编码的解决方案,但是还有可移植性问题。首先,IEEE 754标准没有完全定义NaN的编码,特别是区分安静和信令NaNs的方式(实际上硬件不同);发送NaNs信号将产生未定义的行为。此外,IEEE 754标准没有定义如何在内存中表示位字符串,也就是说,可能需要检测到endianness。如果解决了这些问题,那么使用指针强制转换的联合或无符号字符数组就可以获得浮点类型。不要使用一个带指针在地址上的整数来做双关语,因为这会打破C别名规则。

#7


0  

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

遵循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;
}

Following will be the output of the program.

下面是程序的输出。

1.#QNAN0

1 . # QNAN0

#8


0  

nan is produced when we program contain value like 0.0/0.0 as said by @Dan Cecile OR sqrt(-1).

nan是在我们的程序包含值时产生的,如@Dan Cecile或sqrt(-1)所说的0/0.0。