今天,我的一位朋友向我展示了网站上的一个错误。(关联)
您可以看到百分比之和为 100.1%。
49 + 20.7 + 10.9 + 7 + 5.5 + 7 = 100.1%
我想:如果我正在编程并且有这 7 个(浮点)数字,我该如何解决这个问题?
假设所有数字都有一位小数:
49.0 + 20.7 + 10.9 + 7.0 + 5.5 + 7.0 = 100.1%
我相信这是一个四舍五入的问题,我没有看到该错误的其他解释。
例如:
49.5% + 50.5% = 100%,如果我们四舍五入的话,50% + 51% = 101%。
但在这种情况下,因为我们有两个数字,所以我们可以使用舍入来求偶。
49.5% + 50.5% = 100%,如果四舍五入的话,50% + 50% = 100%。
这些数字已经被污染了,因为它们的总和是 100.1%,因此,至少有一个数字等于自己减去 0.5。
在这个 7 数字示例中,四舍五入到偶数不起作用,因为它不适用于以下总和:
49 + 20.65 + 10.85 + 7 + 5.5 + 7 = 100%
49 + 20.6 + 10.8 + 7 + 5.5 + 7 = 99.9%
有没有简单/快速的方法来解决这个问题?使用不同的舍入方法?
或者我解决这个问题的唯一方法是创建一个函数来专门处理我的问题?
注意:我并不是在寻找特定的编程语言方法。我希望我能用不同的语言(例如 PHP 和 C++)解决这个问题。
首先,您对可能原因的分析并不是这里的实际原因。\n但是您正在谈论的概念称为舍入方案中的偏差。它确实存在并且是真实的 - 它只是不是您此处特定问题的原因。
\n\n在您声称导致此问题的示例中:49.5% + 50.5% = 100%,向上舍入,50% + 51% = 101%。\n向上舍入(向正无穷大舍入)相当于舍入-0 表示正数。请参阅下面的舍入方案列表1。\n但是,这不太可能是这里的原因,除非您碰巧得到两个相同等于 a.5 和 b.5 的相邻数字而不是 a.7 + b.8 + c.5,或任何其他数字组合。\n为了证明为什么这不是实际原因,在这个 n 个数字的列表中,有 (n-1) 个相邻对,并且如果我们做出合理的假设如果最后一个数字的概率相等,那么获得相邻数字 a.5, b.5 的机会仅为 (0.1)^2 = 0.01
\n\n无论如何,这里的真正原因是由于缺少精度而引入的数字错误(由于转换为字符串“%2.1f”的数字表示被截断)(无论他们使用哪种语言,大概是 PHP、Javascript 或 Java)...
\n\n通常且最简单的解决方案是提高精度。严格来说,这里您可能只需要一位(或两位)数字,但IEEE 754 浮点数免费为您提供 23 位尾数,因此每个人都使用它。
\n\n然而,如果您确实坚持要给自己设置一个(人为的)挑战,即在精度缺失的情况下对数字进行舍入,并且在它们总和必须为 100.0%(或最大化它们的机会)的约束下,有几种较少使用的舍入方案。\您可以在教科书中找到它们,但由于明显的原因,它们在现实世界中并没有太多使用,因为它们引入了随机性和可能的不确定性(尽管您可以设置随机种子,以至少确保可重复性)。
\n\n因此,无论它的价值如何,这里都是这些舍入方案(以及许多其他舍入方案,请参阅整篇文章):
\n\n[2] http://en.wikipedia.org/wiki/Rounding#Tie-breaking
\n\n以下所有内容都会导致 q=.5 情况的偏差,并且您说您想完全避免使用它们(而不是携带额外的精度,这使得问题消失):
\n\n现在,以下是您感兴趣的内容:
\n\n如果 y 的小数部分为 0.5,则在 y + 0.5 和 y \xe2\x88\x92 0.5 之间以等概率随机选择 q。\n优点:基本上没有整体偏差;但它在偶数和奇数 q 值中也是“公平的”。另一方面,它在结果中引入了随机成分;对相同的数据执行两次相同的计算可能会产生两个不同的结果。此外,如果人类(而不是计算机或随机设备)“随机”决定向哪个方向进行舍入,则可能会出现无意识偏见。
\n\n如果小数部分为 0.5,则向上舍入和向下舍入交替:对于第一次出现 0.5 的小数部分,向上舍入;对于第二次出现,向下舍入;依此类推。\n如果可以有效地对 0.5 个小数部分的出现进行编号,则这会抑制结果的随机分量。但如果出现的总数是奇数,它仍然可以根据分配给第一次出现的舍入方向引入正偏差或负偏差。
\n\n如果您想阅读有关这些内容的所有内容(计算机算术以及实现它的硬件电路),一个很好的参考资料(在硬件方面很重要)是
\n\n\n\n计算机算术算法,第二版,Israel Koren\n www.ecs.umass.edu/ece/koren/arith/\xe2\x80\x8e\n 马萨诸塞大学\n 阿默斯特,2010 年
\n
| 归档时间: |
|
| 查看次数: |
7559 次 |
| 最近记录: |