15 ответов:
разве это не так просто, если вход является строкой? Вы можете использовать один из них:
string.Format("{0:G29}", decimal.Parse("2.0044")) decimal.Parse("2.0044").ToString("G29") 2.0m.ToString("G29")Это должно работать для всех входных.
обновление Проверьте Стандартные Числовые Форматы мне пришлось явно установить спецификатор точности в 29, поскольку документы четко указывают:
однако, если число десятичное и спецификатор точности опущен, всегда используется фиксированная нотация и конечные нули сохранилось
обновлениеКонрадуказал комментарий:
следите за такими значениями, как 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() на выходе decimal запишет число без какого-либо трейлинга 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; }
Я нашел элегантное решение от http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/
в принципе
decimal v=2.4200 M;
v. ToString ("#.######"); // Вернет 2.42. Число # - это количество поддерживаемых десятичных цифр.
использовать хэш-код (
#) символ для отображения только трейлинг 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%
это именно то, что вы хотите:
если начальное значение
decimal: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
Если это просто округление, используйте математику.Круглая перегрузка, которая требует перегрузки 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
следующий код может быть использован, чтобы не использовать тип строки:
int decimalResult = 789.500 while (decimalResult>0 && decimalResult % 10 == 0) { decimalResult = decimalResult / 10; } return decimalResult;возвращает 789.5
вы можете просто установить как:
decimal decNumber = 23.45600000m; Console.WriteLine(decNumber.ToString("0.##"));
усечь конечные нули очень легко, решить с помощью дуплексного приведения:
decimal mydecimal = decimal.Parse("1,45000000"); //(I) decimal truncate = (decimal)(double)mydecimal; //(II)(I) -- > разбор десятичного значения из любого строкового источника.
(II) -- > Во-первых: приведение, чтобы удвоить это удалить конечные нули. Во-вторых: другое приведение к десятичной, потому что не существует неявного преобразования из десятичной в двойную и наоборот)
попробуйте этот код:
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
Comments