एक्सपोनेंशियल नोटेशन से एक नंबर पार्स करें


85

मुझे दशमलव डेटा प्रकार के लिए "1.2345E-02" (घातांक अंकन में व्यक्त संख्या) स्ट्रिंग को पार्स करने की आवश्यकता है, लेकिन Decimal.Parse("1.2345E-02")बस एक त्रुटि फेंकता है

जवाबों:


169

यह एक फ्लोटिंग पॉइंट नंबर है, आपको यह बताना होगा कि:

decimal d = Decimal.Parse("1.2345E-02", System.Globalization.NumberStyles.Float);

49

यदि आप निर्दिष्ट करते हैं तो यह काम करता है NumberStyles.Float:

decimal x = decimal.Parse("1.2345E-02", NumberStyles.Float);
Console.WriteLine(x); // Prints 0.012345

मुझे पूरी तरह से यकीन नहीं है कि यह डिफ़ॉल्ट रूप से समर्थित क्यों नहीं है - डिफ़ॉल्ट का उपयोग करना है NumberStyles.Number, जो AllowLeadingWhite, AllowTrailingWhite, AllowLeadingSign, AllowTrailingSign, AllowDecimalPoint, और AllowThousands शैलियों का उपयोग करता है। संभवतः यह प्रदर्शन-संबंधी है; प्रतिपादक निर्दिष्ट करना अपेक्षाकृत दुर्लभ है, मुझे लगता है।


मैं इसे डबल के साथ काम करने की कोशिश कर रहा हूं, लेकिन ऐसा लगता है कि यह नहीं होगा। नहीं यकीन है कि यह क्यों नहीं कर सकता ..?
JanT

@JTT: "यह नहीं होगा" और "यह नहीं कर सकता" की तुलना में अधिक जानकारी के साथ मैं वास्तव में अधिक मदद नहीं कर सकता। मेरा सुझाव है कि आप और अधिक विस्तार के साथ एक नया प्रश्न पूछें, जिसमें दिखाया गया है कि आपने क्या किया और वास्तव में क्या हुआ।
जॉन स्कीट

मैंने आपके उत्तर की तरह कोड चलाने की कोशिश की लेकिन दशमलव के बजाय दोहरे का उपयोग किया। लेकिन पहले ही वर्कअराउंड मिल गया। चीयर्स
JanT

1
@JTT यह अच्छा होगा यदि आप अपने वर्कअराउंड को साझा कर सकते हैं। मैं वास्तव में एक ही समस्या है और जानकारी का उपयोग कर सकते हैं। धन्यवाद!
रिक ग्लैमर

@RickGlimmer: मुझे यकीन नहीं है कि आप कैसे जानते हैं कि आपकी समस्या बिल्कुल जेएनटी के समान है, यह देखते हुए कि उन्होंने कभी भी यह विवरण नहीं दिया कि वे क्या करने की कोशिश कर रहे थे। मेरे कोड के decimalसाथ प्रतिस्थापित करना doubleमेरे लिए ठीक काम करता है, जैसे मैं उससे उम्मीद करता हूं। आप प्रदान कर सकता है विवरण आप की कोशिश कर रहे हैं की, कोड का उपयोग कर रहे है, और परिणाम है, यह ज्यादा मदद करने के लिए आसान होगा।
जॉन स्कीट

34

NumberStyles निर्दिष्ट करने के अतिरिक्त मैं सुझाव है कि आप का उपयोग decimal.TryParse जैसे समारोह:

decimal result;
if( !decimal.TryParse("1.2345E-02", NumberStyles.Any, CultureInfo.InvariantCulture, out result) )
{
     // do something in case it fails?
}

NumberStyles के विकल्प के रूप में। यदि आप अपने स्वरूपों के बारे में निश्चित हैं तो आप एक विशिष्ट सेट का उपयोग कर सकते हैं। उदाहरण के लिए:

NumberStyles.AllowExponent | NumberStyles.Float

1
लेकिन इसके लिए जरूरी नहीं है कि फ्लोट को AllowExponent के साथ इस्तेमाल करें क्योंकि फ्लोट = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowDecimalPoint | AllowExponent
Lukáš Kmoch

@ LukášKmoch वास्तव में आप सही हैं। दूसरों के रूप में आदत के बल (किसी के अलावा) इसे शामिल नहीं करते हैं। हालांकि अतिरिक्त प्रदर्शन करने के लिए चोट नहीं करनी चाहिए।
सेवरर सिगमंडर्सन


8

चयनित उत्तर के बारे में सतर्क रहें: एक सूक्ष्मता निर्दिष्ट करना है System.Globalization.NumberStyles.Float में Decimal.Parse जो एक System.FormatException को जन्म दे सकता है क्योंकि आपके सिस्टम को 'के बजाय', 'के साथ एक संख्या का इंतजार करना पड़ सकता है।'

उदाहरण के लिए, फ्रेंच संकेतन में, "1.2345E-02" अमान्य है, आपको इसे पहले "1,2345E-02" में बदलना होगा।

निष्कर्ष में, की तर्ज पर कुछ का उपयोग करें:

Decimal.Parse(valueString.Replace('.',','), System.Globalization.NumberStyles.Float);

1
आप बिल्कुल सही कह रहे है। मुझे समझ नहीं आता कि कोई और इसे क्यों नहीं लाया।
कार्ल्स अल्कोली

10
बेहतर उपयोग CultureInfo.InvariantCulture पार्स के एक 3 पैरामीटर के रूप में
एंड्री कोज़चुक

3

मैंने पाया है कि NumberStyles.Floatकुछ मामलों में पास होना, उन नियमों में बदलाव करता है जिनके द्वारा स्ट्रिंग को संसाधित किया जाता है और इसके परिणामस्वरूप एक अलग आउटपुट NumberStyles.Number(डिफ़ॉल्ट नियमों का उपयोग किया जाता है decimal.Parse) होता है।

उदाहरण के लिए, निम्नलिखित कोड FormatExceptionमेरी मशीन में एक उत्पन्न करेगा :

CultureInfo culture = new CultureInfo("");
culture.NumberFormat.NumberDecimalDigits = 2;
culture.NumberFormat.NumberDecimalSeparator = ".";
culture.NumberFormat.NumberGroupSeparator = ",";
Decimal.Parse("1,234.5", NumberStyles.Float, culture); // FormatException thrown here

मैं इनपुट का उपयोग करने की सलाह देता हूं NumberStyles.Number | NumberStyles.AllowExponent, क्योंकि यह घातीय संख्याओं की अनुमति देगा और अभी भी decimalनियमों के तहत स्ट्रिंग की प्रक्रिया करेगा ।

CultureInfo culture = new CultureInfo("");
culture.NumberFormat.NumberDecimalDigits = 2;
culture.NumberFormat.NumberDecimalSeparator = ".";
culture.NumberFormat.NumberGroupSeparator = ",";
Decimal.Parse("1,234.5",NumberStyles.Number | NumberStyles.AllowExponent, culture); // Does not generate a FormatException

पोस्टर के प्रश्न का उत्तर देने के लिए, इसके बजाय सही उत्तर होना चाहिए:

decimal x = decimal.Parse("1.2345E-02", NumberStyles.Number | NumberStyles.AllowExponent);
Console.WriteLine(x);

1

NumberStyles.Any का उपयोग करने के बारे में चेतावनी:

"6.33E + 03" उम्मीद के अनुसार 6330 में परिवर्तित होता है। जर्मन में, दशमलव बिंदुओं को अल्पविराम द्वारा दर्शाया जाता है, लेकिन 6,33E + 03 633000 में परिवर्तित होता है! यह मेरे ग्राहकों के लिए एक समस्या है, क्योंकि डेटा उत्पन्न करने वाली संस्कृति ज्ञात नहीं है और उस संस्कृति से भिन्न हो सकती है जो डेटा पर काम कर रही है। मेरे मामले में, मेरे पास हमेशा वैज्ञानिक संकेतन होता है, इसलिए मैं पार्सिंग से पहले हमेशा कॉमा को दशमलव बिंदु तक बदल सकता हूं, लेकिन यदि आप मनमाने ढंग से संख्याओं के साथ काम कर रहे हैं, जैसे सुंदर स्वरूपित संख्या जैसे 1,234,567 तो वह दृष्टिकोण काम नहीं करता है।


0

आपको डॉट्स को बदलने की आवश्यकता नहीं है (क्रमशः कॉमा) बस इनपुट IFormatProvider निर्दिष्ट करें:

float d = Single.Parse("1.27315", System.Globalization.NumberStyles.Float, new CultureInfo("en-US"));
float d = Single.Parse("1,27315", System.Globalization.NumberStyles.Float, new CultureInfo("de-DE"));

0

यदि आप घातांक मान को जाँचना और परिवर्तित करना चाहते हैं तो इसका उपयोग करें

string val = "1.2345E-02";
double dummy;
bool hasExponential = (val.Contains("E") || val.Contains("e")) && double.TryParse(val, out dummy);
if (hasExponential)
{
    decimal d = decimal.Parse(val, NumberStyles.Float);
}

आशा है कि यह किसी की मदद करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.