当显示当前小数的值时.ToString()
,它精确到15个小数位,并且由于我用它来表示美元和美分,我只希望输出为2位小数.
我是否使用此变体.ToString()
?
decimalVar.ToString ("#.##"); // returns "" when decimalVar == 0
要么
decimalVar.ToString ("0.##"); // returns "0" when decimalVar == 0
我知道这是一个古老的问题,但我很惊讶地看到似乎没有人发布一个答案;
没有使用银行家四舍五入
没有将值保留为小数.
这是我会用的:
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#FFormatString(感谢Jon Schneider)
如果你只是需要这个用于显示使用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
给定小数d = 12.345; 表达式d.ToString("C")或String.Format("{0:C}",d)产生$ 12.35 - 请注意使用当前文化的货币设置,包括符号.
请注意,"C"使用当前文化中的位数.您始终可以覆盖默认值以强制使用C{Precision specifier}
类似的必要精度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"
为上述每个操作提供小数位().
当你想要一个十进制到2位小数时,大概有95%的可能性,因为它是货币,在这种情况下,95%的情况下这可能是好的:
Decimal.Parse("25.0").ToString("c") => "$25.00"
或者在XAML中你只是使用 {Binding Price, StringFormat=c}
我遇到一个案例,我需要一个十进制AS小数,这是在向亚马逊的Web服务发送XML时.该服务抱怨,因为Decimal值(最初来自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: $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 ===================
Math.Round方法(十进制,Int32)
如果值为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分钟(大多数)人的时间.
这些都不是我所需要的,强迫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"
评价最高的答案描述了一种格式化十进制值的字符串表示的方法,并且它可以工作.
但是,如果您确实要将保存的精度更改为实际值,则需要编写如下内容:
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");
如果你有一个decimal d = 1.2300000
,你需要将其修剪为2位小数,那么它可以像这样打印d.Tostring("F2",ci);
,其中F2是字符串格式化为2位小数,ci是locale或cultureinfo.
有关更多信息,请查看此链接
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx
Mike M.的答案对我来说非常适合.NET,但.NET Core decimal.Round
在撰写本文时没有一种方法.
在.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); }