При отображении значения десятичной дроби в настоящее время с .ToString() оно соответствует 15 десятичным разрядам, а поскольку я использую его для представления долларов и центов, я хочу, чтобы на выходе было только 2 десятичных знака.
Могу ли я использовать для этого вариант .ToString()?





decimalVar.ToString ("#.##"); // returns "" when decimalVar == 0
или же
decimalVar.ToString ("0.##"); // returns "0" when decimalVar == 0
проблема здесь в том, что у нас 0,00; он возвращает пустую строку.
Затем вы можете сделать decimalVar.ToString ("0. ##"). Вы также можете использовать 0,00 в качестве строки форматирования.
@MikeCole Я не думаю, что вы можете выполнить усечение с помощью одного только форматирования - единственный известный мне способ - сначала передать его в Math.Floor, например, (Math.Floor (decimalVar * 100M) / 100M) .ToString ( «0.00») должно работать (и если вы используете двойные, а не десятичные дроби, используйте, конечно, 100D вместо 100M).
С этим решением у вас не будет форматирования культуры, которое можно было бы ожидать при чтении чисел. Для этого вы должны использовать ToString («N2») или ToString («N»).
Это очень вводящий в заблуждение ответ. Это просто создает новую строку, но числовое значение остается неизменным. Это создает хаос в любом другом месте, где используется это количество. Это серьезная проблема, не позволяющая понизить десятичную версию типа до некоторого количества десятичных знаков.
Метод @Hill Decimal и DoubleToString принимает аргумент для форматирования. Попробуйте сначала преобразовать ваше значение в десятичное / двойное.
@ f470071 Десятичные дроби являются типами значений и, как таковые, никогда не "модифицируются". Тем не менее, от ToString () никогда не ожидалось, что он изменит содержимое того, что вызвано.
Работает нормально для десятичных знаков. Если это целое число, то "#. ##" будет игнорировать десятичные знаки. Однако "{0: #, ## 0.00}" будет работать как для десятичных, так и для целых чисел.
@Hill Вы можете получить эту ошибку с типом, допускающим значение NULL. Попробуйте yourNumber.Value.ToString (0. ##), чтобы решить вашу проблему.
Приведенное ниже решение лучше, поскольку оно рассматривает его как десятичное и возвращает десятичное.
Если вам это просто нужно для отображения, используйте string.Format
String.Format("{0:0.00}", 123.4567m); // "123.46"
http://www.csharp-examples.net/string-format-double/
«M» - десятичный суффикс. О десятичном суффиксе:
http://msdn.microsoft.com/en-us/library/364x0z75.aspx
Технически, для десятичной дроби это будет 123,4567 м, да? Без суффикса "m" это двойное
или ярлык $ "{value: 0.00}"
Метод Math.Round (Decimal, Int32)
это не использует банковское округление?
Это лучший способ, потому что значение не преобразуется в строку, и вы по-прежнему можете выполнять математические операции.
@Danimal: вы можете указать третий аргумент, чтобы изменить тип округления
Учитывая десятичный d = 12,345;, выражения d.ToString ("C") или String.Format ("{0: C}", d) дают 12,35 долл. США - обратите внимание, что используются настройки валюты текущего языка, включая символ.
Обратите внимание, что "C" использует количество цифр из текущего языка и региональных параметров. Вы всегда можете изменить значение по умолчанию, чтобы добиться необходимой точности с помощью C{Precision specifier}, например String.Format("{0:C2}", 5.123d).
@ Slick86 - знак валюты
Если вы хотите, чтобы он был отформатирован запятыми, а также десятичной точкой (но без символа валюты), например 3,456,789,12 ...
decimalVar.ToString("n2");
Лучший ответ, так как вопрос касался вывода на страницу, а форматирование чисел важно для больших чисел. Кроме того, «n *» учитывает текущий язык и региональные параметры, поэтому это может быть «3.456.789,12», «3 456 789,12» и т. д.
decimalVar.ToString("F");
Это будет:
23.456 → 23.4623 → 23.00; 12.5 → 12.50Идеально подходит для отображения валюты.
Ознакомьтесь с документацией по ToString ("F") (спасибо Джону Шнайдеру).
Это отлично работает, когда есть только 1 десятичный знак; .ToString ("#. ##") не работает. Этот ответ намного лучше
Разве не было бы 23,456 => 23,46?
Документация о том, что здесь означает буква "F" и как это работает: msdn.microsoft.com/en-us/library/…
Почему бы не .ToString («N») вместо «F»? Насколько я понимаю, они оба будут работать для нужд этого вопроса, но N также будет ставить запятые для чисел в тысячах.
Примечание. . может быть заменен на , в зависимости от культуры. Вы должны передать CultureInfo.InvariantCulture в качестве второго аргумента, чтобы отключить это.
Я знаю, что это старый вопрос, но я был удивлен, увидев, что никто не опубликовал ответ на этот вопрос;
Вот что я бы использовал:
decimal.Round(yourValue, 2, MidpointRounding.AwayFromZero);
http://msdn.microsoft.com/en-us/library/9s0xa85y.aspx
ToString или string.Format без банковского округления: msdn.microsoft.com/en-us/library/0c899ak8.aspx#sectionToggle 1
@MatthijsWessels Я знаю ... но он также не сохраняет значение в виде десятичной дроби.
Это лучший способ по-настоящему представить два десятичных знака, поскольку при этом не будут отбрасываться нули в конце.
Вы можете использовать system.globalization для форматирования числа в любом требуемом формате.
Например:
system.globalization.cultureinfo ci = new system.globalization.cultureinfo("en-ca");
Если у вас есть decimal d = 1.2300000, и вам нужно обрезать его до 2 знаков после запятой, его можно напечатать, как этот d.Tostring("F2",ci);, где F2 - это строка, форматируемая до 2 знаков после запятой, а ci - это локаль или информация о культуре.
для получения дополнительной информации проверьте эту ссылку http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx
+1, но - объект CultureInfo будет влиять только на символ Юникода, используемый для обозначения десятичного разряда. например. fr-FR будет использовать запятую вместо точки. Это не связано с количеством отображаемых десятичных знаков.
У Decimal есть очень важная характеристика, которая не очевидна:
A
Decimal'knows' how many decimal places it has based upon where it came from
Следующее может быть неожиданным:
Decimal.Parse("25").ToString() => "25"
Decimal.Parse("25.").ToString() => "25"
Decimal.Parse("25.0").ToString() => "25.0"
Decimal.Parse("25.0000").ToString() => "25.0000"
25m.ToString() => "25"
25.000m.ToString() => "25.000"
Выполнение тех же операций с Double приведет к нулю десятичных знаков ("25") для всех приведенных выше примеров.
Если вы хотите использовать десятичную дробь до двух знаков после запятой, высока вероятность того, что это валюта, и в этом случае это, вероятно, нормально в 95% случаев:
Decimal.Parse("25.0").ToString("c") => ".00"
Или в XAML вы бы использовали {Binding Price, StringFormat=c}
Я столкнулся с одним случаем, когда мне понадобилось десятичное число AS a decimal, когда я отправлял XML в веб-сервис Amazon. Служба жаловалась, потому что десятичное значение (изначально из SQL Server) было отправлено как 25.1200 и отклонено (25.12 был ожидаемым форматом).
Все, что мне нужно было сделать, это Decimal.Round(...) с двумя десятичными знаками, чтобы решить проблему независимо от источника значения.
// generated code by XSD.exe
StandardPrice = new OverrideCurrencyAmount()
{
TypedValue = Decimal.Round(product.StandardPrice, 2),
currency = "USD"
}
TypedValue относится к типу Decimal, поэтому я не мог просто сделать ToString("N2"), и мне нужно было округлить его и оставить как decimal.
+1 это отличный ответ. Когда вы говорите, что System.Decimal «знает, сколько десятичных знаков имеет» - это означает, что System.Decimal не является саморегулирующийся, как другие типы с плавающей запятой. Еще одно полезное свойство System.Decimal состоит в том, что результат математических операций всегда имеет наибольшее количество десятичных знаков из входных аргументов, т.е. 1.0 м + 2.000 м = 3.000 м. Вы можете использовать этот факт, чтобы преобразовать десятичную дробь без десятичных знаков в 2 десятичных разряда, просто умножив ее на 1,00 м, например. 10 м * 1,00 м = 10,00 м.
MattDavey неверен, добавлена десятичная точность. (1,0 м * 1,00 м) .ToString () = "1.000"
Очень, очень полезно знать, что «десятичное число« знает », сколько десятичных знаков оно имеет, в зависимости от того, откуда оно взялось». Большое спасибо!
ценю ваш ответ и объяснение!
Ни один из них не сделал именно то, что мне нужно, чтобы заставить 2 п.п. и округлить до 0.005 -> 0.01
Форсирование 2 д.п. требует увеличения точности на 2 п.п. чтобы у нас было не менее 2 д.п.
затем округляем, чтобы убедиться, что у нас не более 2 d.p.
Math.Round(exactResult * 1.00m, 2, MidpointRounding.AwayFromZero)
6.665m.ToString() -> "6.67"
6.6m.ToString() -> "6.60"
Вот небольшая программа Linqpad для отображения разных форматов:
void Main()
{
FormatDecimal(2345.94742M);
FormatDecimal(43M);
FormatDecimal(0M);
FormatDecimal(0.007M);
}
public void FormatDecimal(decimal val)
{
Console.WriteLine("ToString: {0}", val);
Console.WriteLine("c: {0:c}", val);
Console.WriteLine("0.00: {0:0.00}", val);
Console.WriteLine("0.##: {0:0.##}", val);
Console.WriteLine("================== = ");
}
Вот результаты:
ToString: 2345.94742
c: $2,345.95
0.00: 2345.95
0.##: 2345.95
===================
ToString: 43
c: $43.00
0.00: 43.00
0.##: 43
===================
ToString: 0
c: $0.00
0.00: 0.00
0.##: 0
===================
ToString: 0.007
c: $0.01
0.00: 0.01
0.##: 0.01
===================
https://msdn.microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx
Эта ссылка подробно объясняет, как вы можете решить свою проблему и что вы можете сделать, если хотите узнать больше. Для простоты вам нужно
double whateverYouWantToChange = whateverYouWantToChange.ToString("F2");
если вы хотите получить это для валюты, вы можете упростить задачу, набрав «C2» вместо «F2».
Ответ Майка М. идеально подходил для меня в .NET, но .NET Core не имеет метода decimal.Round на момент написания.
В .NET Core мне пришлось использовать:
decimal roundedValue = Math.Round(rawNumber, 2, MidpointRounding.AwayFromZero);
Хакерский метод, включая преобразование в строку, это:
public string FormatTo2Dp(decimal myNumber)
{
// Use schoolboy rounding, not bankers.
myNumber = Math.Round(myNumber, 2, MidpointRounding.AwayFromZero);
return string.Format("{0:0.00}", myNumber);
}
Очень редко вам нужна пустая строка, если значение равно 0.
decimal test = 5.00;
test.ToString("0.00"); //"5.00"
decimal? test2 = 5.05;
test2.ToString("0.00"); //"5.05"
decimal? test3 = 0;
test3.ToString("0.00"); //"0.00"
Ответ с наивысшей оценкой неверен и потратил 10 минут (большинства) людей впустую.
в основном "#" означает цифру числа (при необходимости) (без заполнения, если не требуется) "0" означает цифру числа (не важно, что) (с нулями, если недоступно)
Самый популярный ответ описывает метод форматирования строковое представление десятичного значения, и он работает.
Однако, если вы действительно хотите изменить точность, сохраненную до фактического значения, вам нужно написать что-то вроде следующего:
public static class PrecisionHelper
{
public static decimal TwoDecimalPlaces(this decimal value)
{
// These first lines eliminate all digits past two places.
var timesHundred = (int) (value * 100);
var removeZeroes = timesHundred / 100m;
// In this implementation, I don't want to alter the underlying
// value. As such, if it needs greater precision to stay unaltered,
// I return it.
if (removeZeroes != value)
return value;
// Addition and subtraction can reliably change precision.
// For two decimal values A and B, (A + B) will have at least as
// many digits past the decimal point as A or B.
return removeZeroes + 0.01m - 0.01m;
}
}
Пример модульного теста:
[Test]
public void PrecisionExampleUnitTest()
{
decimal a = 500m;
decimal b = 99.99m;
decimal c = 123.4m;
decimal d = 10101.1000000m;
decimal e = 908.7650m
Assert.That(a.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
Is.EqualTo("500.00"));
Assert.That(b.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
Is.EqualTo("99.99"));
Assert.That(c.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
Is.EqualTo("123.40"));
Assert.That(d.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
Is.EqualTo("10101.10"));
// In this particular implementation, values that can't be expressed in
// two decimal places are unaltered, so this remains as-is.
Assert.That(e.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
Is.EqualTo("908.7650"));
}
Double Amount = 0;
string amount;
amount=string.Format("{0:F2}", Decimal.Parse(Amount.ToString()));
Если вам нужно оставить только 2 десятичных разряда (т.е. обрезать все остальные десятичные цифры):
decimal val = 3.14789m;
decimal result = Math.Floor(val * 100) / 100; // result = 3.14
Если вам нужно сохранить только 3 десятичных знака:
decimal val = 3.14789m;
decimal result = Math.Floor(val * 1000) / 1000; // result = 3.147