当前位置:  开发笔记 > 编程语言 > 正文

使用Float或Decimal作为会计应用程序的美元金额?

如何解决《使用Float或Decimal作为会计应用程序的美元金额?》经验,为你挑选了9个好方法。

我们正在用VB.NET和SQL Server重写我们的旧会计系统.我们引入了一个新的.NET/SQL程序员团队来进行重写.大多数系统已经使用Floats完成了Dollar数量.我编程的遗留系统语言没有Float,所以我可能会使用Decimal.

你有什么建议?

Float或Decimal数据类型应该用于美元金额吗?

两者的优点和缺点有哪些?

在我们的日常scrum中提到的一个骗局是,当你计算一个返回超过两个小数位的结果的金额时,你必须要小心.听起来你必须将金额四舍五入到小数点后两位.

另一个Con是所有显示和打印金额必须有一个显示两个小数位的格式声明.我注意到有几次没有这样做,金额看起来不正确.(即10.2或10.2546)

专家是Float只占用磁盘上的8个字节,其中Decimal占用9个字节(十进制12,2)



1> 小智..:

Float或Decimal数据类型应该用于美元金额吗?

答案很简单.永远不要漂浮.永远不会!

浮点数是根据IEEE 754始终二进制,只有新标准IEEE 754R定义的十进制格式.许多小数二进制部分永远不能等于精确的十进制表示.
任何二进制数都可以写成m/2^n(m,n正整数),任何十进制数m/(2^n*5^n).
由于二进制文件缺少素数factor 5,所有二进制数可以用小数精确表示,但反之亦然.

0.3 = 3/(2^1 * 5^1) = 0.3

0.3 = [0.25/0.5] [0.25/0.375] [0.25/3.125] [0.2825/3.125]

          1/4         1/8         1/16          1/32

因此,您最终会得到一个高于或低于给定十进制数的数字.总是.

为什么这么重要?四舍五入.
正常舍入表示0..4向下,5..9向上.因此,它确实重要,如果结果为0.049999999999....或者0.0500000000......你可能知道,这意味着5%,但对计算机不知道和轮0.4999...向下(错)和0.5000...起来(右).
鉴于浮点计算的结果总是包含小的错误项,因此决定是纯粹的运气.如果你想要使用二进制数进行十进制舍入到偶数处理,那就无望了.

不相信?你坚持认为在你的帐户系统中一切都很好吗?
资产和负债相等?好的,然后获取每个条目的每个给定格式化的数字,解析它们并用独立的十进制系统求和它们!将其与格式化的总和进行比较.
糟糕,有些不对劲,不是吗?

对于那个计算,需要极高的准确性和保真度(我们使用Oracle的FLOAT),因此我们可以记录得到的"十分之一便士".

无助于解决此错误.因为所有人都自动认为计算机总和正确,所以几乎没有人独立检查.


对于那些不确定Keith意味着什么的人,Decimal类型使用不同类型的舍入.它似乎通常被称为"银行家四舍五入",但维基百科有许多替代名称:圆半到均匀,无偏舍入,收敛舍入,统计学舍入,荷兰舍入,高斯舍入或银行家舍入(http:// en .wikipedia.org /维基/四舍五入#Rounding_to_a_specified_increment).
要记住的另一件事是Decimal.Round和String.Format给出不同的结果:Decimal.Round(0.045M,2)= 0.04和String.Format("{0:0.00}",0.045M)= 0.05

2> Nakilon..:

这张照片答案:

照片1,CO

这是另一种情况:来自北安普顿的人得到一封信,说如果他没有支付零美元和零美分就会被扣押!

照片2,CO


我每个月都会从一家电话公司拿到0.01美元的账单.所以我在网上支付了0.02美元,然后在六个月内收到了0.01美元的账单,然后停了下来.
这让我发笑.方式去,百思买.

3> Rich Schuler..:

首先,您应该阅读每个计算机科学家应该知道的关于浮点运算的内容.那么你应该考虑使用某种类型的定点/任意精度数字包(例如java BigNum,python十进制模块),否则你将陷入一个受伤的世界.然后弄清楚是否使用本机SQL十进制类型就足够了.

浮点/双打存在(ed)以暴露快速x87 fp,现在已经过时了.如果您关心计算的准确性和/或不完全补偿其限制,请不要使用它们.



4> Darrel Mille..:

正如另一个警告,SQL Server和.Net框架使用不同的默认算法进行舍入.请务必查看Math.Round()中的MidPointRounding参数..Net框架默认使用Bankers算法,SQL Server使用Symmetric Algorithmic Rounding.在这里查看维基百科的文章



5> 小智..:

问问你的会计师!他们会对你使用漂浮物皱眉.就像之前发布的一些,如果您不关心准确性,请仅使用float.虽然在谈到金钱时我总是反对它.

在会计软件中不可接受浮动.使用带小数点后4位的小数.



6> Keith..:

浮点有意想不到的无理数.

例如,你不能存储1/3作为小数,它将是0.3333333333 ......(依此类推)

浮点数实际上存储为二进制值和2指数幂.

所以1.5被存储为3 x 2到-1(或3/2)

使用这些base-2指数会创建一些奇怪的无理数,例如:

将1.1转换为浮点数然后再将其转换回来,结果如下:1.0999999999989

这是因为1.1的二进制表示实际上是154811237190861 x 2 ^ -47,超过双倍可以处理.

更多关于我的博客上的这个问题,但基本上,对于存储,你最好用小数.

在Microsoft SQL服务器上,您具有money数据类型 - 这通常最适合财务存储.精确到4位小数.

对于计算,你有更多的问题 - 不准确性是一小部分,但把它放入一个幂函数,它很快就会变得很重要.

但是小数对于任何类型的数学都不是很好 - 例如,没有对十进制幂的原生支持.


"无理性"不是你要找的词.1/3仍然是合理的,但它没有有限的二进制表示......

7> Mitch Wheat..:

使用SQL Server的十进制类型.

不要用漂浮.

money使用4位小数,比使用decimal更快但是有一些明显的和一些不那么明显的舍入问题(见这个连接问题)



8> Joshua..:

我推荐的是使用64位整数来存储整个东西.



9> David Thornl..:

这里有点背景......

没有数字系统可以准确处理所有实数.所有这些都有其局限性,这包括标准IEEE浮点和带符号小数.每个位使用的IEEE浮点更准确,但这并不重要.

财务数据基于几个世纪的纸笔练习以及相关的惯例.它们相当准确,但更重要的是,它们是可重复的.使用各种数字和费率的两名会计师应该提出相同的数字.任何差异的余地都是欺诈的余地.

因此,对于财务计算,正确答案是与擅长算术的注册会计师给出相同答案的答案.这是十进制算术,而不是IEEE浮点.

推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有