Как мне округлить десятичное значение до 2 знаков после запятой (для вывода на страницу)
Вопрос
При отображении значения десятичной дроби, в данный момент с .ToString()
, с точностью до 15 знаков после запятой, и поскольку я использую его для представления долларов и центов, я хочу, чтобы результат был равен только 2 знакам после запятой.
Использую ли я вариант .ToString()
за это?
Решение
decimalVar.ToString ("#.##"); // returns "" when decimalVar == 0
или
decimalVar.ToString ("0.##"); // returns "0" when decimalVar == 0
Другие советы
Я знаю, что это старый вопрос, но я был удивлен, увидев, что никто не опубликовал такой ответ;
<Ол>Это то, что я бы использовал:
decimal.Round(yourValue, 2, MidpointRounding.AwayFromZero);
decimalVar.ToString("F");
Это будет:
- Округлите до 2 знаков после запятой, например.23.456 => 23.46
- Убедитесь, что в нем всегда есть 2 знака после запятой, например.23 => 23.00, 12.5 => 12.50
Идеально подходит для обмена валюты и отображения денежных сумм.
Для получения документации по toString("F"): http://msdn.microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx#FFormatString (с благодарностью Джону Шнайдеру)
Если вам просто нужно это для отображения, используйте строку. Формат
String.Format("{0:0.00}", 123.4567m); // "123.46"
http://www.csharp-examples.net/string-format-double / р>
" m " является десятичным суффиксом. О десятичном суффиксе:
С учетом десятичного числа d = 12.345; выражения d.ToString (" C ") или String.Format (" {0: C} ") ;, d) доход $ 12,35 - обратите внимание, что используются текущие настройки валюты культуры, включая символ.
Обратите внимание, что " C " использует количество цифр из текущей культуры. Вы всегда можете переопределить значение по умолчанию, чтобы принудительно установить необходимую точность, используя C {Precision спецификатор}
, например String.Format (" {0: C2} " ;, 5.123d)
. . р>
Если вы хотите, чтобы он был отформатирован запятыми, а также десятичной запятой (но без символа валюты), например, 3 456 789,12 ...
decimalVar.ToString("n2");
Уже есть два ответа с высокими оценками, которые относятся к Decimal.Round (...), но я думаю, что требуется немного больше объяснений - потому что есть неожиданное важное свойство Decimal, которое не очевидно.
Десятичное число «знает», сколько десятичных разрядов оно основало на том, откуда оно пришло.
Например, следующее может быть неожиданным:
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% вероятности, это потому, что это валюта, и в этом случае это, вероятно, хорошо для 95% времени:
Decimal.Parse("25.0").ToString("c") => "$25.00"
Или в XAML вы просто используете {Binding Price, StringFormat = c}
В одном случае я столкнулся с необходимостью использования десятичной дробной части, так как десятичная дробь была при отправке XML на веб-сервис Amazon. Служба жаловалась, потому что десятичное значение (первоначально из SQL Server) было отправлено как 25.1200
и отклонено ( 25.12
было ожидаемым форматом).
Все, что мне нужно было сделать, это Decimal.Round (...)
с двумя десятичными знаками для решения проблемы.
// This is an XML message - with generated code by XSD.exe
StandardPrice = new OverrideCurrencyAmount()
{
TypedValue = Decimal.Round(product.StandardPrice, 2),
currency = "USD"
}
TypedValue
относится к типу Decimal
, поэтому я не мог просто сделать ToString (" N2 ")
и ему нужно было округлить его и сохранить это как десятичный
.
Вот небольшая программа 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: <*>.00
0.00: 0.00
0.##: 0
===================
ToString: 0.007
c: <*>.01
0.00: 0.01
0.##: 0.01
===================
Ни один из них не сделал именно то, что мне было нужно, чтобы заставить 2 д.п. и округлить до Принудительное 2 д.п. требует повышения точности на 2 д.п. чтобы у нас было минимум 2 д.п. Р>
затем округление, чтобы убедиться, что у нас не более 2 д.п. 0,005 - > 0.01 Код> р>
Math.Round(exactResult * 1.00m, 2, MidpointRounding.AwayFromZero)
6.665m.ToString() -> "6.67"
6.6m.ToString() -> "6.60"
Очень редко вы захотите пустую строку, если значение равно 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 минут времени (большинства) людей.
Ответ с самым высоким рейтингом описывает метод форматирования строкового представления десятичного значения, и он работает.
Однако, если вы действительно хотите изменить точность, сохраненную на фактическое значение, вам нужно написать что-то вроде следующего:
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"));
}
Вы можете использовать system.globalization для форматирования числа в любом необходимом формате.
Например:
system.globalization.cultureinfo ci = new system.globalization.cultureinfo("en-ca");
Если у вас десятичное число d = 1.2300000
, и вам нужно обрезать его до 2 десятичных знаков, тогда его можно напечатать следующим образом: d.Tostring (" F2 ", ci);
где F2 - форматирование строки с двумя десятичными разрядами, а ci - локаль или cultureinfo. Р>
для получения дополнительной информации проверьте эту ссылку
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx р>
Ответ Майка М. был идеален для меня в .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);
}
https://msdn.microsoft. ком / EN-US / библиотека / dwhawy9k% 28В = vs.110% 29.aspx
Эта ссылка подробно объясняет, как вы можете решить свою проблему и что вы можете сделать, если хотите узнать больше. Для простоты, то, что вы хотите сделать, это
double whateverYouWantToChange = whateverYouWantToChange.ToString("F2");
если вы хотите это для валюты, вы можете сделать это проще, набрав " C2 " вместо "F2"