代码之家  ›  专栏  ›  技术社区  ›  LiraNuna

负楠不是楠?

  •  28
  • LiraNuna  · 技术社区  · 14 年前

    我试过用 std::isnan 但断言失败了:

    Assertion `std::isnan(x)' failed.
    

    x ,结果是阴性( -nan

    在试图利用 NaN != NaN 以及使用 assert(x == x) ,编译器帮了我一个“忙”,并优化了断言。

    isNaN 功能也在不断优化。

    如何检查NaN是否相等 -南?

    6 回复  |  直到 8 年前
        1
  •  35
  •   LiraNuna    14 年前

    这太尴尬了。

    编译器(在本例中是GCC)优化比较和 isnan false 是因为我的团队中有人 -ffast-math .

    -ffast-math
        Sets -fno-math-errno, -funsafe-math-optimizations,
        -fno-trapping-math, -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans and fcx-limited-range.
    
        This option causes the preprocessor macro __FAST_MATH__ to be defined.
    
        This option should never be turned on by any -O option since it can result in incorrect output for programs which depend on an exact implementation of IEEE or ISO rules/specifications for math functions. 
    

    注意结尾的句子- -法斯特数学

        2
  •  4
  •   sam hocevar    13 年前

    isnan() 预期具有未定义的行为 -ffast-math .

    这是我在测试套件中使用的:

    #if defined __FAST_MATH__
    #   undef isnan
    #endif
    #if !defined isnan
    #   define isnan isnan
    #   include <stdint.h>
    static inline int isnan(float f)
    {
        union { float f; uint32_t x; } u = { f };
        return (u.x << 1) > 0xff000000u;
    }
    #endif
    
        3
  •  1
  •   Chinmay Kanchi    14 年前

    这看起来像是库的实现中的一个bug isnan()

    std::isnan(std::abs(yourNanVariable));
    

    std::isnan(-NaN) true 在我的系统里。

    编辑 :带 -ffast-math -O NAN == NAN 是的 NAN == -NAN . 这可能会严重破坏代码。我建议你离开

        4
  •  0
  •   Pavel Radzivilovsky    14 年前

    有一个C99 isnan(),您应该可以使用它。

    如果在您的实现中它不能正常工作(那是哪一个?)你可以实现你自己的,通过重新解释你铸造到长和做IEEE位魔术。

        5
  •  0
  •   Andrey    14 年前

    • 信令NaN由X'7F80 0001'和X'7FBF FFFF'之间或X'FF80 0001'和X'FFBF FFFF'之间的任何位模式表示。
    • 安静的NaN由X'7FC0 0000'和X'7FFF FFFF'之间或X'FFC0 0000'和X'FFFF FFFF'之间的任何位模式表示。

    这可能是不可移植的,但如果你确定你的平台,它可以接受。更多: http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlf101l.doc/xlfopg/fpieee.htm

        6
  •  -3
  •   Billy ONeal IS4    14 年前

    这是根据维基百科文章发表的评论。请注意,它是完全未经测试的--它应该给你一个想法,你可以做的事情,虽然。

    bool reallyIsNan(float x)
    {
        //Assumes sizeof(float) == sizeof(int)
        int intIzedX = *(reinterpret_cast<int *>(&x));
        int clearAllNonNanBits = intIzedX & 0x7F800000;
        return clearAllNonNanBits == 0x7F800000;
    }
    

    编辑:我真的认为你应该考虑向GLibc的人提交一个bug。