This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

NaN detection in DP FP operations

Hello all,


I expected to detect the NaN result after the Double-Precision Floating-Point operations
with the conventional condition: if(!(result == result))
But I have got some subitaneous results that depend from variables declarations and
from Optimization modes.
I used the following program:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "math.h"

void main(void)
{
double val2=-0.182147, val3=0.0, val4=0.0; //volatile double val2=-0.182147, val3=0.0, val4=0.0;
double result=3.3; //volatile double result=3.3;

result = sqrt(val2); // Square-Root from negative number = expected as NaN
if( !(result == result) ) printf("row=12 result= %17lf \r\n",result);
if( result == result ) printf("row=13 result= %17lf \r\n",result);

result = val3/val4; // 0.0/0.0 = expected as NaN
if( !(result == result) ) printf("row=16 result= %17lf \r\n",result);
if( result == result ) printf("row=17 result= %17lf \r\n",result);

result = (1.0/val3)/(1.0/val4); // +inf/+inf = expected as NaN
if( !(result == result) ) printf("row=20 result= %17lf \r\n",result);
if( result == result ) printf("row=21 result= %17lf \r\n",result);

result = (-1.0/val3) + (1.0/val4); // (-inf) + (+inf) = expected as NaN
if( !(result == result) ) printf("row=24 result= %17lf \r\n",result);
if( result == result ) printf("row=25 result= %17lf \r\n",result);

// Double-Precision Floating-Point Square-Root Reciprocal Approximation
result = _rsqrdp (val2); // _rsqrdp from negative number = expected as NaN
if( !(result == result) ) printf("row=29 result= %17lf \r\n",result);
if( result == result ) printf("row=30 result= %17lf \r\n",result);

printf("THE END ===================================== \r\n");
}


I have done four experiments:

1st case:
----------
volatile double val2=-0.182147, val3=0.0, val4=0.0;
volatile double result=3.3;
Optimization -> "empty"; Advanced Optimization -> "empty"

[C66xx_0] row=13 result= 0.000000
[C66xx_0] row=16 result= nan
[C66xx_0] row=20 result= nan
[C66xx_0] row=24 result= nan
[C66xx_0] row=29 result= nan

2nd case:
----------
volatile double val2=-0.182147, val3=0.0, val4=0.0;
volatile double result=3.3;
Optimization -> "2"; Advanced Optimization -> "2"

[C66xx_0] row=13 result= 0.000000
[C66xx_0] row=16 result= nan
[C66xx_0] row=20 result= nan
[C66xx_0] row=24 result= nan
[C66xx_0] row=29 result= nan

In 1st and 2nd cases all work as expected, except sqrt() which do not return NaN from negative argument.

3rd case:
----------
double val2=-0.182147, val3=0.0, val4=0.0;
double result=3.3;
Optimization -> "empty"; Advanced Optimization -> "empty"

[C66xx_0] row=13 result= 0.000000
[C66xx_0] row=16 result= nan
[C66xx_0] row=20 result= nan
[C66xx_0] row=24 result= nan
[C66xx_0] row=29 result= nan

In 3rd case
all work as expected (except sqrt() which always do not return NaN from negative argument)

4th case:
----------
double val2=-0.182147, val3=0.0, val4=0.0;
double result=3.3;
Optimization -> "2"; Advanced Optimization -> "2"

[C66xx_0] row=13 result= 0.000000
[C66xx_0] row=17 result= nan
[C66xx_0] row=21 result= 1.000000
[C66xx_0] row=25 result= nan
[C66xx_0] row=30 result= nan

In 4th case
division (+inf)/(+inf) returns 1.0 instead of NaN (may be Optimization cansels 0s in the fraction),
but
I have got more strange results here:
division (0.0)/(0.0) returns NaN, but NaN==NaN (row17) that contradicts with the NaN definition;
sum (-inf) + (+inf) returns NaN, but NaN==NaN (row25) that contradicts with the NaN definition;
function _rsqrdp() returns NaN, but NaN==NaN (row30) that contradicts with the NaN definition.


Please answer on  two questions:
1) why do function sqrt() from negative argument do not return NaN ?
2) why do NaN==NaN in 4th case ?


I used:
Code Composer Studio 5.2.1.00018
Compiler version 7.4.7
mcsdk_2_01_02_06
MDSEVM6678L/MDXEVMPCI boards


Best regards.

 

 

 

 

        

  • Hi Viktor,
    I have requested our team member to address this post however please check whether below wiki helps you. Please ignore if you have refered already,
    processors.wiki.ti.com/.../Floating_Point_Optimization

    Thank you for your patience.
  • Hi Rajasekaran,

    Thank you for the wiki help, but it does not clear up mentioned results.

    As I wrote results depend from variables declarations(e.g. presense or absense of "volatile") and from Optimization modes.

    In 1st and 2nd cases code produces expected results,  but  in 4th case the same code produces results which contradict with the NaN definition. 

    As I think  if(NaN==NaN) must return "False".   But the same operator returns "False" in one case and "True" in another.  

    Regards,

    Viktor.

  • Hi Viktor,

    Thanks for your update.

    Yes, you are right. NaN cannot be equal to NaN.  Again, if (NaN==NaN) should always return false and if (NaN!=NaN) should always return true but usually, these NaN values would behave strange when on any arithmetic expression is involved. This has been experienced by many users and as you say, it will behave random like the same NaN operator would return false in one case and true in some other case.

    It is better recommended to avoid arithmetic expression generating NaN value and in particular, we may not give any reason to this  atleast for timebeing.

    But, let me try to explore more on this and will provide more insight if possible.

    Thanks & regards,

    Sivaraj K

    -------------------------------------------------------------------------------------------------------

    Please click the Verify Answer button on this post if it answers your question.

    -------------------------------------------------------------------------------------------------------

  • Hi Viktor,

    from Wikipedia:
    A comparison with a NaN always returns an unordered result even when comparing with itself.
    en.wikipedia.org/.../NaN

    Better is isnan function:
    www.cplusplus.com/.../isnan

    Kind regards,
    one and zero
  • Hi Sivaraj,

    >always returns an unordered result...
    No.
    As I wrote operator if(NaN==NaN) returns "False" in case1 and case2

    Thank you for your suggest.

    Regards,
    Viktor.
  • Hi Sivaraj,

    One question remains.
    Why do
    sqrt(negative number) return 0 ?

    As wroten in
    www.cplusplus.com/.../isnan
    isnan(sqrt(-1.0)) return True,
    so sqrt(-1.0) must return NaN.

    Thank you

    Regards,
    Viktor.