Лучший способ отображения десятичной дроби без конечных нулей
Есть ли форматор отображения, который будет выводить десятичные числа в виде этих строковых представлений в С# без округления?
// 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 не будет работать с связанным числовым столбцом в сетке.
Ответы
Ответ 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;
}