我想知道为什么 x86 架构上的指令
FYL2XP1
精确计算数学公式 y · log2(x + 1)。
这个公式有什么特别之处?
y
操作数通常是编译时间常数,暂时忘记x + 1
。
由于
log_b(x) = log_b(2) * log_2(x)
,该指令允许计算 x + 1
的任何底数的对数。log_b(2)
是一个常数,因为很少需要计算具有基数自由度的对数。
FYL2XP1
和 FYL2X
是仅有的两条计算对数的 x87 指令。FYL2X
适用于对数的整个域,但在整个范围内它并不完全准确,特别是对于x
的非常小的值(并且可能更慢,我相信它必须进行范围缩小,使用截断的泰勒展开式或 Padé 近似,然后通过查表提高准确性)。
FYL2XP1
相反,仅适用于小范围 ±( 1 – sqrt(2) ⁄ 2 ) 内的输入。该指令为接近 0 的 epsilon 值 [寄存器 ST(0) 中的值] 提供最佳精度。 小 epsilon (ε) 值,使用
指令比使用 (ε+1) 作为FYL2XP1
指令的参数。FYL2X
@Mysticial 的评论很到位:
在完成所有其他必要步骤之后,
FYL2X
使用的算法可能正在使用 log(x + 1)
的近似公式。log(x)
的公式,必须将输入减一。如果 x - 1
非常小,则 x
运算将失去精度(因为两个数字的指数之间的巨大差异会将 x
的大部分数字向右移动)。FYL2XP1
不会做 x - 1
因此不会失去精度。
据我了解,该指令的常见描述包含不准确之处。从历史上看,该指令不是在 ±(1 – sqrt(2) ⁄ 2) 范围内工作,而是在 sqrt(2) ⁄ 2 – 1 <= x <= sqrt(2) – 1. This is a convenient range of approximation of this function using a series expansion (e.g. by Chebyshev method). This seems to be true because then the left and right boundaries of the range for the argument of the logarithm (x + 1) differ by a factor of 2, which makes it relatively easy to extend the result of this function to any x > -1 范围内工作。
需要注意的是,在所有现代处理器中,
fyl2xp1
指令支持任何 x > -1,并且可以安全地使用此功能。但您需要记住,如果参数错误,该指令不会引发异常。
致OP,该公式是Shannon-Hartley公式,用于在给定带宽(y)和信噪功率比(x)的情况下确定传输系统的容量C,即C = B*log2(1+ S/N)