Ken*_*nol 5 c trigonometry ieee-754
我已经在许多正弦/余弦的实现中看到了所谓的扩展模块化精度算法.但是它的用途是什么?例如,在cephes实现中,在缩减到[0,pi/4]范围后,他们正在进行这种模块化精度算法以提高精度.
下面的代码:
z = ((x - y * DP1) - y * DP2) - y * DP3;
Run Code Online (Sandbox Code Playgroud)
其中DP1,DP2和DP3是一些硬编码系数.如何在数学上找到这些系数?我已经理解了大数字"模块化扩展算术"的目的,但这里的确切目的是什么?
nju*_*ffa 10
在三角函数的参数减少的背景下,你所看到的是Cody-Waite论证减少,这是一本书中介绍的技术:William J. Cody和William Waite,基本函数软件手册,Prentice-Hall,1980.尽管在中间计算中减去了消除,但目标是为了达到一定幅度的参数,实现精确的简化参数.为了这个目的,相关的常数被表示用比天然精度更,通过使用减小的量值的多个号码的总和(在此:DP1,DP2,DP3),使得所有的中间产物,除了至少显著一个能够不舍入误差计算.
以IEEE-754 binary32(单精度)中sin(113)的计算为例.典型的参数减少将在概念上计算i=rintf(x/(?/2)); reduced_x = x-i*(?/2).的binary32最接近的数到π/ 2是0x1.921fb6p+0.我们计算i=72,产品舍入到0x1.c463acp+6,接近参数x=0x1.c40000p+6.在减法期间,一些前导位取消,我们结束reduced_x = -0x1.8eb000p-4.注意重整化引入的尾随零.这些零位不携带有用的信息.对减少的参数应用精确的近似值sin(x) = -0x1.8e0eeap-4,而真实的结果是-0x1.8e0e9d39...p-4.我们结束了大的相对误差和大的ulp误差.
我们可以通过使用两步Cody-Waite参数减少来解决这个问题.例如,我们可以使用pio2_hi = 0x1.921f00p+0,和pio2_lo = 0x1.6a8886p-17.注意在单精度表示的八个拖尾零个比特pio2_hi,这允许我们使用任何8位整数相乘i,仍然有该产品i * pio2_hi可表示恰好为单精度数.当我们计算((x - i * pio2_hi) - i * pio2_lo),我们得到reduced_x = -0x1.8eafb4p-4的,因此sin(x) = -0x1.8e0e9ep-4,一个相当精确的结果.
将常量分割为和的最佳方法取决于i我们需要处理的幅度,取决于给定参数范围的减法消除的最大位数(基于π/ 2的整数倍数可以达到的接近程度)整数)和性能考虑因素.典型的现实使用案例涉及两到四级的Cody-Waite减少方案.融合多重加法(FMA)的可用性允许使用具有较少尾随零比特的组成常数.参见本文:Sylvie Boldo,Marc Daumas和Ren-Cang Li,"用融合的乘法加法正式验证了参数的减少." IEEE Transactions on Computers,58:1139-1145,2009.对于使用的工作示例,fmaf()您可能希望查看我以前的一个答案中的代码.