Decimal vs. Double 对于只存储,不操纵的小货币数字
Decimal vs. Double for small currency numbers that only get stored, not manipulated
我正在编写一个小型应用程序,它访问 SQL 数据库以检索有关某些本地事件的信息,包括它们的价格,并允许创建和编辑新事件以及导出格式化和过滤的事件列表打印等事件
现在一个活动可能有入场费,该费用也显示在数据集中(MS SQL 服务器数据类型 "money"),但我想知道在我的数据集中使用哪种数据类型客户端应用程序。
我知道您应该始终使用十进制进行货币计算,因为它的精度很高 - 但我不会进行 任何 计算,它只会作为数字输入有两位小数并存储到数据库中,稍后它会再次加载并显示或导出到可打印文档中 - 没有可能累积不准确的计算。
那么在这种情况下您会使用哪种数据类型?仍然选择 Decimal 只是因为它是金钱而不关心内存等?或者使用 Double 代替,因为它足够精确?或者,我也可以将美分价格存储为整数。我应该选择哪种类型?
只需使用 Decimal(x+2,2)
其中 x 是您要存储的整数位
CREATE TABLE dbo.MyTable
(
MyDecimalColumn decimal(5,2)
....
);
public class MyTableObject{
public decimal MyDecimalColumn {get;set;}
}
欢迎来到地狱。可悲的是,C#(或者更确切地说.NET)没有实现不实现 IEEE 754 2008 十进制浮点规范。
在您的情况下,我建议使用浮点数或双精度数 - 浮点数对于小货币数字可能足够好,如果分辨率不够好,请使用双精度数。
确保每个输出的输出格式都具有准确的位数 "possible",因为某些数字很可能是近似值(例如 1.1 没有精确表示)。如果没有好的格式字符串,您可能会得到有趣的打印结果。
Alternatively I could probably store the price in Cents as Integer as well.
这行得通 - 但显然需要对每个输出进行有趣的尝试。当你只做演示时,这是非常可行的。恕我直言,这也是非常不需要的。
一般在处理已有的数据源时,按照已经使用的就可以了。在这种情况下,SQL Server .NET reader 映射 money to decimal。这意味着没有尴尬的转换,也没有传输中的浪费。
TomTom 在其评论中的回答指出,double 可以以可接受的精度获得您所需的性能,但除非您要处理数百万次计算或存储不足,否则没有理由不对财务数据使用 decimal。
在SQL中使用DECIMAL
,经常在数据库内部存储一个int,但是逗号点在打印前通过第二个参数左移。所以DECIMAL(5,2)
表示它总共可以存储5位数字,其中2位会在逗号后面。
使用货币时,最好使用十进制数据类型或以美分执行所有计算和存储。
如果您只想存储它们然后将它们打印为文本,那么 float 或 double 就足够了(哪个取决于您需要的总位数,而不仅仅是小数位)。如果您最多需要 6 位数字,则浮点数即可;如果您最多需要 15 位数字,则需要加倍。 (这来自 "theory of round-tripping",我经常在我的网站上讨论它,例如 http://www.exploringbinary.com/number-of-digits-required-for-round-trip-conversions/)。
注意:双向转换(到浮点数,到文本)必须正确完成。例如,它们在 SQLite 中没有(或者至少六年前没有)正确完成。 (我没有研究过 MS SQL 服务器。)仅这一点就可能会吓到你重新使用 Decimal。
由于您只存储价格值并稍后显示,因此您可以只使用一个字符串。这样存储和读取的转换成本为零。对于像这样的小值,它可能使用比 Decimal 更少的内存。有时您需要根据语言环境在 ,
和 .
之间进行转换,但对于本地事件来说可能并不重要
下一个最佳选择是将分值存储为整数
我正在编写一个小型应用程序,它访问 SQL 数据库以检索有关某些本地事件的信息,包括它们的价格,并允许创建和编辑新事件以及导出格式化和过滤的事件列表打印等事件
现在一个活动可能有入场费,该费用也显示在数据集中(MS SQL 服务器数据类型 "money"),但我想知道在我的数据集中使用哪种数据类型客户端应用程序。
我知道您应该始终使用十进制进行货币计算,因为它的精度很高 - 但我不会进行 任何 计算,它只会作为数字输入有两位小数并存储到数据库中,稍后它会再次加载并显示或导出到可打印文档中 - 没有可能累积不准确的计算。
那么在这种情况下您会使用哪种数据类型?仍然选择 Decimal 只是因为它是金钱而不关心内存等?或者使用 Double 代替,因为它足够精确?或者,我也可以将美分价格存储为整数。我应该选择哪种类型?
只需使用 Decimal(x+2,2)
其中 x 是您要存储的整数位
CREATE TABLE dbo.MyTable
(
MyDecimalColumn decimal(5,2)
....
);
public class MyTableObject{
public decimal MyDecimalColumn {get;set;}
}
欢迎来到地狱。可悲的是,C#(或者更确切地说.NET)没有实现不实现 IEEE 754 2008 十进制浮点规范。
在您的情况下,我建议使用浮点数或双精度数 - 浮点数对于小货币数字可能足够好,如果分辨率不够好,请使用双精度数。
确保每个输出的输出格式都具有准确的位数 "possible",因为某些数字很可能是近似值(例如 1.1 没有精确表示)。如果没有好的格式字符串,您可能会得到有趣的打印结果。
Alternatively I could probably store the price in Cents as Integer as well.
这行得通 - 但显然需要对每个输出进行有趣的尝试。当你只做演示时,这是非常可行的。恕我直言,这也是非常不需要的。
一般在处理已有的数据源时,按照已经使用的就可以了。在这种情况下,SQL Server .NET reader 映射 money to decimal。这意味着没有尴尬的转换,也没有传输中的浪费。
TomTom 在其评论中的回答指出,double 可以以可接受的精度获得您所需的性能,但除非您要处理数百万次计算或存储不足,否则没有理由不对财务数据使用 decimal。
在SQL中使用DECIMAL
,经常在数据库内部存储一个int,但是逗号点在打印前通过第二个参数左移。所以DECIMAL(5,2)
表示它总共可以存储5位数字,其中2位会在逗号后面。
使用货币时,最好使用十进制数据类型或以美分执行所有计算和存储。
如果您只想存储它们然后将它们打印为文本,那么 float 或 double 就足够了(哪个取决于您需要的总位数,而不仅仅是小数位)。如果您最多需要 6 位数字,则浮点数即可;如果您最多需要 15 位数字,则需要加倍。 (这来自 "theory of round-tripping",我经常在我的网站上讨论它,例如 http://www.exploringbinary.com/number-of-digits-required-for-round-trip-conversions/)。
注意:双向转换(到浮点数,到文本)必须正确完成。例如,它们在 SQLite 中没有(或者至少六年前没有)正确完成。 (我没有研究过 MS SQL 服务器。)仅这一点就可能会吓到你重新使用 Decimal。
由于您只存储价格值并稍后显示,因此您可以只使用一个字符串。这样存储和读取的转换成本为零。对于像这样的小值,它可能使用比 Decimal 更少的内存。有时您需要根据语言环境在 ,
和 .
之间进行转换,但对于本地事件来说可能并不重要
下一个最佳选择是将分值存储为整数