2010-05-11 10 views
7

यह सी प्रोग्राम "गलत" आउटपुट क्यों दे रहा है?इस फ्लोट का मूल्य उस चीज़ से क्यों बदलता है जो इसे सेट किया गया था?

#include<stdio.h> 

void main() 
{ 
    float f = 12345.054321; 

    printf("%f", f); 

    getch(); 
} 

आउटपुट:

12345.054688 

लेकिन उत्पादन होना चाहिए, 12345.054321

मैं वीएस -2008 में वीसी ++ का उपयोग कर रहा हूं।

उत्तर

10

यह "गलत" उत्तर दे रहा है क्योंकि सभी वास्तविक मूल्य फ़्लोट (या उस मामले के लिए युगल) द्वारा प्रतिनिधित्व योग्य नहीं हैं। आपको जो मिल जाएगा वह अंतर्निहित एन्कोडिंग के आधार पर अनुमान है।

आदेश भी 1.0x10 -100 और 1.1x10 -100 (वास्तव में एक मामूली रेंज) के बीच, हर वास्तविक मूल्य का प्रतिनिधित्व करने के लिए, आप अभी भी बिट्स की एक अनंत संख्या की आवश्यकता है।

सिंगल-प्रेसिजन आईईईई 754 मानों में केवल 32 बिट उपलब्ध हैं (जिनमें से कुछ को एक्सपोनेंट और नाएन/इंफ प्रस्तुतियों जैसे अन्य चीजों के लिए काम किया जाता है) और इसलिए आपको अनंत सटीकता नहीं दे सकती है। उनके पास वास्तव में 23 बिट्स उपलब्ध हैं जो लगभग 2 (एक अतिरिक्त अंतर्निहित बिट) है या केवल 7 दशमलव अंक (लॉग (2) लगभग सटीक 7.2 है।

मैं उद्धरणों में "गलत" शब्द संलग्न करता हूं क्योंकि यह वास्तव में गलत नहीं है। कंप्यूटर क्या संख्याओं का प्रतिनिधित्व करने के बारे में आपकी समझ में गलत है (हालांकि नाराज मत हो, आप इस गलतफहमी में अकेले नहीं हैं)।

http://www.h-schmidt.net/FloatApplet/IEEE754.html पर शीर्ष पर जाएं और कार्रवाई में इसे देखने के लिए अपना दशमलव "दशमलव प्रतिनिधित्व" बॉक्स में टाइप करें।

यदि आप अधिक सटीक संख्या चाहते हैं, तो फ्लोट्स के बजाय युगल का उपयोग करें - इन्हें मूल्यों का प्रतिनिधित्व करने के लिए उपलब्ध बिट्स की संख्या दोगुना हो गई है (मान लीजिए कि आपका सी कार्यान्वयन आईईईई 754 सिंगल और डबल परिशुद्धता डेटा प्रकारों को क्रमशः फ्लोट और डबल के लिए उपयोग कर रहा है)।

यदि आप मनमाने ढंग से परिशुद्धता चाहते हैं, तो आपको GMP जैसे "बिग्नम" लाइब्रेरी का उपयोग करना होगा, हालांकि यह देशी प्रकारों की तुलना में कुछ हद तक धीमा है, इसलिए सुनिश्चित करें कि आप व्यापार-बंद समझते हैं।

2

दशमलव संख्या 12345.054321 को आपके प्लेटफ़ॉर्म पर float के रूप में सटीक रूप से प्रदर्शित नहीं किया जा सकता है। परिणाम जो आप देख रहे हैं वह निकटतम संख्या का दशमलव अनुमान है जिसे float के रूप में दर्शाया जा सकता है।

+0

मैं इस जानता था सी # के मामले में हुआ। लेकिन सी – anonymous

+0

सी के 'फ्लोट' के मामले में कभी नहीं पता था कि सटीक प्रकार भी तय किया गया है, इसलिए सी # में कोई अंतर नहीं है। –

0

एकल-परिशुद्धता फ़्लोटिंग पॉइंट मान केवल आठ से नौ महत्वपूर्ण (दशमलव) अंकों का प्रतिनिधित्व कर सकते हैं। उस बिंदु से परे, आप मात्राकरण त्रुटि देख रहे हैं।

0

यह सब परिशुद्धता के साथ करना है। आपका नंबर एक फ्लोट में सटीक रूप से संग्रहीत नहीं किया जा सकता है।

+0

सही और गलत - ओपी का नंबर सटीक रूप से संग्रहीत नहीं किया जा सकता है, लेकिन फ्लोट्स उच्च सटीक संख्याओं को बिल्कुल स्टोर कर सकते हैं, उन्हें बस बाइनरी में बिल्कुल प्रतिनिधित्व करने योग्य होना चाहिए (उदा। 1/65536)। –

+2

@ मैट, जो वास्तव में ज़फ द्वारा किए गए दावे नहीं थे, जिन्होंने कहा: _Your number_ नहीं कर सकता ... – paxdiablo

+0

दाएं, ऊपर की ओर। मैं बस यह स्पष्ट कर रहा था कि परिशुद्धता स्वयं फ्लोट के साथ कोई मुद्दा नहीं है। –

2

float एस सुविधा और गति के बारे में हैं, और एक द्विआधारी प्रतिनिधित्व का उपयोग करें - यदि आप सटीक उपयोग को दशमलव प्रकार का उपयोग करते हैं।

समस्या समझने के लिए, पढ़ा क्या हर कंप्यूटर वैज्ञानिक के बारे में फ्लोटिंग प्वाइंट अंकगणित पता होना चाहिए: http://docs.sun.com/source/806-3568/ncg_goldberg.html

एक समाधान के लिए, देखें दशमलव अंकगणित पूछे जाने वाले प्रश्न: http://speleotrove.com/decimal/decifaq.html

संबंधित मुद्दे