आज मैं पर नज़र रखने गया था क्यों मेरे कार्यक्रम कुछ अप्रत्याशित चेकसम-बेमेल त्रुटियों हो रही थी, कुछ कोड में है कि मैं ने लिखा है कि serializes और deserializes आईईईई-754 फ्लोटिंग प्वाइंट मूल्यों, एक प्रारूप है कि एक 32-बिट चेकसम मान शामिल में (जो फ़्लोटिंग-पॉइंट सरणी के बाइट्स पर एक सीआरसी-प्रकार एल्गोरिदम चलाकर गणना की जाती है)।सी == ऑपरेटर कैसे तय करता है कि दो फ़्लोटिंग पॉइंट मान बराबर हैं या नहीं?
कुछ सिर-खरोंच के बाद, मुझे एहसास हुआ कि समस्या 0.0f और -0.0f में अलग-अलग बिट-पैटर्न (क्रमशः 0x00000000 बनाम 0x00000080 (थोड़ा-अंत)) है, लेकिन उन्हें C++ के बराबर माना जाता है समानता ऑपरेटर। इसलिए, चेकसम-मिस्चैच त्रुटियां इसलिए हुईं क्योंकि मेरे चेकसम-गणना एल्गोरिदम ने उन दो बिट-पैटर्न के बीच अंतर उठाया, जबकि मेरे कोडबेस के कुछ अन्य हिस्सों (जो फ़्लोटिंग पॉइंट समानता परीक्षण का उपयोग करते हैं, मूल्यों को देखने के बजाय बाइट-बाय- बाइट) ने उस भेद को नहीं बनाया।
ठीक है, निष्पक्ष पर्याप्त - मैं शायद से फ्लोटिंग प्वाइंट समानता वैसे भी परीक्षण करना बेहतर पता होना चाहिए था।
लेकिन यह मिल गया मुझे सोच, वहाँ अन्य आईईईई-754 चल बिन्दु मान जो बराबर माना जाता है लेकिन (सी == ऑपरेटर के अनुसार) विभिन्न बिट पैटर्न है कर रहे हैं? या, इसे एक और तरीका रखने के लिए, == ऑपरेटर कैसे तय करता है कि दो फ़्लोटिंग-पॉइंट मान बराबर हैं या नहीं? मुझे नौसिखिया हालांकि यह memcmp() जैसे उनके बिट-पैटर्न पर कुछ कर रहा था, लेकिन स्पष्ट रूप से यह उससे अधिक प्रचलित है।
यहाँ मैं क्या मतलब है की एक कोड उदाहरण है, इस मामले में मैं ऊपर स्पष्ट नहीं किया गया था।
#include <stdio.h>
static void PrintFloatBytes(const char * title, float f)
{
printf("Byte-representation of [%s] is: ", title);
const unsigned char * p = (const unsigned char *) &f;
for (int i=0; i<sizeof(f); i++) printf("%02x ", p[i]);
printf("\n");
}
int main(int argc, char ** argv)
{
const float pzero = -0.0f;
const float nzero = +0.0f;
PrintFloatBytes("pzero", pzero);
PrintFloatBytes("nzero", nzero);
printf("Is pzero equal to nzero? %s\n", (pzero==nzero)?"Yes":"No");
return 0;
}
http://how-to.wikia.com/wiki/Howto_compare_floating_point_numbers_in_the_C_programming_language FYI करें, एक एप्सिलॉन का उपयोग कर नाव तुलना के लिए आगे रास्ता है। विषय पर नहीं, लेकिन जानना उपयोगी है। – darvids0n
NaNs किसी भी तरह से जा सकता है (संभवतः कंपाइलर के आधार पर)। वे मेमोरी में भी भिन्न हो सकते हैं क्योंकि बड़ी संख्या में संभावित नाएन (सिंगल परिशुद्धता के लिए 2^24-1) हैं। – ughoavgfhw