Debugger disagrees with the FEZ Panda II!

I have a function to check for NaN values in my code. As per the spec, this is done by comparing for equality against itself:


public static bool IsNaN(double x)
{
	return x != x;
}

I then pass it a value which is known to be NaN. This should return true. If I stick a breakpoint at the return line, and select “x != x”, Visual Studio shows me that the value is true. Great! But when I do a “Debug.Print” on the result, I get false.

What the hell is going on here? Are floating point operations implemented incorrectly on the processor?

Is there any other way to detect a NaN value?

EDIT: Actually, it’s better than that:


Debug.Print("" + nanValue != nanValue); //True
Debug.Print("" + IsNaN(nanValue)); //False

What’s going on here?

Thanks

There was something about this IIRC. Have you tried this on emulator?

No. There wouldn’t be any point. It works in the debugger, so it’ll work in the emulator.

More info here:

This is code based on the IEEE standard 754 .


	// @ struct IEEE_DOUBLEREP | allows bit access to 8 byte floats
	//[StructLayout(LayoutKind.Sequential)]
	//public struct ieee_doublerep
	//{
	//    ulong low_mantissa;		// @ field low 16 bits of mantissa
	//    ushort mid_mantissa;	// @ field mid 16 bits of mantissa
	//    uint high_mantissa:4;		// @ field high 4 bits of mantissa
	//    uint exponent:11;			// @ field exponent of floating point number
	//    uint sign:1;				// @ field sign of floating point number
	//};

	public struct DoubleEx
	{
		public const long NANMASK = 0x7FF0000000000000;
		public const long INFINITYMASK = 0x000FFFFFFFFFFFFF;

		public const double NaN = 0.0f / 0.0f;
		public const double NegativeInfinity = -1.0f / 0.0f;
		public const double PositiveInfinity = 1.0f / 0.0f;
		public static bool IsNaNBad(double x)
		{
			return x != x;
		}

		public unsafe static bool IsNaN(double value)        
		{
			long rep = *((long*)&value);
			return ((rep & NANMASK) == NANMASK &&
					((rep & INFINITYMASK) != 0));
		}

		public unsafe static bool IsPositiveInfinity(double value)
		{
			double negInf = DoubleEx.PositiveInfinity;
			return *((long*)&value) == *((long*)&negInf);
		}

		public unsafe static bool IsNegativeInfinity(double value)
		{
			double posInf = DoubleEx.PositiveInfinity;
			return *((long*)&value) == *((long*)&posInf);
		}

		public unsafe static bool IsInfinite(double x)
		{
			long rep = *((long*)&x);
			return ((rep & NANMASK) == NANMASK &&
					((rep & INFINITYMASK) == 0));
		}
	}

When using Debub.Print, all values should be strings.

For example,

Debug.Print(“xxx=” + (1 == 1).ToStrilng());

See if that helps.

I realize that this is a very old thread, but it came up in my search. What ever came of this? Is there something wrong with double comparisons in involving NaN?

I just encountered something similar and very strange. On a G80 a have a double variable called “new_value” and a double property of the class called “Value”. “new_value” is 0.5 and “Value” is NaN.

My program on the G80 evaluates “new_value != Value” as false :astonished:

Visual Studio evaluates “new_value != Value” correctly as true in the Watch or Immediate windows.

Can you post a small example that shows different behavior on desktop and the device? Is this NETMF or TinyCLR?

This is NETMF v4.3 with GHI SDK 2016 R1,

I took out all of my specific application. Here is a simple test code:

using System;
using Microsoft.SPOT;

namespace TestNaN
{
    public class Program
    {
        public static void Main()
        {
            double new_value = 0.5;
            double Value = double.NaN;
            bool equal = new_value == Value;
            bool not_equal = new_value != Value;
        }
    }
}

Here is a copy/paste from the Watch window in Visual Studio 2013:

		new_value	        0.5	double
		Value	                NaN	double
		equal	                true	bool
		not_equal	        false	bool
		new_value == Value	false	bool
		new_value != Value	true	bool

The results are strange. The variable “equal” should be false, as entering “new_value == Value” into Visual Studio is. Likewise, the variable “not_equal” should be true, as the expression “new_value != Value” is in Visual Studio.

Are the “equal” and “not_equal” variables evaluated and assigned to on the microcontroller, while the expressions entered into the Watch window are evaluated differently, i.e. by Visual Studio?

Do you see this? If not, I guess it’s possible that my whole system is corrupted somehow. I’ve been having several problems lately that apparently others don’t see, e.g. Serial deploy to G80 with FEZ Config or MFDeploy

I’m going to try rebooting again… Rebooting did NOT fix it.

I may try reinstalling everything… (please let me know if it is reproducible. If so, I won’t go through all the trouble)

You are not using “good practices” to check for equality with doubles…
You should use

bool equal = Equals(new_value, Value);

Unfortunately the same incorrect behavior appears to happen in the emulator as it does on the device, so it’s an issue in the NETMF core.

@John_Brochue - I wish the news was better, but thank you for checking. I will work around it in my software from now on.

What are the chances of this being fixed sometime?

I can’t say one way or the other in NETMF. If you verify the same bug in the emulator, you can always open an issue on the NETMF GitHub repo.