Как отобразить десятичное значение с точностью до 2 знаков после запятой?

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

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

Здесь is a brief example of the different options for formatting floating point values (alignment, number of digits, group separators, exponential, percent, currency, etc.).
saastn 02.03.2021 02:33
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
698
1
1 122 780
17
Перейти к ответу Данный вопрос помечен как решенный

Ответы 17

Ответ принят как подходящий

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

или же

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

проблема здесь в том, что у нас 0,00; он возвращает пустую строку.

Jronny 04.05.2010 14:13

Затем вы можете сделать decimalVar.ToString ("0. ##"). Вы также можете использовать 0,00 в качестве строки форматирования.

albertein 04.05.2010 19:14

@MikeCole Я не думаю, что вы можете выполнить усечение с помощью одного только форматирования - единственный известный мне способ - сначала передать его в Math.Floor, например, (Math.Floor (decimalVar * 100M) / 100M) .ToString ( «0.00») должно работать (и если вы используете двойные, а не десятичные дроби, используйте, конечно, 100D вместо 100M).

BrainSlugs83 26.08.2013 13:50

С этим решением у вас не будет форматирования культуры, которое можно было бы ожидать при чтении чисел. Для этого вы должны использовать ToString («N2») или ToString («N»).

Shautieh 21.08.2014 19:54

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

f470071 02.10.2015 15:13

Метод @Hill Decimal и DoubleToString принимает аргумент для форматирования. Попробуйте сначала преобразовать ваше значение в десятичное / двойное.

sohaiby 13.03.2016 11:05

@ f470071 Десятичные дроби являются типами значений и, как таковые, никогда не "модифицируются". Тем не менее, от ToString () никогда не ожидалось, что он изменит содержимое того, что вызвано.

Justin Skiles 26.08.2016 15:35

Работает нормально для десятичных знаков. Если это целое число, то "#. ##" будет игнорировать десятичные знаки. Однако "{0: #, ## 0.00}" будет работать как для десятичных, так и для целых чисел.

Rahatur 03.10.2016 22:50

@Hill Вы можете получить эту ошибку с типом, допускающим значение NULL. Попробуйте yourNumber.Value.ToString (0. ##), чтобы решить вашу проблему.

Anh Hoang 05.04.2018 11:37

Приведенное ниже решение лучше, поскольку оно рассматривает его как десятичное и возвращает десятичное.

Mocas 23.01.2019 18:29

Если вам это просто нужно для отображения, используйте 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" это двойное

Adam Tegen 30.11.2009 23:41

или ярлык $ "{value: 0.00}"

mamczas 21.11.2018 02:02

Метод Math.Round (Decimal, Int32)

это не использует банковское округление?

Danimal 03.10.2008 03:15

Это лучший способ, потому что значение не преобразуется в строку, и вы по-прежнему можете выполнять математические операции.

shinji14 21.06.2010 21:29

@Danimal: вы можете указать третий аргумент, чтобы изменить тип округления

Jay Sullivan 29.07.2013 17:16

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

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

@ Slick86 - знак валюты

fubo 29.05.2015 11:31

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

decimalVar.ToString("n2");

Лучший ответ, так как вопрос касался вывода на страницу, а форматирование чисел важно для больших чисел. Кроме того, «n *» учитывает текущий язык и региональные параметры, поэтому это может быть «3.456.789,12», «3 456 789,12» и т. д.

Shautieh 21.08.2014 19:48

decimalVar.ToString("F");

Это будет:

  • Округлить до 2 знаков после запятой например.23.45623.46
  • Убедитесь, что там всегда 2 десятичных разряда например.2323.00; 12.512.50

Идеально подходит для отображения валюты.

Ознакомьтесь с документацией по ToString ("F") (спасибо Джону Шнайдеру).

Это отлично работает, когда есть только 1 десятичный знак; .ToString ("#. ##") не работает. Этот ответ намного лучше

Eric Frick 21.03.2013 22:25

Разве не было бы 23,456 => 23,46?

rtpHarry 31.05.2013 17:07

Документация о том, что здесь означает буква "F" и как это работает: msdn.microsoft.com/en-us/library/…

Jon Schneider 25.06.2014 19:06

Почему бы не .ToString («N») вместо «F»? Насколько я понимаю, они оба будут работать для нужд этого вопроса, но N также будет ставить запятые для чисел в тысячах.

jgerman 29.09.2014 20:30

Примечание. . может быть заменен на , в зависимости от культуры. Вы должны передать CultureInfo.InvariantCulture в качестве второго аргумента, чтобы отключить это.

Duncan Luk 12.02.2019 18:04

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

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

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

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

Matthijs Wessels 21.03.2013 06:36

@MatthijsWessels Я знаю ... но он также не сохраняет значение в виде десятичной дроби.

Mike M. 29.03.2013 05:26

Это лучший способ по-настоящему представить два десятичных знака, поскольку при этом не будут отбрасываться нули в конце.

LiquidDrummer 22.04.2016 22:15

Вы можете использовать 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 будет использовать запятую вместо точки. Это не связано с количеством отображаемых десятичных знаков.

MattDavey 11.01.2012 13:17

У 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 10.01.2012 21:16

MattDavey неверен, добавлена ​​десятичная точность. (1,0 м * 1,00 м) .ToString () = "1.000"

Kaido 25.10.2012 18:27

Очень, очень полезно знать, что «десятичное число« знает », сколько десятичных знаков оно имеет, в зависимости от того, откуда оно взялось». Большое спасибо!

iheartcsharp 08.07.2013 22:07

ценю ваш ответ и объяснение!

sspaniel 28.01.2021 17:23

Ни один из них не сделал именно то, что мне нужно, чтобы заставить 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" означает цифру числа (не важно, что) (с нулями, если недоступно)

Mr Heelis 19.01.2018 17:09

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

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

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

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