这种分割近似算法如何工作?

我正在使用软件渲染器进行游戏,以获得最准确的PS1外观。 当我正在研究PS1图形/渲染系统的工作原理,摇摆顶点的原因等时,我遇到了一些关于他们分工的文档。 这里是它的链接:http://problemkaputt.de/psx-spx.htm#gteoverview(请参阅“GTE分区不准确性”部分)

相关代码:

  if (H < SZ3*2) then                            ;check if overflow
    z = count_leading_zeroes(SZ3)                ;z=0..0Fh (for 16bit SZ3)
    n = (H SHL z)                                ;n=0..7FFF8000h
    d = (SZ3 SHL z)                              ;d=8000h..FFFFh
    u = unr_table[(d-7FC0h) SHR 7] + 101h        ;u=200h..101h
    d = ((2000080h - (d * u)) SHR 8)             ;d=10000h..0FF01h
    d = ((0000080h + (d * u)) SHR 8)             ;d=20000h..10000h
    n = min(1FFFFh, (((n*d) + 8000h) SHR 16))    ;n=0..1FFFFh
  else n = 1FFFFh, FLAG.Bit17=1, FLAG.Bit31=1    ;n=1FFFFh plus overflow flag

我很难理解这是如何工作的,这个'不'表是什么? 我们为什么要改变事情? 如果有人能够更详细地解释这件事实际上是如何实现鸿沟的,那将不胜感激。


该算法是[0,1)中两个无符号16位小数值的定点除法。 它首先通过表格查找计算除数倒数的初始9位近似值,并用单一的Newton-Raphson迭代对倒数xi + 1:= xi *(2-d * xi)进行精化,得到一个倒数精确到大约16位,最后乘以这个除数,在[0,2)中产生一个17位的商。

对于表格查找,除数首先通过应用比例因子2z归一化为[0.5,1],显然这个除数需要用相同的比例因子进行调整。 由于[0.5,1]中操作数的倒数将为[1,2],所以倒数的整数位已知为1,因此可以使用8位表格条目生成1.8个定点通过加上0x100 (= 1)来倒数。 这里使用0x101的原因尚不清楚; 这可能是由于这个步骤总是高估了真正的互惠。

接下来的两个步骤是牛顿 - 拉夫逊迭代的逐字翻译,其中考虑了定点比例因子的倒数。 所以0x2000000代表2.0。 该代码使用0x2000080因为它将以下除以256的舍入常量0x80 (= 128)合并,用于重新缩放结果。 下一步同样会将0x00000080作为舍入除法的舍入常量,加上256。如果不进行缩放,则这将是纯粹的乘法。

最终乘法n*d乘以在倒数d与被除数n得到的商在33位。 再次,在除以65536之前应用舍入常数0x8000以重新调整到适当的范围,以1.16定点格式给出商。

连续重新缩放是固定点计算的典型代表,其中试图尽可能保持中间结果以最大化最终结果的准确性。 有点不寻常的是,四舍五入适用于所有中间算法,而不仅仅是最后一步。 也许有必要达到指定的准确度。

该函数并不是那么准确,但可能是由初始逼近中的不准确性所引起的。 在所有非例外情况下,2,424,807,756匹配正确舍入的1.16定点结果,780,692,403错误1 ulp,15,606,093有2-ulp错误,86,452有3-ulp错误。 以快速的实验中,在初始近似的最大相对误差u是3.89e-3。 一种改进的查找表降低最大相对误差在u至2.85E-3,减少但在最后的结果不消除3- ULP错误。

如果你想看一个具体的例子,考虑h = 0.3( 0x4ccd )除以SZ3 = 0.2( 0x3333 )。 那么z = 2,因此d = 0.2 * 4 = 0.8( 0xcccc )。 这导致u = 1.25( 0x140 )。 由于估计值非常准确,我们期望(2-d * u)接近1,实际上, d = 1.000015( 0x10001 )。 精炼的倒数出现在d = 1.250015( 0x14001 ),因此商是n = 1.500031( 0x18002 )。

链接地址: http://www.djcxy.com/p/94751.html

上一篇: How does this division approximation algorithm work?

下一篇: Tensorflow: How to use a trained model in a application?