机器学习是现在很火的一门技术,很多人一提起机器学习就大谈特谈各种算法。这些算法都有理论基础,主要就是数学公式,然后就是用数值方法求解这些公式。跟机器学习类似,油藏数值模拟器的理论基础也是需要用数值算法求解大量的数学公式。有很多人认为只要有数学公式,那么开发成软件就很简单了。但是现实并不是这样,主要原因是因为使用目前的计算机并不能描述一个无限制的浮点数,它只能描述某个固定长度的一个数值,超出这个固定长度(注意是长度而不是值的大小),数据会被截断。截断其实就是舍弃掉超出这个长度以外的数据。截断所造成的数值误差,称为截断误差。这是目前的计算机中表示数据与我们想象最大的差异,也是最不引常人注意的差异。正是这个差异导致了要编程完美地求解一套数学公式并不像很多人想象的那么简单。我们来看最简单的一个公式的数值求解——累加求和公式(下图):
很多人会说,求和有什么复杂的,把这些数累加起来就行啊,一个循环就可以搞定。理论上来说这个算法没问题,但是现实却是残酷的,并不是所有的数这么加起来就能得到正确的和。由于上面说的差异,计算机在求解的时候会出现大数吃掉小数的情况。这里以C语言中的float类型为例,float是基础的浮点数类型,长度是32位(4个字节)。它所能描述的浮点数是有效位数是7位(实际能绝对保证的只有6位)。下图是IEEE对浮点数的表示定义。