Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between underflow and nan in C?

Currently I'm learning about floating point exceptions. I'm writing a loop with a function. In that function a value is calculated that equals 0.5. As the loop proceeds, the input value gets divided by 10.

The loop:

 for(i = 0; i < e; i++)
 {
     xf /= 10.0;   // force increasingly smaller values for x
     float_testk (xf, i);
 }

The function:

void float_testk(float x, int i)
{
    float result;
   
    feclearexcept(FE_ALL_EXCEPT); // clear all pending exceptions
         
    result = (1 - cosf(x)) / (x * x);
        
    if(fetestexcept(FE_UNDERFLOW) != 0)
        fprintf(stderr,"Underflow occurred in double_testk!\n");
    if(fetestexcept(FE_OVERFLOW) != 0)
        fprintf(stderr,"Overflow occurred in double_testk!\n");
    if(fetestexcept(FE_INVALID) != 0)
        fprintf(stderr,"Invalid exception occurred in double_testk!\n");
   
    printf("Iteration %3d, float result for x=%.8f : %f\n",i,x,result);
}

The first few iterations the output is around 0.5 and later it becomes 0 due CC. After a while this is the output of the program:

Iteration  18, float result for x=0.00000000 : 0.000000
Underflow occurred in double_testk!
Iteration  19, float result for x=0.00000000 : 0.000000
Underflow occurred in double_testk!
Iteration  20, float result for x=0.00000000 : 0.000000
Underflow occurred in double_testk!
Iteration  21, float result for x=0.00000000 : 0.000000
Underflow occurred in double_testk!
Invalid exception occurred in double_testk!
Iteration  22, float result for x=0.00000000 : -nan
Underflow occurred in double_testk!
Invalid exception occurred in double_testk!

I want to know what happens at the transition from underflow to NaN. Because underflow means that the number is too small to be stored in the memory.

But if the number is already too small, what is the goal of NaN?

like image 300
Tim Avatar asked Sep 23 '20 16:09

Tim


People also ask

What is underflow in C?

What is Integer Underflow in C? Integer Underflow occurs when we attempt to store a value that is "less" than the least representable integer. This is very similar to Overflow but in the opposite direction.

What is underflow with example?

Underflow can in part be regarded as negative overflow of the exponent of the floating point value. For example, if the exponent part can represent values from −128 to 127, then a result with a value less than −128 may cause underflow.

What is the difference between overflow and underflow?

2. Overflow and Underflow. Simply put, overflow and underflow happen when we assign a value that is out of range of the declared data type of the variable. If the (absolute) value is too big, we call it overflow, if the value is too small, we call it underflow.

How is NaN represented in C?

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

What is the difference between Overflow and underflow in C++?

You get overflow in both floating point and integer numbers, but underflow occurs only in floating point numbers. If you’re using real time data queues, overflow occurs when input is coming in faster than needed processing time allowed for data that you’re storing in the queue, and this can be a cause of unfortunate misch

What does Nan mean in C programming?

What is NaN in C programming? 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.

What does underflow mean?

the condition in a computer program that can occur when the true result of a floating point operation is smaller in magnitude (that is, closer to zero) than the smallest value representable as a normal floating point number in the target datatype. float x = 1e-30; x /= 1e20; // Underflow!

What is stack underflow in C++?

Stack underflow occurs when the programmer attempts to read a value from an empty stack and the value of the memory address before the start of the stack is read. Both cases result in corrupted data, which is a form of program error.


2 Answers

Because underflow means that the number is too small to be stored in the memory.

Not quite; in floating-point, underflow means a result is below the range at which numbers can be represented with full precision. The result may still be fairly accurate.

As long as x is at least 2−75, x * x produces a non-zero result. It may be in the subnormal part of the floating-point domain, where the precision is declining, but the real-number result of xx is big enough to round to 2−149 or greater. Then, for these small x, (1 - cosf(x)) / (x * x) evaluates to zero divided by a non-zero value, so the result is zero.

When x is less than 2−75, then x * x produces zero, because the real-number result of xx is so small that, in floating-point arithmetic, it is rounded to zero. Then (1 - cosf(x)) / (x * x) evaluates to zero divided by zero, so the result is a NaN. This is what happens in your iteration 22.

(2−149 is the smallest positive value representable in IEEE-754 binary32, which your C implementation likely uses for float. Real-number results between that and 2−150 will round up to 2−149. Lower results will round down to 0. Assuming the rounding mode is round-to-nearest, ties-to-even.)

like image 83
Eric Postpischil Avatar answered Oct 19 '22 23:10

Eric Postpischil


NaN is a concept defined in IEEE 754 standard for floating-point arithmetic, not being a number is not the same as negative infinity or positive infinity, NaN is used for arithmetic values that cannot be represented, not because they are too small or too large but simply because they don't exist. Examples:

1/0 = ∞ //too large     
log (0) = -∞ //too small
sqrt (-1) = NaN //is not a number, can't be calculated

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:

The goal of these flags you are using is to be compiant with the mentioned standard. It specifies five arithmetic exceptions that are to be recorded in the status flags:

FE_INEXACT: Inexact result, rounding was necessary to store the result of an earlier floating-point operation.

Set if the rounded (and returned) value is different from the mathematically exact result of the operation.

FE_UNDERFLOW: The result of an earlier floating-point operation was subnormal with a loss of precision.

Set if the rounded value is tiny (as specified in IEEE 754) and inexact (or maybe limited to if it has denormalization loss, as per the 1984 version of IEEE 754), returning a subnormal value including the zeros.

FE_OVERFLOW: The result of an earlier floating-point operation was too large to be representable.

Set if the absolute value of the rounded value is too large to be represented. An infinity or maximal finite value is returned, depending on which rounding is used.

FE_DIVBYZERO: Pole error occurred in an earlier floating-point operation.

Set if the result is infinite given finite operands, returning an infinity, either +∞ or −∞.

FE_INVALID: Domain error occurred in an earlier floating-point operation.

Set if a real-valued result cannot be returned e.g. sqrt(−1) or 0/0, returning a quiet NaN.*

*Concept of quiet NaN:

Quiet NaNs, or qNaNs, do not raise any additional exceptions as they propagate through most operations. The exceptions are where the NaN cannot simply be passed through unchanged to the output, such as in format conversions or certain comparison operations.

Sources:

Floating point environment

Floating-point arithmetic

20.5.2 Infinity and NaN

NaN

like image 44
anastaciu Avatar answered Oct 19 '22 22:10

anastaciu