在 C# 中,我应该使用什么数据类型来表示货币金额?十进制?漂浮?双倍的?我想考虑:精度、舍入等。
System.Decimal
:
Decimal值类型代表 从正数到十进制数 79,228,162,514,264,337,593,543,950,335 至负数 79,228,162,514,264,337,593,543,950,335。 Decimal值类型合适 对于财务计算需要 大量有效积分 和小数位且不四舍五入 错误。 Decimal 类型不 消除舍入的需要。 相反,它最大限度地减少了由于 四舍五入。
System.Single
(float
) 和 System.Double
(double
) 都如果您使用 SQL,请在数据库中使用小数和货币。
在 C# 中,Decimal 类型实际上是一个具有重载函数的结构体,用于以 10 为基数的所有数学和比较运算,因此它的舍入误差较小。 另一方面,浮点(和双精度)类似于二进制的科学记数法。 因此,当您知道所需的精度时,小数类型会更准确。
运行此命令以查看 2 的准确度差异:
using System;
using System.Collections.Generic;
using System.Text;
namespace FloatVsDecimal
{
class Program
{
static void Main(string[] args)
{
Decimal _decimal = 1.0m;
float _float = 1.0f;
for (int _i = 0; _i < 5; _i++)
{
Console.WriteLine("float: {0}, decimal: {1}",
_float.ToString("e10"),
_decimal.ToString("e10"));
_decimal += 0.1m;
_float += 0.1f;
}
Console.ReadKey();
}
}
}
十进制就是你想要的。
考虑使用CLR 的货币类型。 它是一种自定义值类型(结构),还支持货币并处理舍入问题。
在 C# 中,您应该采用“Decimal”来表示货币金额。
对于一些快速而肮脏的事情,任何浮点基元类型都可以。
float
和double
的问题在于它们都不能准确地表示1/10,有时会导致令人惊讶的万亿分之一美分。您可能听说过臭名昭著的 10 美分 + 20 美分。更现实的是,尝试计算每件税前价值 39.99 美元的三件商品的 6% 销售税。
此外,
float
和double
具有诸如负无穷大和NaN之类的值,这些值对于表示金钱没有任何用处。所以可以精确表示 1/10 的 decimal
似乎是最好的选择。
但是,
decimal
不包含有关我们正在处理的货币的任何信息。例如,金额 29.89 美元等于 29.89 欧元吗? 29.89 美元 > 29.89 欧元吗?如何确保这些金额以正确的货币符号显示?
如果这些细节对您的程序很重要,那么您应该使用第三方库或创建您自己的
CurrencyAmount
类(或任何您想要的名称)。
但是如果这类事情对程序来说并不重要,你可以只使用浮点类型。或者甚至可能是整数(例如,我在 Java 中的二十一点实现要求玩家输入整美元的赌注)。
存储货币的最有效方式是将其最小单位作为整数,例如
int
(最多 2,147,483,647)或 long
(最多 9,223,372,036,854,775,807)。
因此,如果您存储美元,一个整数最多可以存储 21,474,836.47 美元,而对于日元,一个整数最多可以存储 2,147,483,647 日元(因为该货币存储 0 位小数)。
然后在运行时您可以将它们转换为正确的格式以显示给用户,并且您需要考虑每种货币存储多少位小数。处理小数时的正确格式是始终显示小数,因此它会显示“$4.99”、“$7.50”和“$1.00”,而不删除零小数。