2010-01-19 18 views
9

कोड की यह पंक्ति:को पार्स संख्या weirdness

Console.WriteLine(Convert.ToInt32(“23,23”) + 1); 

एक अपवाद फेंकता। कोड की यह पंक्ति:

Console.WriteLine(Convert.ToDouble(“23,23”) + 1); 

प्रिंटों 2324.

किसी को पता है क्यों यह मामला है? मुझे नहीं लगता कि कुछ भी अच्छा रूपांतरण दूसरे रूपांतरण के लिए आ सकता है।

+4

कौन सा बस पता चलता है कि आप अधिभार और एक IFormatProvider कि एक NumberStyles लेता है का उपयोग करना चाहिए अगर आप आश्चर्य से बचना चाहते हैं चला जाता है। – bdukes

उत्तर

14
the MSDN documentation of System.Double.Parse से

:

एस पैरामीटर शामिल कर सकते हैं [...] प्रपत्र की एक स्ट्रिंग:

[ws][sign][integral-digits[,]]integral-digits[.[fractional-digits]][e[sign]exponential-digits][ws]

यहाँ, अल्पविराम (,) "के लिए खड़ा है [ए] संस्कृति-विशिष्ट हजारों विभाजक प्रतीक "।

संक्षेप में: यदि आपकी वर्तमान संस्कृति के हजारों विभाजक प्रतीक स्ट्रिंग में कहीं भी दिखाई देते हैं, तो इसे Double.Parse द्वारा अनदेखा किया जाता है (जिसे Convert.ToDouble द्वारा आंतरिक रूप से बुलाया जाता है)।


Int32.Parse(string), दूसरे हाथ पर, स्ट्रिंग में हजारों विभाजक अनुमति नहीं देता:

है और इसीलिए आपके पहला उदाहरण एक अपवाद फेंकता है। आप इस व्यवहार को Double.Parse और Int32.Parse दोनों के लिए एक ओवरलोड का उपयोग करके बदल सकते हैं जो आपको अन्य उत्तरों द्वारा समझाए गए अनुसार NumberStyles निर्दिष्ट करने की अनुमति देता है।

+0

लेकिन यह 'इंटीजर.पर्स' के लिए क्यों अलग है? हजारों विभाजक यहां समान ज्ञान नहीं बनाते हैं? –

+0

@ कोनराड: मैंने अपना जवाब अपडेट किया। Int32.Parse केवल '[ws] [sign] अंक [ws]' की अनुमति देता है। इसके पीछे प्रेरणा के बारे में: कोई विचार नहीं ... – Heinzi

+1

मुझे लगता है कि यह केवल एक कार्यान्वयन अंतर है (जो इसके पीछे कुछ तर्क हो सकता है या नहीं)। एमएसडीएन दस्तावेज कहता है कि 'Int32.Parse' केवल' [ws] [sign] अंक [ws] स्वीकार करता है, जहां 'ws' व्हाइटस्पेस है। यह डिफ़ॉल्ट रूप से हजारों ऑपरेटर को स्वीकार नहीं करता है ... – bdukes

0

क्योंकि डबल यह मान रहा है कि अल्पविराम हजारों सेपरेटर है, और इसे अनदेखा करता है। Int32 कनवर्ट ऐसा नहीं करता है।

8

पहला विफल रहता है क्योंकि int.Parse डिफ़ॉल्ट रूप से हजारों विभाजक को अनुमति नहीं देता है। आप बदल सकते हैं कि NumberStyles का उपयोग कर:

int d = int.Parse("11,23", 
        NumberStyles.AllowThousands, 
        CultureInfo.InvariantCulture); 

अब यह डबल संस्करण है जो डिफ़ॉल्ट रूप से समर्थन हजारों विभाजक की तरह काम करता है। वे संभवतः सफल होते हैं क्योंकि "," जब पार्सर द्वारा हजारों विभाजक के रूप में व्यवहार किया जाता है तो पूरी तरह से अनदेखा किया जाता है - भले ही अल्पविराम कभी-कभी हजारों विभाजक के रूप में समझ में नहीं आता है।

हैरानी की बात है, यहां तक ​​कि इस काम करता है:

double d = double.Parse("1,,1,2,3", CultureInfo.InvariantCulture); 

ऊपर में, घ मूल्य 1123.0 को तैयार है।

+0

+1। उपयोगी जानकारी के लिए – Heinzi

+0

+1 :) –

+0

चूंकि प्रदान किए गए नमूने में ',' के बाद केवल दो अंक हैं, तो क्या यह दशमलव विभाजक होने की अधिक संभावना नहीं है? –

1

कम से कम रूपांतरण में अल्पविरामों को नजरअंदाज कर दिया जाता है। यदि आप अल्पविराम उत्पन्न करने के लिए अल्पविराम चाहते हैं, तो आप Double.Parse (स्ट्रिंग, System.Globalization.NumberStyles) विधि का उपयोग कर सकते हैं।

+0

यदि दशमलव बिंदु के बाद अल्पविराम (संख्या समूह विभाजक) रखा गया है तो यह एक प्रारूप अपवाद देता है, इसलिए मुझे लगता है कि इसे वास्तव में अनदेखा नहीं किया जाता है लेकिन किसी भी तरह से माना जाता है। – Keugyeol

6
Console.WriteLine(Convert.ToDouble(“23,23”) + 1); 

इस मामले में, अल्पविराम को आपके स्थानीयकरण के समूह विभाजक प्रतीक के रूप में व्याख्या किया जा रहा है, और इसे अनदेखा किया जाता है। http://msdn.microsoft.com/en-us/library/fd84bdyt.aspx देखें।

Console.WriteLine(Convert.ToInt32(“23,23”) + 1); 

इस मामले में, आप Int32.Parse उपयोग कर रहे हैं, जो डिफ़ॉल्ट रूप से समूह विभाजक का समर्थन नहीं करता।

इस के पीछे तर्क पूर्णांक कनवर्टर, कोई स्थानीयकरण समर्थन डिफ़ॉल्ट से है क्योंकि स्थानीयकरण एक अतिरिक्त भूमि के ऊपर कहते हैं और वहाँ एक पार्सर कि किसी भी प्रतीकों के साथ बातचीत करने के लिए की जरूरत नहीं है के लिए इसे जोड़ने के लिए कोई कारण नहीं है है सब। , एक दशमलव विभाजक का समर्थन करने के

int.Parse("11,23", NumberStyles.AllowThousands, CultureInfo.InvariantCulture); 

फ्लोट/डबल रूपांतरण दूसरे हाथ पर, है: हालांकि, आप पार्सर कुछ अतिरिक्त तर्क के साथ स्थानीयकरण समर्थन करने के लिए मजबूर कर सकते हैं। कुछ संस्कृतियों में, यह "," है, अन्य में, यह " " या "." हो सकता है। चूंकि फ़ंक्शन को किसी भी तरह स्थानीयकरण का समर्थन करना चाहिए, इसके लिए यह डिफ़ॉल्ट रूप से कुछ स्थानीयकरण सुविधाओं का समर्थन करने के लिए कोई समझ नहीं लेगा। अन्यथा, कार्यान्वयन उन लोगों को भ्रमित करेगा जो उम्मीद करते हैं कि चूंकि स्थानीयकरण दशमलव विभाजक के लिए समर्थित है, यह अन्य स्थानीयकरण पहलुओं का भी समर्थन करेगा।

+0

int.Parse * करता है * हजारों विभाजक का समर्थन करता है - मेरा जवाब देखें। तर्क के स्पष्टीकरण के लिए –

+0

+1! आप "... * डिफ़ॉल्ट * पूर्णांक कनवर्टर ..." लिखना चाहेंगे, क्योंकि 'Int32.Parse (स्ट्रिंग, संख्या स्टाइल)' आपको स्थानीयकरण समर्थन जोड़ने की अनुमति देता है। – Heinzi

+0

इसे ठीक किया, धन्यवाद। –

0
?double.Parse("23,23", System.Globalization.CultureInfo.InstalledUICulture); 
23.23 

?double.Parse("23,23", new System.Globalization.CultureInfo("en-US")); 
2323.0 
?double.Parse("23,23", new System.Globalization.CultureInfo("fr-FR")); 
23.23 

?double.Parse("23,23", System.Globalization.CultureInfo.InvariantCulture); 
2323.0 

Convert.ToDouble के लिए एक ही बात:

?Convert.ToDouble("23,23", System.Globalization.CultureInfo.InvariantCulture); 
2323.0 
संबंधित मुद्दे