У меня есть несколько полей, возвращаемых коллекцией как
2.4200
2.0044
2.0000
Мне нужны результаты, такие как
2.42
2.0044
2
Я попытался с String.Format
, но он возвращает 2.0000
, а его значение в N0
округляет другие значения.
У меня есть несколько полей, возвращаемых коллекцией как
2.4200
2.0044
2.0000
Мне нужны результаты, такие как
2.42
2.0044
2
Я попытался с String.Format
, но он возвращает 2.0000
, а его значение в N0
округляет другие значения.
Разве это не так просто, как если бы вход был строкой? Вы можете использовать один из них:
string.Format("{0:G29}", decimal.Parse("2.0044"))
decimal.Parse("2.0044").ToString("G29")
2.0m.ToString("G29")
Это должно работать для всех входных данных.
Обновить Проверьте Стандартные числовые форматы Мне пришлось явно установить спецификатор точности 29 в качестве В документах четко указано:
Однако, если число является десятичным и спецификатор точности опущен, всегда используется нотация с фиксированной точкой и сохраняются завершающие нули
Обновить Konrad отметил в комментариях:
Следите за такими значениями, как 0,000001. Формат G29 представит их как можно скорее, чтобы он переключился на экспоненциальную нотацию.
string.Format("{0:G29}", decimal.Parse("0.00000001",System.Globalization.CultureInfo.GetCultureInfo("en-US")))
даст результат "1E-08".
Я столкнулся с одной и той же проблемой, но в случае, когда я не контролирую вывод в строку, которая была решена библиотекой. Изучив детали в реализации десятичного типа (см. http://msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx), Я придумал опрятный трюк (здесь как метод расширения):
public static decimal Normalize(this decimal value)
{
return value/1.000000000000000000000000000000000m;
}
Показательная часть десятичной дроби сводится к тому, что необходимо. Вызов ToString() в выходном десятичном значении будет записывать номер без какого-либо конечного 0. Например:
1.200m.Normalize().ToString();
По-моему, это безопаснее использовать Пользовательские строки числового формата.
decimal d = 0.00000000000010000000000m;
string custom = d.ToString("0.#########################");
// gives: 0,0000000000001
string general = d.ToString("G29");
// gives: 1E-13
Я использую этот код, чтобы избежать научной нотации "G29":
public static string DecimalToString(decimal dec)
{
string strdec = dec.ToString(CultureInfo.InvariantCulture);
return strdec.Contains(".") ? strdec.TrimEnd('0').TrimEnd('.') : strdec;
}
Используйте символ хеширования (#
), чтобы отображать только конечный результат 0. См. Тесты ниже.
decimal num1 = 13.1534545765;
decimal num2 = 49.100145;
decimal num3 = 30.000235;
num1.ToString("0.##"); //13.15%
num2.ToString("0.##"); //49.1%
num3.ToString("0.##"); //30%
Я нашел элегантное решение от http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/
В основном
decimal v = 2.4200M;
v.ToString( "# ######" );//Вернется 2.42. Число # - количество десятичных цифр, которые вы поддерживаете.
Это будет работать:
decimal source = 2.4200m;
string output = ((double)source).ToString();
Или, если ваше начальное значение - string
:
string source = "2.4200";
string output = double.Parse(source).ToString();
Обратите внимание на этот комментарий.
В зависимости от того, что представляет ваш номер и как вы хотите управлять значениями: это валюта, вам нужно округление или усечение, вам нужно это округление только для отображения?
Если для отображения рассмотреть форматирование чисел, это x.ToString("")
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx и
http://msdn.microsoft.com/en-us/library/0c899ak8.aspx
Если это просто округление, используйте перегрузку Math.Round, которая требует перегрузки MidPointRounding
http://msdn.microsoft.com/en-us/library/ms131274.aspx)
Если вы получаете свое значение из базы данных, подумайте о литье вместо преобразования: double value = (decimal) myRecord [ "columnName" ];
Очень низкоуровневый подход, но я считаю, что это было бы самым результативным способом, используя только быстрые вычисления с целым числом (и без медленного анализа строк и чувствительных к культуре методов):
public static decimal Normalize(this decimal d)
{
int[] bits = decimal.GetBits(d);
int sign = bits[3] & (1 << 31);
int exp = (bits[3] >> 16) & 0x1f;
uint a = (uint)bits[2]; // Top bits
uint b = (uint)bits[1]; // Middle bits
uint c = (uint)bits[0]; // Bottom bits
while (exp > 0 && ((a % 5) * 6 + (b % 5) * 6 + c) % 10 == 0)
{
uint r;
a = DivideBy10((uint)0, a, out r);
b = DivideBy10(r, b, out r);
c = DivideBy10(r, c, out r);
exp--;
}
bits[0] = (int)c;
bits[1] = (int)b;
bits[2] = (int)a;
bits[3] = (exp << 16) | sign;
return new decimal(bits);
}
private static uint DivideBy10(uint highBits, uint lowBits, out uint remainder)
{
ulong total = highBits;
total <<= 32;
total = total | (ulong)lowBits;
remainder = (uint)(total % 10L);
return (uint)(total / 10L);
}
Очень простой ответ - использовать TrimEnd(). Вот результат:
double value = 1.00;
string output = value.ToString().TrimEnd('0');
Выход равен 1 Если мое значение равно 1.01, тогда мой вывод будет 1.01
Если вы хотите сохранить десятичное число, попробуйте следующий пример:
number = Math.Floor(number * 100000000) / 100000000;
Это просто
decimal decNumber = Convert.ToDecimal(value);
return decNumber.ToString("0.####");
Проверено.
Ура :)
Вы можете просто установить как:
decimal decNumber = 23.45600000m;
Console.WriteLine(decNumber.ToString("0.##"));
или вы можете преобразовать двойное значение в double, как Convert.ToDouble([double vlaue])
. он удалит конечный ноль, если он есть.
Следующий код может использоваться, чтобы не использовать тип строки:
int decimalResult = 789.500
while (decimalResult>0 && decimalResult % 10 == 0)
{
decimalResult = decimalResult / 10;
}
return decimalResult;
Возвращает 789.5
Усекать конечные Zeros очень легко, разрешить с помощью дуплексного литья:
decimal mydecimal = decimal.Parse("1,45000000"); //(I)
decimal truncate = (decimal)(double)mydecimal; //(II)
(I) → Разделить десятичное значение из любого источника строки.
(II) → Сначала: Сдвинуть, чтобы удвоить это, удалите конечные нули. Second: Other cast to decimal, потому что не существует неявного преобразования из десятичного в double и наоборот)
попробуйте этот код:
string value = "100";
value = value.Contains(".") ? value.TrimStart('0').TrimEnd('0').TrimEnd('.') : value.TrimStart('0');
попробуйте это
string s = "2.4200";
s = s.TrimStart('0').TrimEnd('0', '.');
а затем преобразуйте его в float