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

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

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

15 ответов


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

или

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

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" является десятичным суффиксом. О десятичном суффиксе:

http://msdn.microsoft.com/en-us/library/364x0z75.aspx


дано decimal d=12.345; выражения d.ToString ("C") или строку.Формат ("{0: C}", d) доходность 12.35$ - обратите внимание, что используются настройки валюты текущей культуры, включая символ.

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


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

decimalVar.ToString("n2");

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

когда вы хотите десятичный до 2 десятичных знаков, существует вероятность 95%, потому что это валюта, и в этом случае это, вероятно, хорошо для 95% времени:

Decimal.Parse("25.0").ToString("c")     =>   ".00"

или в XAML вы просто используете {Binding Price, StringFormat=c}

один случай, с которым я столкнулся, где мне нужен десятичный как десятичный, был при отправке XML на веб-сервис Amazon. Служба жаловалась, потому что десятичное значение (первоначально из SQL Server) отправлялось как 25.1200 и отверг, (25.12 был ожидаемый формат).

все, что мне нужно было Decimal.Round(...) С 2 десятичными знаками, чтобы устранить проблему.

 // 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: ,345.95
0.00: 2345.95
0.##: 2345.95
===================
ToString: 43
c: .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 сут.п. и как 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"

вы можете использовать системы.глобализация для форматирования числа в любом требуемом формате.

например:

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

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

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


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

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

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

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


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