शून्य को पीछे किए बिना दशमलव प्रदर्शित करने का सबसे अच्छा तरीका है


107

क्या कोई प्रदर्शन सूत्र है जो इन स्ट्रिंग निरूपण के रूप में c # में दशमलव का उत्पादन करेगा, बिना किसी गोलाई के?

// decimal -> string

20 -> 20
20.00 -> 20
20.5 -> 20.5
20.5000 -> 20.5
20.125 -> 20.125
20.12500 -> 20.125
0.000 -> 0

{0. #} गोल होगा, और कुछ ट्रिम प्रकार के फ़ंक्शन का उपयोग करके ग्रिड में एक बाउंड न्यूमेरिक कॉलम के साथ काम नहीं करेगा।

जवाबों:


147

क्या आपके पास अधिकतम दशमलव स्थान हैं जिन्हें आपको कभी भी प्रदर्शित करना होगा? (आपके उदाहरणों में अधिकतम 5 हैं)।

यदि हां, तो मुझे लगता है कि "0। #####" के साथ प्रारूपण वह होगा जो आप चाहते हैं।

    static void Main(string[] args)
    {
        var dList = new decimal[] { 20, 20.00m, 20.5m, 20.5000m, 20.125m, 20.12500m, 0.000m };

        foreach (var d in dList)
            Console.WriteLine(d.ToString("0.#####"));
    }

4
और आप हमेशा प्रारूप में एक # * प्रतीकों की एक संख्या को फेंक सकते हैं। * वैज्ञानिक नहीं
एंथनी पेग्राम

3
+1 - संयोग से, आपको अग्रणी # की आवश्यकता नहीं है। "" #। ##### "समान रूप से काम करता है। और किसी भी तरह, यह शून्य से दूर (सिर्फ FYI) होता है।
TrueWill

14
@TrueWill दरअसल इससे फर्क पड़ता है। d == 0.1 मी तो "0. #" "0.1" और "#। #" प्रतिपादन ".1" अग्रणी के बिना। 0. "गलत या सही नहीं है, बस आप क्या चाहते हैं पर निर्भर करता है।
आरोनोएल

4
मुझे हर समय एक दशमलव स्थान प्रदर्शित करने की आवश्यकता थी, इसलिए मैंने प्रारूप स्ट्रिंग का उपयोग किया "0.0#"
हैमर

1
नीचे इरविन मेयर का जवाब देखें।
shlgug

32

मैंने अभी सीखा कि Gप्रारूप विनिर्देशक का सही उपयोग कैसे किया जाता है । MSDN प्रलेखन देखें । नीचे एक नोट है जो बताता है कि अनुगामी शून्य को दशमलव प्रकारों के लिए संरक्षित किया जाएगा जब कोई सटीक निर्दिष्ट नहीं किया जाता है। वे ऐसा क्यों करेंगे मुझे नहीं पता, लेकिन हमारी सटीकता के लिए अधिकतम अंकों को निर्दिष्ट करके उस समस्या को ठीक करना चाहिए। इसलिए दशमलव तैयार करने के लिए, G29सबसे अच्छा दांव है।

decimal test = 20.5000m;
test.ToString("G"); // outputs 20.5000 like the documentation says it should
test.ToString("G29"); // outputs 20.5 which is exactly what we want

21
इससे 0.00001 को 1E-05 के रूप में प्रदर्शित किया जाएगा
14

17

इस स्ट्रिंग प्रारूप को आपका दिन बनाना चाहिए: "0। ############################"। ध्यान रखें कि दशमलव में अधिकतम 29 महत्वपूर्ण अंक हो सकते हैं।

उदाहरण:

? (1000000.00000000000050000000000m).ToString("0.#############################")
-> 1000000.0000000000005

? (1000000.00000000000050000000001m).ToString("0.#############################")
-> 1000000.0000000000005

? (1000000.0000000000005000000001m).ToString("0.#############################")
-> 1000000.0000000000005000000001

? (9223372036854775807.0000000001m).ToString("0.#############################")
-> 9223372036854775807

? (9223372036854775807.000000001m).ToString("0.#############################")
-> 9223372036854775807.000000001

4
यह समस्या का सबसे सामान्य उत्तर है। निश्चित नहीं है कि यह दशमलव के लिए डिफ़ॉल्ट "G" प्रारूप क्यों नहीं है। पीछे चल रहे शून्य कोई जानकारी नहीं जोड़ते हैं। Microsoft दस्तावेज़ीकरण में दशमलव के लिए एक अजीब चेतावनी है: docs.microsoft.com/en-us/dotnet/standard/base-types/… हालांकि, यदि संख्या एक दशमलव है और सटीक विनिर्देश छोड़ दिया जाता है, तो निश्चित-बिंदु अंकन हमेशा उपयोग किया जाता है और अनुगामी शून्य संरक्षित हैं।
एरिक रोलर

10

यह अभी तक एक और बदलाव है जो मैंने ऊपर देखा था। मेरे मामले में मुझे दशमलव बिंदु के दाईं ओर सभी महत्वपूर्ण अंकों को संरक्षित करने की आवश्यकता है, जिसका अर्थ है कि सबसे महत्वपूर्ण अंक के बाद सभी शून्य को छोड़ दें। बस सोचा था कि शेयर करना अच्छा होगा। मैं हालांकि इसकी दक्षता के लिए व्रत नहीं कर सकता, लेकिन जब सौंदर्यशास्त्र को प्राप्त करने की कोशिश करते हैं, तो आप पहले से ही अक्षमताओं के लिए बहुत अधिक शापित हैं।

public static string ToTrimmedString(this decimal target)
{
    string strValue = target.ToString(); //Get the stock string

    //If there is a decimal point present
    if (strValue.Contains("."))
    {
        //Remove all trailing zeros
        strValue = strValue.TrimEnd('0');

        //If all we are left with is a decimal point
        if (strValue.EndsWith(".")) //then remove it
            strValue = strValue.TrimEnd('.');
    }

    return strValue;
}

यह सब, बस मेरे दो सेंट में फेंकना चाहता था।


3
यह आसानी से सबसे अच्छा समाधान है, यह या तो "0.0" के लिए उड़ा नहीं करता है। मैंने पूर्णांकों को "1.0" के रूप में वैकल्पिक रूप से दिखाने के लिए एक डिफ़ॉल्ट ध्वज जोड़ा, और इससे मेरे सभी दशमलव गिर गए। समझ में नहीं आता कि यह सबसे अच्छा जवाब क्यों नहीं है, + बहुत सारे।
स्टीव हिब्बर्ट

2
यह विशेष रूप से अच्छा है अगर किसी ने आपको पहले ही एक स्ट्रिंग पारित कर दिया है। आप इसे केवल ToTrimmedString (इस स्ट्रिंग strValue) में बदल सकते हैं और पहली पंक्ति को हटा सकते हैं।
PRMan

ये एक अच्छा बिंदु है। मुझे लगता है कि जब मैं यह लिख रहा था तो मैं उन मूल्यों के साथ काम कर रहा था जो पहले से ही दशमलव या कुछ थे इसलिए मैं पूरी बात को शामिल करना चाहता था। आप इसके बजाय किसी अन्य अतिभारित विधि के अंदर उस विधि का शरीर रख सकते हैं जो इसके बजाय एक स्ट्रिंग को स्वीकार करता है।
डिस्लेक्सिकनकोको

यह एक अच्छा समाधान है जब आप ToTrimmedString () कॉल कर सकते हैं, लेकिन कई मामले हैं जहां आप एक प्रारूप स्ट्रिंग तक सीमित हैं।
माइक मेरीनोस्की

1
जबकि दशमलव विभाजक को संस्कृति विशिष्ट होना चाहिए, मुझे लगता है कि यह एक अच्छा समाधान है। एक छोटा सा सवाल, सिर्फ चेक के strValue.TrimEnd('0').TrimEnd('.')बजाय क्यों EndsWith?
नवाफाल

5

डिस्लेक्सिकनकोको के उत्तर पर आधारित एक और समाधान, लेकिन वर्तमान संस्कृति से स्वतंत्र:

public static string ToTrimmedString(this decimal num)
{
    string str = num.ToString();
    string decimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
    if (str.Contains(decimalSeparator))
    {
        str = str.TrimEnd('0');
        if(str.EndsWith(decimalSeparator))
        {
            str = str.RemoveFromEnd(1);
        }
    }
    return str;
}

public static string RemoveFromEnd(this string str, int characterCount)
{
    return str.Remove(str.Length - characterCount, characterCount);
}

महान। SqlDecimal को छोड़कर, यह क्षेत्रीय सेटिंग्स के बावजूद कल्चरइन्फो। InvariantCulture.NumberFormat.NumberDecimalSeparator है।
user2091150

4

विस्तार विधि:

public static class Extensions
{
    public static string TrimDouble(this string temp)
    {
        var value = temp.IndexOf('.') == -1 ? temp : temp.TrimEnd('.', '0');
        return value == string.Empty ? "0" : value;
    }
}

उदाहरण कोड:

double[] dvalues = {20, 20.00, 20.5, 20.5000, 20.125, 20.125000, 0.000};
foreach (var value in dvalues)
    Console.WriteLine(string.Format("{0} --> {1}", value, value.ToString().TrimDouble()));

Console.WriteLine("==================");

string[] svalues = {"20", "20.00", "20.5", "20.5000", "20.125", "20.125000", "0.000"};
foreach (var value in svalues)
    Console.WriteLine(string.Format("{0} --> {1}", value, value.TrimDouble()));

आउटपुट:

20 --> 20
20 --> 20
20,5 --> 20,5
20,5 --> 20,5
20,125 --> 20,125
20,125 --> 20,125
0 --> 0
==================
20 --> 20
20.00 --> 2
20.5 --> 20.5
20.5000 --> 20.5
20.125 --> 20.125
20.125000 --> 20.125
0.000 --> 0

1
"20.00 -> 2" मुझे लगता है कि यह अच्छा व्यवहार नहीं है। इसे ठीक करने के लिए ट्रिमएंड को दो बार कॉल करें: ट्रिमएंड ('0'); TrimEnd ( ',');
वादिम

2
ऊपर लिखे कोड का उपयोग न करें। @VadymK सही है कि इसका व्यवहार त्रुटिपूर्ण है। यह ट्राइलिंग जीरो ट्रिम कर देगा जो कि पीरियड नहीं होने पर पीरियड से पहले होता है।
Sevin7

2
स्टैकओवरफ्लो पर उत्तर कॉपी-पेस्ट के लिए नहीं है। उनका उपयोग सीखने के स्रोत के रूप में किया जाता है । यह sampel कोड आपको IndexOfएक स्ट्रिंग के भीतर वर्ण खोजने के लिए उपयोग करना सिखाता है । बिना किसी दशमलव के समस्या को हल करने के लिए उदाहरण को समायोजित करना काफी आसान है।
jgauffin

2

मुझे नहीं लगता कि यह आउट-ऑफ-द-बॉक्स संभव है लेकिन इस तरह की एक सरल विधि इसे करना चाहिए

public static string TrimDecimal(decimal value)
{
    string result = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
    if (result.IndexOf('.') == -1)
        return result;

    return result.TrimEnd('0', '.');
}

2

यह बॉक्स से बाहर करना काफी आसान है:

Decimal YourValue; //just as example   
String YourString = YourValue.ToString().TrimEnd('0','.');

यह आपके दशमलव से सभी अनुगामी शून्य हटा देगा।

केवल एक चीज जो आपको करने की आवश्यकता है वह .ToString().TrimEnd('0','.');एक दशमलव चर में जोड़कर बिना अनुगामी शून्य Decimalमें परिवर्तित करने के लिए है String, जैसे ऊपर दिए गए उदाहरण में।

कुछ क्षेत्रों में यह एक होना चाहिए .ToString().TrimEnd('0',',');(जहां वे एक बिंदु के बजाय अल्पविराम का उपयोग करते हैं, लेकिन आप सुनिश्चित करने के लिए पैरामीटर के रूप में एक डॉट और एक अल्पविराम भी जोड़ सकते हैं)।

(आप दोनों मापदंडों के रूप में भी जोड़ सकते हैं)


आपको इसका एहसास नहीं हो सकता है, लेकिन एक paramsतर्क के साथ काम करते समय , आपको स्पष्ट रूप से एक सरणी का निर्माण करने की आवश्यकता नहीं है। इसलिए क्रिया के बजाय TrimEnd("0".ToCharArray())आप सिर्फ लिख सकते हैं TrimEnd('0')(नोट: एक के charबजाय एकल पास char[])।
दान ताओ

@ दान ताओ: धन्यवाद, मैं यह भूल गया। जब से मैंने C # का उपयोग किया है तब से यह एक समय है। यद्यपि दोनों संस्करण काम करते हैं, मैंने अपनी पोस्ट संपादित की है।
मर्विन

@Mervin: आपको एक पास करने की आवश्यकता है char, न कि string(इसलिए: एकल उद्धरण, दोहरे उद्धरण नहीं)। मैंने इसे आपके लिए तय किया - उम्मीद है कि आप बुरा नहीं मानेंगे।
दान ताओ

1
आपका समाधान "2." जैसे आउटपुट का उत्पादन करेगा जब यह केवल शून्य मिला।
jgauffin

2
तब मैं कॉल करने का सुझाव दूंगा .ToString ()। TrimEnd ('0')। TrimEnd (''))। इसके बजाय '।' इसका बेहतर कल्चरइन्फो है। CurrentCulture.NumberFormat.NumberDecimalSeparator ताकि यह संस्कृतियों में काम करे।
11 Г И О И О


0

मैं निम्नलिखित कोड के साथ समाप्त हुआ:

    public static string DropTrailingZeros(string test)
    {
        if (test.Contains(CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator))
        {
            test = test.TrimEnd('0');
        }

        if (test.EndsWith(CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator))
        {
            test = test.Substring(0,
                test.Length - CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator.Length);
        }

        return test;
    }

0

मेरा इस संस्करण के साथ अंत है:

public static string Decimal2StringCompact(decimal value, int maxDigits)
    {
        if (maxDigits < 0) maxDigits = 0;
        else if (maxDigits > 28) maxDigits = 28;
        return Math.Round(value, maxDigits, MidpointRounding.ToEven).ToString("0.############################", CultureInfo.InvariantCulture);
    }

लाभ:

रनटाइम पर प्रदर्शित करने के बिंदु के बाद आप अधिकतम महत्वपूर्ण संख्या निर्दिष्ट कर सकते हैं;

आप स्पष्ट रूप से एक गोल विधि निर्दिष्ट कर सकते हैं;

आप स्पष्ट रूप से एक संस्कृति को नियंत्रित कर सकते हैं।


0

आप विस्तार विधि बना सकते हैं

public static class ExtensionMethod {
  public static decimal simplify_decimal(this decimal value) => decimal.Parse($"{this:0.############}");
}

0

मैंने अपनी परियोजनाओं में से एक को फिट करने के लिए खुद के लिए नीचे के विस्तार के तरीके बनाए, लेकिन शायद वे किसी और के लिए फायदेमंद होंगे।

using System.Numerics;
using System.Text.RegularExpressions;
internal static class ExtensionMethod
{
    internal static string TrimDecimal(this BigInteger obj) => obj.ToString().TrimDecimal();
    internal static string TrimDecimal(this decimal obj) => new BigInteger(obj).ToString().TrimDecimal();
    internal static string TrimDecimal(this double obj) => new BigInteger(obj).ToString().TrimDecimal();
    internal static string TrimDecimal(this float obj) => new BigInteger(obj).ToString().TrimDecimal();
    internal static string TrimDecimal(this string obj)
    {
        if (string.IsNullOrWhiteSpace(obj) || !Regex.IsMatch(obj, @"^(\d+([.]\d*)?|[.]\d*)$")) return string.Empty;
        Regex regex = new Regex("^[0]*(?<pre>([0-9]+)?)(?<post>([.][0-9]*)?)$");
        MatchEvaluator matchEvaluator = m => string.Concat(m.Groups["pre"].Length > 0 ? m.Groups["pre"].Value : "0", m.Groups["post"].Value.TrimEnd(new[] { '.', '0' }));
        return regex.Replace(obj, matchEvaluator);
    }
}

हालांकि इसके लिए एक संदर्भ की आवश्यकता होगी System.Numerics

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