C# 是什么导致这种行为异常?

C# 是什么导致这种行为异常?,c#,.net-micro-framework,C#,.net Micro Framework,我在一个几乎没有双精度/数学库(NETMF)的环境中工作。我写这门课是为了让事情变得更简单: public struct DoubleEx { public const double NaN = 0.0d / 0.0d; public static bool IsNaN(double x) { return x != x; } ... } 看起来应该有用,对吧 嗯,当我运行此代码时: Debug.Print("Method call: "

我在一个几乎没有双精度/数学库(NETMF)的环境中工作。我写这门课是为了让事情变得更简单:

public struct DoubleEx
{
    public const double NaN = 0.0d / 0.0d;
    public static bool IsNaN(double x)
    {
        return x != x;
    }
    ...
}
看起来应该有用,对吧

嗯,当我运行此代码时:

Debug.Print("Method call: " + DoubleEx.IsNaN(DoubleEx.NaN));
Debug.Print("Method call: " + DoubleEx.NaN != DoubleEx.NaN);
我得到这个输出:

False
True

不知怎的,把它放在函数中的行为破坏了它!这里是否进行了某种优化?还是硬件误解了指令?

您是否尝试过
返回x==NaN
?对我来说,假设x似乎不是一个好的做法!=x与“IsNaN”同义。

存在运算符优先级问题,将其放入函数中会更改表达式

尝试:


那么:

static bool DoubleInequal(double a, double b) { return a != b; }
static bool IsNaN(double x) { return DoubleInequal(x, x + 0.0); }

以下内容基于IEEE标准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));
    }
}

根据定义,
NaN==x
对x的所有值返回false。然而,如果我将此添加到我的代码中,我会得到更令人震惊的结果,
Double.IsNaN(0)
是真的@杰森:令人担忧的是,它确实检测到了NaN。它还做的事情是0是NaN@埃里克:你用的是什么处理器?它是否有IEEE浮点,或者.NETMF在软件中模拟浮点运算,甚至可能根本没有NaN的逻辑?一个FEZ Panda II。我问过世跆联在他们的论坛上有什么进展。我的最后期限很紧,如果能知道发生了什么,我将不胜感激。@Eric:好的,找到了那块板,结果是一个ARM7TDMI,我想NaN没有被很好地模仿。太好了。这同样适用于浮点数吗?@Eric:根据另一个问题,单精度应该是好的。
// @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));
    }
}