Как округлить десятичное значение до 2 десятичных знаков (для вывода на страницу)

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

Я использую вариант .ToString() за это?

19 ответов

Решение
decimalVar.ToString ("#.##"); // returns "" when decimalVar == 0

или же

decimalVar.ToString ("0.##"); // returns "0"  when decimalVar == 0

Я знаю, что это старый вопрос, но я был удивлен, увидев, что никто, кажется, не отправил ответ, который;

  1. Не использовал округление банкиров
  2. Не сохранил значение как десятичное.

Вот что я бы использовал:

decimal.Round(yourValue, 2, MidpointRounding.AwayFromZero);

http://msdn.microsoft.com/en-us/library/9s0xa85y.aspx

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 (с благодарностью Джону Шнайдеру)

Если вам просто нужно это для отображения, используйте строку. Формат

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

Если вы хотите, чтобы он был отформатирован с запятыми, а также с десятичной точкой (но без символа валюты), например, 3 456 789,12...

decimalVar.ToString("n2");

Дано десятичное d=12,345; выражения d.ToString("C") или String.Format("{0:C}", d) дают $12,35 - обратите внимание, что используются текущие настройки валюты культуры, включая символ.

Обратите внимание, что "C" использует количество цифр из текущей культуры. Вы всегда можете переопределить значение по умолчанию, чтобы добиться необходимой точности с C{Precision specifier} лайк String.Format("{0:C2}", 5.123d),

Уже есть два ответа с высокими оценками, которые относятся к 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}

Один случай, с которым я столкнулся, когда мне нужно было десятичное число AS как десятичное, было при отправке 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") и нужно было округлить его и сохранить как decimal,

Вот небольшая программа 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
===================

Очень редко вы захотите пустую строку, если значение равно 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 минут времени (большинства) людей.

Ответ Майка М. был идеальным для меня в.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);
}

Ответ с самым высоким рейтингом описывает метод форматирования строкового представления десятичного значения, и он работает.

Однако, если вы действительно хотите изменить сохраненную точность на фактическое значение, вам нужно написать что-то вроде следующего:

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"));
}

Ни один из них не сделал именно то, что мне было нужно, чтобы заставить 2 дп и округлить как 0.005 -> 0.01

Форсирование 2 дп требует повышения точности на 2 дп, чтобы обеспечить как минимум 2 дп

затем округление, чтобы убедиться, что у нас не более 2 дп

Math.Round(exactResult * 1.00m, 2, MidpointRounding.AwayFromZero)

6.665m.ToString() -> "6.67"

6.6m.ToString() -> "6.60"

Вы можете использовать system.globalization для форматирования числа в любом необходимом формате.

Например:

system.globalization.cultureinfo ci = new system.globalization.cultureinfo("en-ca");

Если у тебя есть decimal d = 1.2300000 и вам нужно обрезать его до 2 десятичных знаков, то это может быть напечатано так d.Tostring("F2",ci); где F2 - форматирование строки с двумя десятичными разрядами, а ci - локаль или cultureinfo.

для получения дополнительной информации проверьте эту ссылку
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx

Наиболее применимым решением является

      decimalVar.ToString("#.##");

https://msdn.microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx

Эта ссылка подробно объясняет, как вы можете решить свою проблему и что вы можете сделать, если хотите узнать больше. Для простоты, то, что вы хотите сделать, это

double whateverYouWantToChange = whateverYouWantToChange.ToString("F2");

если вы хотите это для валюты, вы можете сделать это проще, набрав "C2" вместо "F2"

Если вам нужно сохранить только 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
Double Amount = 0;
string amount;
amount=string.Format("{0:F2}", Decimal.Parse(Amount.ToString()));
              var arr = new List<int>() { -4, 3, -9, 0, 4, 1 };
        decimal result1 = arr.Where(p => p > 0).Count();
        var responseResult1 = result1 / arr.Count();
        decimal result2 = arr.Where(p => p < 0).Count();
        var responseResult2 = result2 / arr.Count();
        decimal result3 = arr.Where(p => p == 0).Count();
        var responseResult3 = result3 / arr.Count();
        Console.WriteLine(String.Format("{0:#,0.000}", responseResult1));
        Console.WriteLine(String.Format("{0:#,0.0000}", responseResult2));
        Console.WriteLine(String.Format("{0:#,0.00000}", responseResult3));

вы можете поставить столько 0, сколько хотите.

Другие вопросы по тегам