如何将十进制值四舍五入到小数点后两位(用于在页面上输出)


648

当当前显示带有的十进制值时.ToString(),它精确到15个小数位,并且由于我使用它来表示美元和美分,所以我只希望输出为2个小数位。

.ToString()为此使用变体吗?

Answers:


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

要么

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

31
问题是当我们有0.00时;它返回一个空字符串。
Jronny

164
然后,您可以执行decimalVar.ToString(“ 0。##”)。您也可以使用0.00作为格式字符串。
albertein 2010年

54
使用此解决方案,您将不会具有阅读数字时所期望的区域性格式。为此,您应该使用ToString(“ N2”)或ToString(“ N”)。
Shautieh 2014年

2
@Hill DecimalDoubletype ToString方法接受用于格式化的参数。首先尝试将您的值转换为十进制/双精度。
sohaiby

1
@ f470071小数是值类型,因此永不“修改”。无论如何,从未期望ToString()会修改其调用内容。
贾斯汀·斯基尔斯

589

我知道这是一个古老的问题,但是我很惊讶地看到没有人发布这个答案。

  1. 没有使用银行家四舍五入
  2. 没有将值保留为小数。

这就是我要使用的:

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

http://msdn.microsoft.com/zh-CN/library/9s0xa85y.aspx


3
ToString或string.Format不要使用银行取整:msdn.microsoft.com/zh-cn/library/0c899ak8.aspx#sectionToggle1
Matthijs Wessels 2013年

1
我知道@MatthijsWessels ...但它也不会将值保留为小数。
Mike M.

1
这是真正表示两个小数位的更好方法,因为它不会丢失尾随零。
LiquidDrummer

354
decimalVar.ToString("F");

这将:

  • 四舍五入到小数点后两位 23.45623.46
  • 确保始终有2个小数位,例如。 2323.00; 12.512.50

显示货币的理想选择。

查看有关ToString(“ F”)的文档(感谢Jon Schneider)。


10
只有十进制小数时,这可以正常工作;.ToString(“#。##”)失败。这个答案要好得多
Eric Frick

2
23.456 => 23.46不会吗?
rtpHarry

14
有关“ F”在这里的含义及其工作方式的文档:msdn.microsoft.com/zh-cn/library/…–
Jon Schneider

4
为什么不使用.ToString(“ N”)而不是“ F”?我的理解是,它们都可以满足这个问题的需要,但是N也会为成千上万的数字添加逗号。
jgerman 2014年

注意:.可以,根据区域性替换为。您应该将其CultureInfo.InvariantCulture作为第二个参数来禁用它。
邓肯·卢克


56

给定十进制d = 12.345; 表达式d.ToString(“ C”)String.Format(“ {0:C}”,d)得出$ 12.35注意,使用了当前区域性的货币设置(包括符号)。

请注意,“ C”使用当前区域性的位数。您可以随时覆盖默认强制必要的精度与C{Precision specifier}喜欢String.Format("{0:C2}", 5.123d)


4
@ Slick86-当前标志
fubo 2015年

48

如果要使用逗号和小数点(但没有货币符号)格式化,例如3,456,789.12 ...

decimalVar.ToString("n2");

1
更好的答案,因为问题是关于在页面上输出,数字格式对于大数字很重要。另外,“ n *”考虑了当前的文化,因此可能是“ 3.456.789,12”,“ 3 456 789,12”等
。– Shautieh 2014年

29

已经有两个涉及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的Web服务时,我需要一个十进制的AS。该服务正在抱怨,因为正以十进制值(最初是从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


5
+1这是一个很好的答案。当您说System.Decimal“知道有多少小数位”时,该术语是System.Decimal不会像其他浮点类型那样进行自规范化。System.Decimal的另一个有用的属性是,数学运算的结果始终具有输入参数ie最高的小数位数。1.0m + 2.000m = 3.000m。您可以使用这一事实,只需将1.00m乘以一个无小数位的小数即可将其保留为2个小数位。10m * 1.00m = 10.00m
MattDavey 2012年

2
MattDavey的不正确,已添加了十进制精度。(1.0m * 1.00m).ToString()=“ 1.000”
2012年

2
知道“一个十进制的“根据其来源知道多少个小数位”是非常有用的。非常感谢!
iheartcsharp

21

这是一个小的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
===================


11

如果值为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分钟的时间。


1
基本上 "#"是指数字的位数(如有必要)(如果不需要,则无需填充)"0"是指数字的位数(无内容)(如果没有可用,则用零填充)
Heelis先生,

10

Mike M.的答案对.NET非常适合我,但decimal.Round在撰写本文时,.NET Core没有任何方法。

在.NET Core中,我必须使用:

decimal roundedValue = Math.Round(rawNumber, 2, MidpointRounding.AwayFromZero);

一种hacky方法,包括转换为字符串,是:

public string FormatTo2Dp(decimal myNumber)
{
    // Use schoolboy rounding, not bankers.
    myNumber = Math.Round(myNumber, 2, MidpointRounding.AwayFromZero);

    return string.Format("{0:0.00}", myNumber);
}

9

这些都不符合我的要求,强制2 dp并四舍五入为0.005 -> 0.01

强制2 dp需要将精度提高2 dp,以确保我们至少有2 dp

然后四舍五入以确保我们不超过2 dp

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

6.665m.ToString() -> "6.67"

6.6m.ToString() -> "6.60"

9

评分最高的答案描述了一种格式化十进制值的字符串表示形式的方法,该方法有效。

但是,如果您实际上想将保存的精度更改为实际值,则需要编写如下内容:

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

7

您可以使用system.globalization将数字格式化为任何所需格式。

例如:

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

如果您有a decimal d = 1.2300000且需要将其修剪到2个小数位,则可以像这样打印它d.Tostring("F2",ci);,其中F2是将字符串格式格式化为2个小数位,而ci是语言环境或cultureinfo。

有关更多信息,请检查此链接
http://msdn.microsoft.com/zh-cn/library/dwhawy9k.aspx


+1,但-CultureInfo对象将只影响用于表示小数位的Unicode字符。例如。fr-FR将使用逗号而不是句点。它与呈现的小数位数无关。
MattDavey 2012年



1

如果只需要保留小数点后两位(即,舍去所有其余的十进制数字):

decimal val = 3.14789m;
decimal result = Math.Floor(val * 100) / 100; // result = 3.14

如果只需要保留小数点后三位:

decimal val = 3.14789m;
decimal result = Math.Floor(val * 1000) / 1000; // result = 3.147
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.