双精度坐标系统
在有些时候需要您计算超大数值(例如空间距离),或反之,需要计算超小数值(例如微观世界中的距离)。 那为了应对这类情况,Unigine引擎引入了64位双精度浮点格式(替代常规32位单精度浮点格式)来定义虚拟场景中的对象坐标。 因而,也就为我们创建拥有最高细节,几乎达到无边无际的世界提供了可能性(其最大坐标值实际上比32位浮点精度坐标系统的最大坐标值的536,870,912倍还要大)。
实际上由于定位误差的累计,即使是在应对超出10x10千米范围场景的时候,其浮点精度的局限性也是显而易见的,因此,对于任何较大规模的场景而言,应该使用双精度来保持其精度。
双精度与单精度比对
在计算方面,floating point (浮点) 指的是一种借助尾数和指数来表示实数的方法:
尾数 × 基数 ^ 指数,
在这里【基数】等于2。
IEEE浮点数算术标准 (IEEE 754) 是一项用于规范浮点精度以及双精度浮点格式的技术标准。 单精度浮点格式占用32bits(4字节)存储空间,双精度浮点格式占用64bits(8字节)存储空间。 您可以在下图中看到两种精度的浮点数格式:
在这里:
- S - 符号位 (0 - 正; 1 - 负)
- E - 指数部分 (单精度浮点使用127, 双精度浮点使用1023
- m - 尾数部分 [1;2]
浮点格式的分布(单、双精度都包括)是非规约的。 例如,我们可以取用 -1 ≤ E ≤ 2:
下图给出了单精度和双精度的有效取值范围,以及它们的最低possible gradations (有效分级)。
- 取值范围: [-10^9;+10^9]。 超出该范围的值都将被显示为inf。
- 小数部分的最大数字数量不能超过3个。
而通过UnigineScript方法设置的数则只有格式限制。
误差
使用单精度浮点格式会导致下面所显示的计算不准确。
定位误差
采用单精度浮点时因其possible gradation(有效分级)的间距非常大而导致出现positioning errors (定位误差)。 下面的图示给出了分别采用单、双精度时的定位情况:
在虚拟场景中,对象的变换(包括定位,旋转和缩放),动画和物理的实施都会导致出现定位误差,而反过来定位误差又会导致对象抖动。 为了避免这种问题以及能提供更为精准的定位,须采用双精度浮点坐标系统。 此外,定位误差也有可能引起顶点塌缩,就像下图展示的那样。
误差累计
由于IEEE 754标准给出的是数字的有限集,它是由实数的无限集映射而来,因此输出值中就可能引入了映射表示法的精度误差,这在进一步的运算中导致了Error Accumulation(误差累计)。 误差函数显示如下:
数字的最大绝对误差等于其possible gradation(有效分级)的一半。 由于指数递增时possible gradation(有效分级)被加倍了,继而误差也就跟着加大了。
对于单、双精度数而言,它们的数量分级(gradation)分别为2 ^ (E-150), and 2 ^ (E-1075)。
下面让我们来比较数值1的单、双精度数。
单 | 双 | |
---|---|---|
数字, dec (10进制) | 1.0 | 1.0 |
IEEE754,hex (16进制) | 3F800000 | 3FF00000 00000000 |
绝对误差,dec (10进制) | 2-23 ≈ 1.192*10-7 | 2-52 ≈ 2.220446*10-16 |
相对误差,% | 11.9209*10-6 | 2.220446*10-14 |
根据浮点数的分布,gradation(分级)值是增加的,这也导致了误差加大。 但相比之下,双精度数的误差有很多次是小于单精度数的误差的。