为什么有些文化默认将货币小数点四舍五入?

Why some cultures round currency decimals by default?

我注意到,在使用框架函数 string.Format 格式化货币值时,在某些文化中,此函数默认四舍五入小数。例如,使用马来西亚林吉特时:

CultureInfo culture = new CultureInfo("ms-MY");
someLabel.Content = string.Format(culture,"{0:C}", 1.64m);

Outputs: RM2

然而,当使用其他货币(如美元、欧元或其他货币)时,您会得到原始值,例如:

CultureInfo culture = new CultureInfo("sv-SE");
someLabel.Content = string.Format(culture,"{0:C}", 1.64m);

Outputs: 1.64kr

我知道我可以在 CultureInfo class 中指定小数位数,但问题是,为什么某些货币会出现这种情况而其他货币不会出现这种情况?预计部分货币默认四舍五入?

来自The Currency "C" Format Specifier

If the precision specifier is omitted, the default precision is defined by the CurrencyDecimalDigits property.

并且这种 ms-MY 文化有 0 作为 CurrencyDecimalDigits 属性。这就是结果中没有任何小数位的原因。

作为解决方案,您可以使用精度说明符作为;

CultureInfo culture = new CultureInfo("ms-MY");
someLabel.Content = string.Format(culture,"{0:C2}", 1.64m); // RM1.64

Why some currencies are rounded (or they have this property set to 0, if you prefer), but not others. Is there some rule for that?

老实说,我不知道。但我做了一些研究,这里是我的发现;

马来西亚使用ringgit as a currency. It is divided into 100 sen. And with it's third series,只有4枚硬币; 5 仙、10 仙、20 仙、50 仙

previous (second) series;

As of 1 April 2008, a rounding mechanism of prices to the nearest 5 sen, applied to the total bill only, is in force, which was first announced in 2007 by Bank Negara Malaysia, in an attempt to render the 1 sen coin irrelevant.

文章:http://www.thestar.com.my/story/?file=%2f2007%2f11%2f14%2fnation%2f19460993&sec=nation&focus=1

这张图片很有用,告诉你不能将 RM 除以 100,因为它没有意义。顺便说一句,这个0值和ISO 4217 which specifies currency designators. From Active Codes section不匹配,你可以看到这个MYR在这个标准中有2个十进制数字。

这个XML file from currency-iso.org也是这么说的;

<CcyNtry>
  <CtryNm>MALAYSIA</CtryNm>
  <CcyNm>Malaysian Ringgit</CcyNm>
  <Ccy>MYR</Ccy>
  <CcyNbr>458</CcyNbr>
  <CcyMnrUnts>2</CcyMnrUnts>
</CcyNtry>

也来自非十进制货币页面的 Contemporary non-decimal currencies 部分;

Today only two countries in the world use non-decimal currencies. Both are in Africa. These are Mauritania (1 ouguiya = 5 khoums) and Madagascar (1 ariary = 5 iraimbilanja). However these are only theoretically non-decimal, as in both cases the value of the main unit is so low that the sub-unit is too small to be of any practical use and coins of the sub-unit are no longer used

顺便看看这个页面的其他部分,里面有很多有用的信息。

我认为这有点复杂。我也连接到 .NET 团队。当我收到他们的反馈时,我会更新这个答案。

2015 年 8 月 18 日更新

作为 Tarek ,此 my-MY 文化的 CurrencyDecimalDigits 属性 在 Windows 10.[=42] 中更改为 2 =]

Shawn Steele(Windows和.NET Framework全球化API专家)建议为;

Probably formatting currencies using Windows.Globalization and doing it by currency might be a better idea.

更新 21/02/2016

看起来这种情况再次发生在 Windows Server 2012 R2 上。我就此联系了 .NET 团队,他们回应说我们可以使用 Locale Builder to create a new custom culture or edit an existing culture to change this ICURRDIGITS 设置作为 2

小数位数由NumberFormatInfo.CurrencyDecimalDigits(https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.currencydecimaldigits(v=vs.110).aspx)

控制

ms-MY 文化中,此 CurrencyDecimalDigits 默认为零,这会导致数字四舍五入。 在其他文化中,如 sv-SECurrencyDecimalDigits2,显示 1,64

您可以通过指定 {0:C2} 来控制它,或者您可以更改 NumberFormatInfo 上的值,例如:

CultureInfo culture = new CultureInfo("ms-MY");
NumberFormatInfo nfi = (NumberFormatInfo)culture.NumberFormat.Clone();
nfi.CurrencyDecimalDigits = 2;
content = string.Format(nfi, "{0:C}", 1.64m);

如果您认为 ms-MYCurrencyDecimalDigits 不应该为零,我们可以将此反馈传递给 Windows 团队,因为他们控制 Windows 上的文化数据。

谢谢