2010-08-29 21 views
28

कुछ परीक्षण मामलों को लिखते समय, और कुछ परीक्षण NaN के परिणाम की जांच करते हैं।नकारात्मक NaN एक NaN नहीं है?

मैं std::isnan लेकिन ज़ोर failes उपयोग करने की कोशिश:

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

x का मूल्य मुद्रण के बाद, यह पता चला है कि यह नकारात्मक NaN (-nan) है जो मेरे मामले में पूरी तरह से स्वीकार्य है।

NaN != NaN इस तथ्य का उपयोग करने के बाद और assert(x == x) का उपयोग करने के बाद, संकलक मुझे 'पक्ष' करता है और जोर से अनुकूलित करता है।

अपना खुद का isNaN फ़ंक्शन को भी अनुकूलित किया जा रहा है।

मैं NaN और -NaN की समानता दोनों की जांच कैसे कर सकता हूं?

+7

o_O:

यह वही है मैं अपने परीक्षण के कमरे में उपयोग क्यों करें? नकारात्मक NaN * है * NaN। – kennytm

+1

क्या आप दिखा सकते हैं कि आप अपना खुद का 'isNaN' कैसे लिखते हैं, और शायद आपके कंपाइलर से अंतर्निहित एक है यदि आपके पास है? ** ** ** के लिए परीक्षण करने का एक तरीका (जैसा कि आपने देखा है, कई हैं) http://en.wikipedia.org/wiki/NaN पर थोड़ा पैटर्न का परीक्षण करना है (एक्सपोनेंट 11..11 है)। –

+0

आप किस कंपाइलर का उपयोग कर रहे हैं, और आपका टेस्ट कोड कैसा दिखता है? – jalf

उत्तर

31

यह शर्मनाक है।

कारण संकलक (इस मामले में जीसीसी) तुलना को दूर करने का कारण था और 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. 

सूचना समाप्त होने की सजा - -ffast-math असुरक्षित है।

+0

होगा, मैंने बस एमएस कंपाइलर के साथ सटीक वही समस्या देखी जब/fp: तेज़ ध्वज। ठीक है/एफपी के साथ काम करता है: यद्यपि सटीक। – stijn

0

सी 99 इस्नान() है जिसका उपयोग आप करने में सक्षम होना चाहिए।

यदि आपके कार्यान्वयन में यह सही तरीके से काम नहीं करता है (कौन सा है?) आप लंबे समय तक reinterpret_casting करके और आईईईई बिट जादू कर सकते हैं।

+2

कि 'इस्नान' वही है जो वह पहले से ही उपयोग कर रहा है। –

-3

यह टिप्पणियों में पोस्ट विकिपीडिया लेख पर आधारित है। ध्यान दें कि यह पूरी तरह से अनचाहे है - यह आपको कुछ ऐसा करने का विचार देना चाहिए जो आप कर सकते हैं।

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

संपादित करें: मुझे सच में लगता है कि आपको उस पर जीएलआईबीसी लोगों के साथ एक बग दर्ज करने पर विचार करना चाहिए।

+0

यह 'इंफ'' के लिए भी 'सत्य' वापस करेगा। –

+0

@ सैम: जैसा कि मैंने कहा, मैंने इसका परीक्षण नहीं किया, मुझे इसे विकिपीडिया से मिला। मैंने इसकी शुद्धता के बारे में कभी भी कोई दावा नहीं किया। किसी भी मामले में, ओपी ने पहले से ही इस सवाल का जवाब दिया है। मैं नहीं देखता कि हम एक 1.5 साल का सवाल क्यों खोद रहे हैं जिसे पहले ही चिह्नित किया गया था और इसके बारे में शिकायत की गई थी। –

+4

मैं शिकायत नहीं कर रहा हूं; तुम हो। मुझे यह प्रश्न Google खोज से मिला और देखा कि इसका कोई संतोषजनक उत्तर नहीं था। मैं गलत या अपूर्ण उत्तरों पर टिप्पणी कर रहा हूं क्योंकि मैं नहीं चाहता कि कोई और समय बिताए कि वे गलत क्यों हैं या अपूर्ण हैं। इसके अलावा, अनुमोदित उत्तर एक स्पष्टीकरण देता है, समाधान नहीं। इस सवाल का कितना पुराना बिल्कुल प्रासंगिक नहीं है। यदि आपको इसके साथ कोई समस्या है, तो शायद आप इस वेबसाइट के बिंदु को चूक गए हैं। बस आराम करो, दोस्त। –

0

आप संख्या के बिट्स देख सकते हैं। आईईईई 754 NaN के लिए मुखौटा परिभाषित किया गया है:

  • एक संकेतन NaN 'X'7FBF FFFF और' X'7F80 0001 के बीच किसी भी बिट पैटर्न द्वारा या X'FF80 0001 'और X'FFBF FFFF' के बीच प्रतिनिधित्व किया है।
  • X'7FC0 0000 'और X'7FFF FFFF' या X'FFC0 0000 'और X'FFFF FFFF' के बीच किसी भी शांत पैटर्न द्वारा एक शांत NaN का प्रतिनिधित्व किया जाता है।

यह पोर्टेबल नहीं हो सकता है, लेकिन यदि आप अपने प्लेटफॉम के बारे में निश्चित हैं तो यह स्वीकार्य हो सकता है। अधिक: http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlf101l.doc/xlfopg/fpieee.htm

+0

यह मेरा आखिरी उपाय होगा, मैं अभी भी सबसे पोर्टेबल समाधान खोजने की कोशिश कर रहा हूं। – LiraNuna

+0

@ लीरानुना यह नाटकीय नहीं है। यदि आप इसे एंडियननेस को ध्यान में रखते हुए कार्यान्वित करते हैं तो यह पोर्टेबल एनोट – Andrey

1

यह आपके पुस्तकालय के isnan() के कार्यान्वयन में एक बग जैसा दिखता है। यह हिम तेंदुए पर जीसीसी 4.2.1 पर ठीक काम करता है। हालांकि, यह कोशिश करने के बारे में क्या?

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

जाहिर है, मैं इसे परीक्षण नहीं कर सकते, क्योंकि std::isnan(-NaN)true अपने सिस्टम पर है।

संपादित: -ffast-math के साथ, -O स्विच पर ध्यान दिए बिना, हिमपात तेंदुए पर जीसीसी 4.2.1 सोचता है कि NAN == NANtrue है, के रूप में NAN == -NAN है। यह संभावित रूप से विनाशकारी कोड तोड़ सकता है। मैं समान परिणामों के लिए -ffast-math या कम से कम परीक्षण है छोड़ना सलाह देंगे का उपयोग करने और नहीं इसे प्रयोग बनाता में ...

3

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 
संबंधित मुद्दे