« freebsd 被 gfw 了 | 返回首页 | lua 终于支持了16进制数 »

EPSILON is NOT 0.00001!

今天看到一篇 blog , 浮点数 和 EPSILON 。 这个问题我关注过好几次,最早是为了公司里台球的项目在公司内部 wiki 上写过。后来在留言本上也写过帖子。 http://www.codingnow.com/2004/board/view.php?paster=412&reply=0

想起来,去年 gdc2005 时完整的听过一个讲座,叫做 Numerical Robustness for Geometric Calculations 对这个问题谈的比较深入,google 了一把,把 PPT 找出来了 :) http://realtimecollisiondetection.net/pubs/ 有兴趣可以下载看看。

Comments

然很多人只知fabs(a-b)<0.0001
而不知其如何然
当深入了解以后,才懂得还是能够用a==b判断

我前面帖子给的方法最简单:

判断两个 float a,b 比较是否相等只需要判断:

`(((*(unsigned long*)&a) ^ (*(unsigned long*)&b)) & ~0xf) == 0`

没有EPSILON 的取值问题,运算速度还快。

看了链接的blog, 将a==b写成`fabs(a-b)<epsilon`虽然并不能彻底解决浮点数比较的问题,但在a,b的值本身就很小(`<1.0`)还是非常有用的.而且程序员可以调整epsilon的值,这在程序员实现特定算法的时候就很有用。因为特定的算法往往可以确定浮点误差的允许范围。IEEE-754浮点数保证的是浮点数的有效数字而不是小数点后尾数的位数,程序员不可能找到一个够通用的epsilon值.在通常情况下,用相对误差比较方法更合理.`abs(x-y)<=epsilon*max(1.0f, abs(x), abs(y)).`

例如积分什么的一定要选择最合适的方法防止误差累积。

是啊,如何应对误差累积是计算机仿真的一个主要课题。

hoho,听起来像蝴蝶效应

同样是台球项目。本人在公司的台球项目开始之初。写了一些模拟台球运行的小程序,程序使用了D3DX库的数学函数。分别在AMD/Intel的芯片上跑,结果发现当运算(其实就是一些物理学公式,相当于是一些微积分计算)的次数比较多的时候,同样的输入值将会导致不同的运算结果。有时候两值的差值甚至大于1!估计是D3DX库针对不同芯片使用了不同的优化指令,如3DNow!和SSE所致。后来不使用D3DX库函数。而用标准C库的基本数学函数重写向量,矩阵,四元数的操作类和函数。C库在X86架构的芯片是使用标准X86的FPU指令,就没有出现上述的问题。

在《计算机图形学几何工具算法详解 》一书首章对计算机浮点数和实数系统之间的关系有比较详细的阐述。

呵呵,这人的blog太熟悉了,他也是n年前就在叫唤这个浮点数问题的

Post a comment

非这个主题相关的留言请到:留言本