Подтвердить что ты не робот

Лучший способ отображения десятичной дроби без конечных нулей

Есть ли форматор отображения, который будет выводить десятичные числа в виде этих строковых представлений в С# без округления?

// 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. #} будет округлять, и использование некоторой функции типа Trim не будет работать с связанным числовым столбцом в сетке.

4b9b3361

Ответ 1

У вас есть максимальное количество десятичных знаков, которые вам когда-либо понадобится для отображения? (Ваши примеры имеют максимум 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.#####"));
    }

Ответ 2

Я только что узнал, как правильно использовать спецификатор формата 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

Ответ 3

Этот формат строки должен сделать ваш день: "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

Это еще одна вариация того, что я видел выше. В моем случае мне нужно сохранить все значащие цифры справа от десятичной точки, что означает падение всех нулей после самой значащей цифры. Просто подумал, что было бы приятно поделиться. Я не могу ручаться за эффективность этого, хотя, но когда вы пытаетесь достичь эстетики, вы уже в значительной степени прокляты неэффективностью.

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;
}

Это все, просто хотел бросить мои два цента.

Ответ 5

Метод расширения:

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

Ответ 6

Это довольно легко сделать из коробки:

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

который удалит все конечные нули из десятичного числа.

Единственное, что вам нужно сделать, это добавить .ToString().TrimEnd('0','.'); в десятичную переменную, чтобы преобразовать десятичный код в строку без конечных нулей, как в приведенном выше примере.

В некоторых регионах это должно быть .ToString().TrimEnd('0',','); (где они вместо нас являются запятой, но вы можете также добавить точку и запятую в качестве параметров)

(вы также можете добавить оба параметра)

Ответ 7

Другое решение, основанное на ответе dyslexicanaboko, но не зависящее от текущей культуры:

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);
}

Ответ 8

Я не думаю, что это возможно из коробки, но простой способ, как это, должен сделать это

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

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

Ответ 9

decimal val = 0.000000000100m;
string result = val == 0 ? "0" : val.ToString().TrimEnd('0').TrimEnd('.');

Ответ 10

В итоге я получил следующий код:

    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;
    }