原文地址(英语):Precision of Calculation Results in Web Intelligence

作者:Pascal GAULIN 现就职于SAP

我们在Web Intelligence中用十进制数进行计算时,经常会对奇怪的计算结果产生疑问。


一般来说有这些问题:

  • 虽然C应该等于A + B,为什么当我输入A + B – C时结果却不是0
  • 为什么当我改变表的排序之后,运行求和的结果会有不同?
  • 等等。


这些奇怪的运算结果是基于一个事实,Web Intelligence使用了基于IEEE 754标准定义下的64位精度版本的浮点数据类型来表示十进制数。

该标准详细的解释,可以在这个维基百科页面上找到:

IEEE floating point – Wikipedia, the free encyclopedia

如果使用IEEE 754标准进行浮点运算,十进制数不能被完美地表示成二进制格式,因为不是所有的位数都有效。事实上,实际中有效的位数取决于表示的大小。

Web Intelligence中使用的64位表示(也叫做“双精度”),用来存储数据的比特数是53,而且根据上面维基百科页面上的解释,有效的位数是:

log(2^53),四舍五入就是15


重要的是:Web Intelligence中,十进制数的最大的有效位数是15,而且考虑到了小数点前后的位数。

例如:

  • 100,000,000,000 + 0.001会得到正确的结果100,000,000,000.0010   因为十进制数只要求15个有效位数表示出来(12位在小数点前3位在小数点后)。
  • 100,000,000,000 + 0.0001会得到错误的结果100,000,000,000.0000因为正确的结果需要16个有效位数表示出来(12位在小数点前4位在小数点后)。


由于这样的限制,在十进制数求和运算中很多时候可能得不到预想的结果,尤其是预期的结果是0的时候…!

例如,将19000.2, 0.123, -9100.3, -0.000000000002543等等求和,将只允许只有小数点后10位是有效的。事实上,小数点前5位已经被最大的数字19000.2给占用了。因此,如果求和的结果是这样的:-0.000000000013327,根据IEEE 754标准,那它就会和0没有区别。


因此,在Web Intelligence文档中,如果一个结果是0的十进制数运算被作为接下来步骤的条件的话,我们强烈建议在评估前把十进制数转换成整数。这样的四舍五入操作可以用Round(number; round_level)公式来解决,用0作为round_level的参数。


那么,为什么改变表的排序也可能会改变一个十进制运算的结果呢?


额……IEEE 754浮点格式另一个主要的限制就是十进制数的整数部分和小数部分是分开表示的,因此整数部分的表示是近似值。这样的结果就是,在计算的过程中会产误差,从而会导致不同的运算结果。


例如:

比方说,我们有A = 1,000,000, B = 1.2 and C = -1,000,000

A + B + C 会得到 1.19999999995343E0

A + C + B会得到1.2E0

这是因为,因为排序的不同,A + C + B产生的误差和 A + B + C产生的误差不同。


我希望这些关于奇怪的运算结果的问题现在大家都明白了吧! 😛

如果还没有,请不要犹豫,在下面提出你的问题。

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply