【发布时间】:2010-09-14 23:05:30
【问题描述】:
当前使用.ToString() 显示小数的值时,精确到小数点后 15 位,因为我用它来表示美元和美分,所以我只希望输出为小数点后 2 位。
我是否为此使用.ToString() 的变体?
【问题讨论】:
-
Here 是格式化浮点值(对齐方式、位数、组分隔符、指数、百分比、货币等)的不同选项的简要示例。
当前使用.ToString() 显示小数的值时,精确到小数点后 15 位,因为我用它来表示美元和美分,所以我只希望输出为小数点后 2 位。
我是否为此使用.ToString() 的变体?
【问题讨论】:
decimalVar.ToString("#.##"); // returns ".5" when decimalVar == 0.5m
或
decimalVar.ToString("0.##"); // returns "0.5" when decimalVar == 0.5m
或
decimalVar.ToString("0.00"); // returns "0.50" when decimalVar == 0.5m
【讨论】:
Decimal 和 Double 类型 ToString 方法接受格式化参数。尝试先将您的值转换为十进制/双精度。
我知道这是一个老问题,但我很惊讶地发现似乎没有人发布这个答案;
这是我会使用的:
decimal.Round(yourValue, 2, MidpointRounding.AwayFromZero);
【讨论】:
decimalVar.ToString("F");
这将:
23.456 → 23.46
23 → 23.00; 12.5 → 12.50
非常适合显示货币。
查看ToString("F") 上的文档(感谢 Jon Schneider)。
【讨论】:
. 可能会根据文化替换为 ,。您应该传递 CultureInfo.InvariantCulture 作为第二个参数来禁用它。
如果你只需要这个来显示使用 string.Format
String.Format("{0:0.00}", 123.4567m); // "123.46"
http://www.csharp-examples.net/string-format-double/
“m”是十进制后缀。关于小数后缀:
【讨论】:
给定 decimal 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 有一个非常重要的特性并不明显:
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% 的情况下可能都可以:
Decimal.Parse("25.0").ToString("c") => "$25.00"
或者在 XAML 中你会使用 {Binding Price, StringFormat=c}
在将 XML 发送到 Amazon 的网络服务时,我遇到了一个需要小数的情况,因为小数是小数。该服务正在抱怨,因为 Decimal 值(最初来自 SQL Server)被发送为 25.1200 并被拒绝,(25.12 是预期的格式)。
我需要做的只是Decimal.Round(...) 有 2 位小数来解决问题,无论值的来源如何。
// 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 分钟时间。
【讨论】:
"#" 表示数字的位数(如果需要)(如果不需要则不填充)"0" 表示数字的位数(无论如何)(如果不可用,用零填充)
Mike M.'s answer 在 .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);
}
【讨论】:
这些都没有完全满足我的需要,强制 2 d.p. 并四舍五入为0.005 -> 0.01
强制 2 d.p.需要将精度提高 2 d.p.确保我们至少有 2 个 d.p.
然后四舍五入以确保我们的 d.p. 不超过 2
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 是语言环境或文化信息。
欲了解更多信息,请查看此链接
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx
【讨论】:
https://msdn.microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx
此链接详细说明了如何处理您的问题以及如果您想了解更多信息可以采取哪些措施。为简单起见,您要做的是
double whateverYouWantToChange = whateverYouWantToChange.ToString("F2");
如果您想将其用于货币,您可以通过键入“C2”而不是“F2”来简化操作
【讨论】:
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
【讨论】:
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。
【讨论】: