2010-09-20 16 views
10

यह अपने कंप्यूटर पर क्या होता है:क्यों (डबल) 0.6 एफ> (डबल) (6/10 एफ) है?

(double)(float)0.6 
= 0.60000002384185791 

(double)0.6f 
= 0.60000002384185791 

(double)(6/10f) 
= 0.6 

(double)(float)(6/10f) 
= 0.6 

6/10f भी एक नाव है, यह ठीक हो सकता है 0.6 आते हैं?
मेरे दिमाग में (डबल) (6/10 एफ) 0.60000002384185791 भी होना चाहिए। क्या कोई इसे समझाने में मदद कर सकता है? धन्यवाद!

+0

जावा में रास्ते में, परिणाम सभी ऊपर के लिए 0.6000000238418579 है। –

+0

मैं तत्काल खिड़की का उपयोग कर रहा हूँ। मैंने प्रोग्राम में परीक्षण किया है, वे बराबर नहीं हैं।तो यह फोरामिंग का मामला नहीं है। – zhy2002

+0

http://stackoverflow.com/questions/1778368/python-float-str-float-weirdness – Sharun

उत्तर

5

सबसे पहले, अपने को ध्यान में रखना है कि 0.6 सही रूप में लेकिन यह सही रूप में एक double (चल बिन्दु गणित की अशुद्धियों के रूप में प्रतिनिधित्व किया जा सकता है एक float के रूप में प्रतिनिधित्व नहीं किया जा सकता अच्छी तरह से प्रलेखित रहे हैं, इसकी स्पष्ट नहीं करता है, तो महत्वपूर्ण क्यों 0.6 नहीं कर सकते एक फ्लोट के रूप में सटीक रूप से प्रतिनिधित्व किया जाना चाहिए, this link)

कारण आप उपरोक्त व्यवहार को क्यों देख रहे हैं संकलक के लिए नीचे है - यदि आप परावर्तक में संकलित असेंबली को देखते हैं तो यहां क्या हो रहा है थोड़ा स्पष्ट है:

(अद्यतन मैं कोड बदल दिया है ताकि यह Console.WriteLine उपयोग नहीं करता है, के रूप में मैंने महसूस किया कि संकलक आप के लिए एक अधिभार, जो स्थिति उलझन में चुनने गया था)

// As written in source 
var j = (double)(float)0.6; 
var k = (double)0.6f; 
var l = (double)(6/10f); 
var m = (double)(float)(6/10f); 

// Code as seen by Reflector 
double j = 0.60000002384185791; 
double k = 0.60000002384185791; 
double l = 0.6; 
double m = 0.6; 

क्यों संकलक करने के लिए चुनता

// Code 
var a = 0.6; 
var b = (double)0.6; 
var c = 0.6f; 
var d = (float)0.6; 

var e = 6/10; 
var f = 6/(10f); 
var g = (float)(6/10); 
var h = 6/10f; 
var i = (double)6/10; 
// Prints out 0.60000002384185791 

double n = (float)0.6; 
double o = f; 

// As seen by Reflector 
double a = 0.6; 
double b = 0.6; 
float c = 0.6f; 
float d = 0.6f; 

int e = 0; 
float f = 0.6f; 
float g = 0f; 
float h = 0.6f; 
double i = 0.6; 

double n = 0.60000002384185791; 
double o = f; 

संकलक केवल अब क्या करना लगता है: इस खास तरह से संकलन (FYI करें, इस अनुकूलन सब के साथ बंद कर दिया है)

कुछ रोचक अन्य मामलों मुझे परे है कुछ विशेष मामलों में ओव चाल, यह केवल तब क्यों करता है जब डबल पर कास्टिंग पूरी तरह से मेरे बाहर है!

बाकी समय ऐसा लगता है कि फ्लोटिंग पॉइंट अंकगणित बनाने के लिए कुछ चालबाजी करने के लिए प्रतीत होता है जहां वास्तव में यह सामान्य रूप से नहीं होता है।

+0

दिलचस्प बात यह है कि यदि आप 'फ्लोट' का उपयोग करते हैं, तो वे सभी 0.6 प्रिंट करेंगे (जैसा कि [ideone] (http://ideone.com/2lvBI) पर देखा गया है, विज़ुअल सी # के साथ भी परीक्षण किया गया है) – NullUserException

+0

धन्यवाद सबको, मुझे लगता है कि यह वास्तव में है एक कंपाइलर विशिष्ट मुद्दा। – zhy2002

+0

इसके अलावा मैंने पाया कि: float float3 = 0.6f; int int1 = 6; फ्लोट 1 = 10; Assert.IsTrue (int1/float1> = float3); // विफल रहता है, मेरे कोड फ्लोट 3 में एक तर्क है! – zhy2002

2

ऐसा लगता है कि परिणामस्वरूप गोल हो रहा है। क्या आप परिशुद्धता के आवश्यक अंकों के साथ परिणाम प्रदर्शित कर रहे हैं? आप प्रिंट किए गए परिणाम के सटीक संख्यात्मक प्रतिनिधित्व प्राप्त करने के लिए जॉन स्कीट से this c# class का उपयोग कर सकते हैं।

ध्यान दें कि ToString() हमेशा सभी अंकों को मुद्रित नहीं करेगा, न ही विजुअल स्टूडियो डीबगर होगा।

1

अगर मैं सट्टेबाजी करने वाला व्यक्ति था, तो मैं कहूंगा कि अंतर उस जगह पर है जहां दबाव हो रहा है। बाद के दो उदाहरणों में (6/10 एफ वाले वाले) में, दो अक्षर हैं जो पूरी संख्याएं हैं (पूर्णांक 6 और फ्लोट 10.00000000 ...)। विभाजन कम से कम संकलक के बाद हो रहा है, कम से कम उस कंपाइलर में जिसका आप उपयोग कर रहे हैं। पहले दो उदाहरणों में, आपके पास एक आंशिक फ्लोट शाब्दिक (0.6) है जिसे फ्लोट के मंटिसा के भीतर पर्याप्त रूप से बाइनरी मान के रूप में व्यक्त नहीं किया जा सकता है। एक डबल के लिए मूल्य को जोड़ना जो पहले से किया गया नुकसान की मरम्मत नहीं कर सकता है।

उन वातावरणों में जो पूरी तरह से संगत परिणामों का उत्पादन कर रहे हैं, विभाजन को दोगुना करने से पहले होता है (6 को विभाजन के लिए एक फ्लोट पर ले जाया जाएगा, विभाजन को फ्लोट स्पेस में किया जाता है, फिर विभाजन को फ्लोट स्पेस में किया जाता है, फिर परिणाम एक डबल के लिए मजबूर है)।

+0

आप ildasm का उपयोग करके क्या हुआ और इंटरमीडिएट असेंबली को देखकर क्या हुआ है, आप हमेशा एक बू ले सकते हैं। –

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