Что такое nan в си
Перейти к содержимому

Что такое nan в си

  • автор:

Что такое nan в си

IEEE 754 floating point numbers can represent positive or negative infinity, and NaN (not a number). These three values arise from calculations whose result is undefined or cannot be represented accurately. You can also deliberately set a floating-point variable to any of them, which is sometimes useful. Some examples of calculations that produce infinity or NaN:

When a calculation produces any of these values, an exception also occurs; see FP Exceptions.

The basic operations and math functions all accept infinity and NaN and produce sensible output. Infinities propagate through calculations as one would expect: for example, 2 + ∞ = ∞, 4/∞ = 0, atan (∞) = π/2. NaN, on the other hand, infects any calculation that involves it. Unless the calculation would produce the same result no matter what real value replaced NaN, the result is NaN.

In comparison operations, positive infinity is larger than all values except itself and NaN, and negative infinity is smaller than all values except itself and NaN. NaN is unordered: it is not equal to, greater than, or less than anything, including itself. x == x is false if the value of x is NaN. You can use this to test whether a value is NaN or not, but the recommended way to test for NaN is with the isnan function (see Floating-Point Number Classification Functions). In addition, < , > , <= , and >= will raise an exception when applied to NaNs.

math.h defines macros that allow you to explicitly set a variable to infinity or NaN.

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 Number Classification Functions.

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

Macro: float SNANF ¶ Macro: double SNAN ¶ Macro: long double SNANL ¶ Macro: _FloatN SNANFN ¶ Macro: _FloatNx SNANFNx

These macros, defined by TS 18661-1:2014 and TS 18661-3:2015, are constant expressions for signaling NaNs.

Macro: int FE_SNANS_ALWAYS_SIGNAL

This macro, defined by TS 18661-1:2014, is defined to 1 in fenv.h to indicate that functions and operations with signaling NaN inputs and floating-point results always raise the invalid exception and return a quiet NaN, even in cases (such as fmax , hypot and pow ) where a quiet NaN input can produce a non-NaN result. Because some compiler optimizations may not handle signaling NaNs correctly, this macro is only defined if compiler support for signaling NaNs is enabled. That support can be enabled with the GCC option -fsignaling-nans .

IEEE 754 also allows for another unusual value: negative zero. This value is produced when you divide a positive number by negative infinity, or when a negative result is smaller than the limits of representation.

How to use nan and inf in C?

I have a numerical method that could return nan or inf if there was an error, and for testing purposed I’d like to temporarily force it to return nan or inf to ensure the situation is being handled correctly. Is there a reliable, compiler-independent way to create values of nan and inf in C?

After googling for about 10 minutes I’ve only been able to find compiler dependent solutions.

10 Answers 10

You can test if your implementation has it:

The existence of INFINITY is guaranteed by C99 (or the latest draft at least), and «expands to a constant expression of type float representing positive or unsigned infinity, if available; else to a positive constant of type float that overflows at translation time.»

NAN may or may not be defined, and «is defined if and only if the implementation supports quiet NaNs for the float type. It expands to a constant expression of type float representing a quiet NaN.»

Note that if you’re comparing floating point values, and do:

is false. One way to check for NaN would be:

You can also do: a != a to test if a is NaN.

There is also isfinite() , isinf() , isnormal() , and signbit() macros in math.h in C99.

C99 also has nan functions:

Renan Lopes's user avatar

There is no compiler independent way of doing this, as neither the C (nor the C++) standards say that the floating point math types must support NAN or INF.

Edit: I just checked the wording of the C++ standard, and it says that these functions (members of the templated class numeric_limits):

wiill return NAN representations «if available». It doesn’t expand on what «if available» means, but presumably something like «if the implementation’s FP rep supports them». Similarly, there is a function:

which returns a positive INF rep «if available».

These are both defined in the <limits> header — I would guess that the C standard has something similar (probably also «if available») but I don’t have a copy of the current C99 standard.

Explore NaN and Infinity in C Programming

In the world of programming, developers often encounter peculiar values like NaN (Not a Number) and Inf (Infinity) while working with floating-point numbers. These special values can be confusing, but understanding their meaning and use is essential for producing accurate and reliable programs. This article will explain how to use NaN and Inf in the C programming language and provide examples to help you better understand their significance.

1.1 Understanding NaN and Inf in C

NaN (Not a Number) is a special floating-point value that represents the result of an undefined or unrepresentable mathematical operation, such as the square root of a negative number or the division of zero by zero. NaN is unique in that it is the only value that is not equal to itself, which means that comparing a NaN value to another NaN value will always return false.

Infinity (Inf) is another special floating-point value that represents a number too large to be stored in the floating-point format. It can be the result of a mathematical operation that grows without bounds, such as dividing a positive number by zero. In C, there are two types of infinity: positive infinity and negative infinity.

In the following sections, we will explore how to represent and work with NaN and Inf in C, including creating and checking these values, performing arithmetic operations, and understanding their use cases and potential pitfalls.

2. Representing NaN and Infinity in C

Before we dive into working with NaN and Infinity in C, it’s essential to understand how to represent these special floating-point values.

2.1 The ‘math.h’ Library

To work with NaN and Infinity in C, you’ll need to include the math.h library. This library provides various mathematical functions, constants, and macros to facilitate calculations and manipulations of floating-point numbers.

Include the math.h library by adding the following line at the beginning of your C program:

#include <math.h>

2.2 Constants for NaN and Infinity

The math.h library provides predefined constants for NaN and Infinity that you can use in your C programs. These constants are platform-independent and ensure that your code remains portable and compatible across different systems.

To represent NaN, you can use the constant NAN. For positive infinity, use the constant INFINITY, and for negative infinity, use the expression -INFINITY.

Here’s an example of how to declare and initialize variables with NaN and Infinity:

Output:

NaN: 1.#QNAN0
Positive Infinity: 1.#INF00
Negative Infinity: -1.#INF00

Explanation:

This example demonstrates how to represent NaN and Infinity in C using the math.h library and predefined constants. The program initializes three floating-point variables with NaN, positive Infinity, and negative Infinity and then prints their values.

2.3 Macros from the math.h Library

  • The INFINITY macro from the math.h library represents positive infinity.
  • The -INFINITY macro represents negative infinity.
  • The NAN macro represents a NaN value.

These macros provide a convenient and standardized way to represent NaN and Infinity values in C, as specified by the C standard library.

2.4 Functions from the math.h Library

  • HUGE_VAL: This macro represents positive infinity in C. It is part of the math.h library and is used when the result of a mathematical operation overflows, resulting in a positive infinite value.
  • -HUGE_VAL: This is the negative counterpart of HUGE_VAL. It represents negative infinity and is used when the result of a mathematical operation overflows in the negative direction.
  • sqrt(): This is a standard mathematical function, part of the math.h library, that calculates the square root of a given number. When provided with a negative input, the square root is not defined for real numbers, so the sqrt() function returns a NaN value, indicating that the result is not a real number.

By using these functions and macros from the math.h library, you can generate NaN and Infinity values in your C code in a standardized and portable way.

2.5 Alternative Methods to Generate NaN and Infinity Values in C

2.5.1 C99 nan(), nanf(), and nanl() Functions

You can also use these functions from the C99 standard to generate NaN values. The functions are part of the math.h library and are available for different floating-point types:

  1. nan(): This function returns a quiet NaN value of type double. It takes a const char * argument, which can be used to specify a custom payload for the NaN value, although this feature is implementation-specific and not guaranteed to be supported.
  2. nanf(): This function works similarly to nan() , but it returns a quiet NaN value of type float. It also takes a const char * argument for specifying a custom payload, if supported by the implementation.
  3. nanl(): This function returns a quiet NaN value of type long double. Like the other nan functions, it takes a const char * argument for specifying a custom payload, if supported.

By using these C99 functions, you can generate NaN values in a standardized and portable way, ensuring that your code is compatible with different compiler implementations that support the C99 standard.

2.5.2 Using strtod()

You can make use of the strtod() function to generate NaN and Infinity values in C. The strtod() function is part of the stdlib.h library and is used to convert a string representation of a floating-point number to a double.

By providing specific string representations as input to the strtod() function, you can generate NaN and Infinity values:

  1. NaN: To generate a NaN value, you can provide the string «NaN» as an input to the strtod() function. The function will parse the string and return a quiet NaN value of type double.
  2. Infinity: To generate positive Infinity, you can provide the string «Inf» or «Infinity» as an input to the strtod() function. The function will parse the string and return a positive infinity value of type double.

Using the strtod() function allows you to generate NaN and Infinity values in a portable manner, as it is part of the C standard library and is supported by different compiler implementations.

2.5.3 Bit Manipulation (Assuming IEEE 754 Floating-Point Format)
  1. NaN: To generate a NaN value, you can set the exponent bits of a floating-point number to all ones (1s) and ensure that at least one of the significand (mantissa) bits is non-zero. This can be achieved by creating an integer with the appropriate bit pattern and then type-punning it to a floating-point type using a pointer or a union.
  2. Infinity: To generate Infinity values, you can set the exponent bits of a floating-point number to all ones (1s) and set all the significand (mantissa) bits to zero. For positive Infinity, the sign bit should be zero, and for negative Infinity, the sign bit should be one. Similar to NaN, you can create an integer with the desired bit pattern and type-pun it to a floating-point type.

Here’s an example demonstrating how to create NaN and Infinity values using bit manipulation, assuming the IEEE 754 floating-point format for single-precision floats:

Output:

NaN: 1.#QNAN0
Positive Infinity: 1.#INF00
Negative Infinity: -1.#INF00

  1. We define three uint32_t variables (nan_bits, pos_inf_bits, and neg_inf_bits) to represent the desired bit patterns for NaN, positive Infinity, and negative Infinity in single-precision floating-point format.
  2. We use pointer type-punning to convert the bit patterns to their corresponding float values.
  3. We print the generated NaN and Infinity values using printf().

Using bit manipulation can be an efficient way to create NaN and Infinity values, but it comes with the caveat that it assumes the target system uses the IEEE 754 floating-point format.

For maximum portability, it’s generally recommended to use C standard library functions or macros instead.

Note: This method assumes the IEEE 754 floating-point format and may not work on all systems. It might also trigger undefined behavior due to strict aliasing rules.

3. Working with NaN in C

In this section, we’ll explore how to create and work with NaN values in C programming.

3.1 Creating NaN Values

Apart from using the predefined constant NAN, you can also create NaN values by performing specific mathematical operations that yield undefined results. For example:

3.2 Checking for NaN Values

To check if a floating-point value is NaN, you can use the isnan() function from the math.h library:

Output:

The value is NaN.

  • We include the math.h and stdio.h header files.
  • Inside the main function, we create a NaN value by dividing 0 by 0.
  • We use the isnan() function to check if the value is NaN.
  • We print the result using printf.

Here’s another example that demonstrates how to work with NaN values in C:

Output:

a is NaN.
b is NaN.
c is not NaN.

  • We include the math.h and stdio.h header files.
  • Inside the main function, we create two NaN values (a and b) and one regular floating-point value (c).
  • We use the isnan() function to check if each value is NaN or not.
  • We print the results using printf.

4. Working with Infinity in C

In this section, we’ll explore how to create and work with Infinity values in C programming.

4.1 Creating Infinity Values

As mentioned in Section 2.3, you can create Infinity values using the predefined constants INFINITY and -INFINITY. However, you can also create Infinity values by performing specific mathematical operations that yield infinite results. For example:

4.2 Checking for Infinity Values

To check if a floating-point value is positive or negative infinity, you can use the isinf() function from the math.h library:

Output:

The value is positive infinity.

  • We include the math.h and stdio.h header files.
  • Inside the main function, we create a positive infinity value by dividing 1 by 0.
  • We use the isinf() function to check if the value is positive or negative infinity.
  • We print the result using printf.

Here’s another example that demonstrates how to work with Infinity values in C:

Output:

a is positive infinity.
c is not infinity.

  • We include the math.h and stdio.h header files.
  • Inside the main function, we create two infinity values (a and b) and one regular floating-point value (c).
  • We use the isinf() function to check if each value is positive or negative infinity.
  • We print the results using printf.

5. Arithmetic Operations with NaN and Infinity

In this section, we’ll discuss how arithmetic operations behave when NaN or Infinity values are involved.

5.1 Arithmetic Operations with NaN

When NaN is involved in any arithmetic operation, the result is typically NaN. Here are some examples:

  • NaN + x = NaN
  • NaN — x = NaN
  • NaN * x = NaN
  • NaN / x = NaN

Output:

NaN + 5 = 1.#QNAN0
NaN — 5 = 1.#QNAN0
NaN * 5 = 1.#QNAN0
NaN / 5 = 1.#QNAN0

  • We include the math.h and stdio.h header files.
  • Inside the main function, we perform arithmetic operations between a NaN value and a regular floating-point value.
  • We print the results using printf, which show that all the results are NaN.

5.2 Arithmetic Operations with Infinity

Arithmetic operations involving Infinity follow specific rules:

  • Infinity + x = Infinity (for x ≠ -Infinity)
  • Infinity — x = Infinity (for x ≠ Infinity)
  • Infinity * x = Infinity (for x > 0)
  • Infinity / x = Infinity (for x > 0)

Similar rules apply for negative Infinity.

  • Infinity — Infinity = NaN
  • Infinity * 0 = NaN
  • Infinity / Infinity = NaN

Output:

Infinity + 5 = 1.#INF00
Infinity — 5 = 1.#INF00
Infinity * 5 = 1.#INF00
Infinity / 5 = 1.#INF00

  • We include the math.h and stdio.h header files.
  • Inside the main function, we perform arithmetic operations between a positive Infinity value and a regular floating-point value.
  • We print the results using printf, which show that all the results are Infinity.

6. Use Cases for NaN and Infinity in C

Understanding and handling NaN and Infinity values is crucial in various real-world applications. In this section, we’ll discuss some of the applications where NaN and Infinity values play an important role.

6.1 Error Handling in Mathematical Functions

6.1.1 Division by Zero

Division by zero is a common scenario where Infinity and NaN can arise. Dividing a positive or negative number by zero results in positive or negative Infinity, while dividing zero by zero results in NaN.

6.1.2 Invalid Mathematical Operations

Performing invalid mathematical operations, such as taking the square root of a negative number, can also result in NaN values.

Example:

6.2 Placeholder Values in Arrays

NaN values can be used as placeholders in arrays to represent missing or invalid data. This approach is especially helpful when working with datasets that may have gaps or inconsistencies.

By using NaN as a placeholder, you can still perform calculations and operations on the array without disrupting the flow of your program.

Example:

In this example, the third element in the data array is a NaN value, representing a missing or invalid data point. You can later filter or replace these NaN values as needed.

6.3 Edge Cases in Algorithms

In certain algorithms, NaN and Infinity values can be used to handle edge cases or represent specific conditions.

For example, in an algorithm that finds the minimum value in an array, you can initialize the minimum value as positive Infinity. This ensures that any finite value encountered in the array will be smaller than the initial value, making it easier to find the minimum value.

Example:

Output:

The minimum value is: 1.200000

Explanation:

In this example, we use positive Infinity as the initial minimum value. As we iterate through the array, any finite value will be smaller than positive Infinity, allowing us to accurately find the minimum value.

6.4 Overflow and Underflow

Overflow and underflow in floating-point arithmetic can lead to Infinity and NaN values. For example, a very large positive number multiplied by another large positive number might result in positive Infinity, while a very small positive number divided by a very large positive number might result in NaN.

Example:

Output:

Overflow: 1.#INF00
Underflow: 0.000000

  1. We define two float variables, large_number and small_number, with very large and very small values, respectively.
  2. We calculate overflow by multiplying large_number by itself. This operation results in a value too large to be represented by a float, causing an overflow.
  3. We calculate underflow by dividing small_number by large_number. This operation results in a value too small to be represented by a float, causing an underflow.
  4. We print the resulting overflow and underflow values using printf().

This output demonstrates that the overflow operation resulted in positive Infinity (inf), while the underflow operation resulted in a value that is effectively zero (0.000000).

7. Potential Pitfalls and Best Practices

Working with NaN and Infinity values in C can lead to potential pitfalls. In this section, we’ll discuss some of these pitfalls and provide best practices to help you avoid them.

7.1 Comparing Floating-Point Numbers

Comparing floating-point numbers, including NaN and Infinity, can be tricky due to their unique properties. When comparing NaN values, it’s important to remember that NaN is not equal to any value, including itself. This can lead to unexpected results in your code. To safely compare floating-point numbers, you can use the isnan() and isinf() functions provided by the math.h library.

Example:

Output:

a is NaN
b is Infinity

In this example, we use isnan() and isinf() functions to check if a is NaN and b is Infinity, respectively.

7.2 Ensuring Portability and Compatibility

Different platforms and compilers may represent NaN and Infinity values differently. To ensure that your code is portable and compatible across platforms, you should use the NAN and INFINITY macros and the functions provided by the math.h library, as shown in previous examples.

Also, be cautious when serializing or deserializing floating-point numbers, as different platforms may have different representations for NaN and Infinity. Using standardized formats like IEEE 754 can help maintain compatibility when exchanging data between platforms.

8. Conclusion

In this article, we explored NaN and Infinity values in the C programming language, their properties, and how they can be used in various scenarios. We also discussed some real-world applications, implications, and potential pitfalls associated with these values, as well as best practices to help you avoid them.

By understanding and correctly handling NaN and Infinity values, you can create more robust, accurate, and reliable software applications. Keep in mind the unique properties and behaviors of these values and use the functions provided by the math.h library to work with them effectively.

We hope that this article has provided you with a solid foundation for working with NaN and Infinity values in C and that you can apply these concepts to your projects with confidence.

Что такое nan в си

Returns a quiet NaN (Not-A-Number) value of type double .

The values are used to identify undefined or non-representable values for floating-point elements, such as the square root of negative numbers or the result of 0/0.

The argument can be used by library implementations to distinguish different NaN values in a implementation-specific manner.

Similarly, nanf and nanl return NaN values of type float and long double , respectively.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *