向客户解释浮点舍入问题的最佳方法是什么?
我知道
http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html
以及针对开发人员和科学家的C ++ FAQ和其他各种页面中的条目,但是是否有针对具有有限数学或科学背景的“常规”客户的网页,文章或说明?(以上参考文献对此持平)。
如果它是维护的或来自知名的和公认的机构或公司,那么情况就更好了,因为正如您中某些人可能曾经经历过的那样,要解释自己可能有些复杂。
向客户解释浮点舍入问题的最佳方法是什么?
我知道
http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html
以及针对开发人员和科学家的C ++ FAQ和其他各种页面中的条目,但是是否有针对具有有限数学或科学背景的“常规”客户的网页,文章或说明?(以上参考文献对此持平)。
如果它是维护的或来自知名的和公认的机构或公司,那么情况就更好了,因为正如您中某些人可能曾经经历过的那样,要解释自己可能有些复杂。
Answers:
我找到一种简单的方法来解释这一点,以证明这一点。讨论如何将x
数字除以 然后再乘以相同的数字将使您x
再次返回-让客户同意这种情况总是如此。然后(100 / 3) * 3
用计算器做旧的事;表明该值不会像您期望的那样返回到100。当大多数人看到显然简单的数学“分解”时,则趋向于“冒”在精度很重要的地方浮点数的危险(尽管在直观上方式,而不是将您指向的文章介绍到较低的层次)。
不幸的是,如今大多数半体面的计算器(肯定是我所见过的所有科学计算器,并且超过了一些基本的计算器)都能够处理这个问题-我想他们正在存储超出显示和舍入范围之外的多余数字-这样做在您面对客户之前,请先检查您的计算器有多聪明。
我认为没有捷径可走。您必须:
或者,如果这太过需要,您只需要:
也许与无理数的例子帮助(即使浮点问题也适用于有理数和)sqrt(2) ~ 1.414
。然后1.414^2 = 1.999396
。无论您使用多少位数字,都永远不会回到原始数字上2
。好的,正确的4位有效数字是可以接受的,但是请考虑当这种“舍入误差”累积时会发生什么。那才是真正的危险所在。
首先,确定他们在抱怨什么。必须使用正确的小数位数和正确的舍入规则精确地进行金融交易。这通常意味着维护货币单位的整数,并确保算法正确完成。
另外,他们可能抱怨显示过于精确,因此减少所有有效数字的输出可能是必要的。
对于一般的数字,您总是可以尝试使用三位数的十进制x来表示x * 3为10。这显示了基本原理。
剩下两个问题。一种是某些数字可以精确地用十进制表示,而不能用二进制表示(例如3.15)。这将很难向非技术人员解释,您最好的选择是尝试通过不提供足够多的有效数字来显示它来避免这种情况。另一个是了解一点的客户,足以知道计算机算术并不总是精确的,也不足以认识到十进制算术并不总是精确的。我已经与其中一些争论,没有什么可报告的。
计算机中的浮点数使用二进制,因此就像我们有一个包含一个,十个,数百个和十分之一,十分之一列的数字系统一样,计算机中的浮点数实际上具有一个,两个,四个和一半,四分之一和四分之一。第八列。如果客户熟悉英尺/英寸,请提醒他们通常如何使用以2为底的英寸为单位进行测量。
现在尝试将10美分存储为一半,四分之一,八分之一美元的组合。只是不起作用:
.00011001100110011。。。(无限重复)
这与获取标准的英制卷尺并尝试测量十分之一英寸相同。您无法做到准确。没有将1/10表示为X / Y,其中X和Y是整数,Y是2的幂。
这就是为什么我们拥有使用4位存储每个十进制数字的十进制数据类型的原因,因此我们回到以10为基数的表示形式。需要权衡的是空间和性能(据我所读,大约有100%的性能下降)。
告诉他们,就像他们的银行帐户无法容纳4.4423425908459032890413 ...美元(即$ 4.44或$ 4.45,中间什么都没有)一样,计算机也不能轻易地以任意精度存储数字。存储的不完善会导致计算的不完善。
(这有点作弊,但是应该让他们知道问题出在哪里。)
在进行计算时,计算机通常使用近似值(例如,不是使用1000000.7,而是使用1000000),因为使用近似值的速度要快得多。这样做的问题是,当您使用近似值进行计算时,您会获得近似值。通常效果很好,但有时会导致意外结果。
一些计算是根据某些法律规则进行的。例如,如果您要计算在德国应税的年收入79.245,18欧元必须缴纳多少所得税,那么只有一个正确的答案。正确或错误。如果操作正确,则无需解释浮点算法的工作原理。如果弄错了,则无需解释浮点算法的工作原理,而必须修复损坏的代码。
有时您显示的结果看起来不正确。例如,如果您将US $ 13,297.46转换为带有两位十进制数字的UK£,然后将该金额的UK£转换回US $,您可能不会获得US $ 13,297.46而是US $ 13,297.45或US $ 13,297.47。这与浮点算法无关。这是一个不可避免的问题,您最好能够解释为什么它不可避免。(您还应该知道,当您从UK£转换为USD并返回时,为什么不会出现此问题)。
还有其他可能看起来不正确的结果。如果将数字转换为百分比,则百分比的总和应为100%,但可能并非如此。如果使用两个小数显示四个百分比,则显示的四个百分比可能总计为99.99%或100.01%。与浮点运算无关。您仍然应该能够解释原因。
接下来,在某些情况下,粗心使用浮点算法会导致不适当的结果。例如,a + b + c通常与b + c + a不同。如果这引起了问题,则没有什么要解释的,这是您要解决的问题。