打开网易新闻 查看精彩图片

1、在与数据打交道的过程中,四舍五入,无疑是无法回避的问题。正如BtOfficer在《知VBA的浮点数结构,更懂矿机装显卡》中所述,虽然计算机里只有整数,但在客观世界里,没有那么多刚刚好的事。毕竟,小数点里才有人间烟火。

2、但是浮点数有精度问题,比如3个人均分1块钱,如果太过算计,反而会一事无成。不过好在我们的先祖,早就明白了取舍,有舍才有得是我们为人处世的哲学。所以,千年以前我们就有了四舍五入的约定,也即>=5则入,<5则舍。这也成为我们日常四舍五入最直观的常识。

3、随着科技的发展,电子计算机在各个方面上,都在改造着人类的生产生活。电子表格软件,对于厘清社会要素的流动上,发挥着不可估量的作用。而Office和WPS这类电子表格软件中的表格函数(Round)以及VBA中的内置函数(Round)则担负起了四舍五入的职责。

4、相信用过Round函数的朋友都说好,但是这里面却存在一个很容易被人忽略的问题。无论是遇到,还是没遇到的朋友,都可以来看一看。

打开网易新闻 查看精彩图片

在VB/VBA中,Round(0.565,2)=0.56。是不是不敢相信?按照四舍五入的理解,明明该0.57嘛。在工作表中,也有Round函数,但前述结果恰恰为0.57,与直觉理解相符。二者出现迥然不同的结果,这就是问题,很多人遇到过的人,甚至称之为Bug,将锅甩给了VB/VBA。

5、但真是这样吗?这么明显的Bug,开发小组和测试小组都没发现?就像Dateiff函数计算年、季、月数一样,看上去违反常识理解,实际上却是常识在误导。

浮点数,只有在科学计算中,才会真正涉及精度问题。日常生活中的浮点数,每一位都是有意义的,也就是说它们是精确的,不涉及精度问题,只涉及取舍问题。但问题在于,有了计算器后,原本取舍问题,因为计算,变成了精度和取舍的双重问题。

为了更好地说明问题,举个例子:会计上有个费用分摊的概念,比如需要将100元,分摊到1-3月,那么每个月分摊的费用为100/3。在计算上,这会导致无限循环小数,从而在无意义的精度上不得不有所取舍,但分歧就此产生。以下分析按小数点后3位为有效取舍位。

按计算,则每个月都是33.333...。如果按直观常识的四舍五入,则每月为33.33,合计数为99.99。如果还要照顾数据整体精度,则必然有1个月为33.34,这样合计数才是100。
看到了没?我们通常理解的四舍五入,要么夸大数据,要么缩小数据。这样在传递数据时,势必会传递这种误差。而后一种,能够在概率上保证数据整体的精度,缩小误差。

打开网易新闻 查看精彩图片

6、这其实对应了四舍五入的两种算法,一种非平衡算法,另一种平衡算法。非平衡算法,就是我们直观常识理解的那种,真的有舍有得,约定俗成。而平衡算法,则建立在概率统计的基础上,力求数据整体的取舍平衡。

事实上,平衡算法是一种国际标准,大部分开发语言都遵守这一标准。所以,不仅VB/VBA存在这样的现象,Python/C#等,也一样存在这样的现象。所以,不必纠结VB/VBA内置的Round函数的计算结果是否准确。

7、既然平衡算法更符合统计学的精确,那为何工作表中的Round函数和日常使用中却采用误差更大的非平衡算法呢?原因,就在于更符合直觉判断,这个就叫亲兄弟明算账,有舍有得,但心知肚明,更可控吧。

不知这样的理解,大家是否认可?欢迎关注BtOfficer,留言吐槽,更多精彩正在有备而来。