pow(x,y)计算为e ^(y log(x)) 通常,数学库会以四倍精度计算log(x)(这很费时间),以避免计算ylog(x)时精度的损失,因为精度误差会在e ^(y * log(x)。 现在,以防我想在以下步骤中计算pow(x,y)。
double pow(double x,double y) {
return exp(y*log(x)); //Without any quad precision multiplication
}
此功能的最大ULP错误是多少?我确实知道IEEE-754标准规定,任何浮点运算都应具有小于0.5的ULP误差,即0.5 * 2 ^(-52)。 因此,如果我的操作y log(x)遇到0.5 ULP误差,如何计算e ^(y log(x))
的最大ULP误差同意pow(x,y)的计算相当复杂。算法通常以更高的精度计算log(x),并且y和log(x)之间的乘法并不简单。由于ULP误差取决于y log(x),因此最大误差将是Y log(x)的最大值,而e ^(y log(x))不存在无穷。对?在这种情况下,如何计算ULP的数量?在y log(x)最大值的情况下,双精度格式中尾数的最大位数是多少,该位数会与实际值不同?
更新了问题。感谢您的所有帮助!
那么10位的差异将导致多少ULP错误?我将其计算为
ULP = (actual - computed)/ 2^(e-(p-1))
其中e是实际数字的指数,对于双精度,p = 53。我读到我ULP = 2 ^(e-(p-1)) 假设,
Actual = 1.79282279439444787915898270592 *10^308
Computed = 1.79282279439451553814547593293 * 10^308
error= actual - computed = 6.7659e+294
现在
1 ULP = 2^(e- (p-1))
e = 1023 (exponent of the actual number - bias)
1 ULP = 2^(1023 - (53-1)) = 2^971
ULP error = error/ 1 ULP = 339
这正确吗?
答案 0 :(得分:1)
我现在没有时间更全面地回答,但是这里有一些要开始的地方:
假设每个单独操作(exp
,*
和log
中的错误最多为1/2 ULP。这意味着对于某些,log(x)
的计算值正好是log( x )•(1+ e 0 ) e 0 满足-/ 2≤ e 0 ≤/ 2,其中ULP为1(2 −52 IEEE-754基本64位二进制格式)。并且y*log(x)
的计算值正好是 y •log( x )•(1+ e 0 )•(1+ e 1 )对于-/ 2≤ e 0 ≤/ 2且-/ 2≤ e 1 ≤/ 2。 exp(y*log(x))
的计算值恰好是e y •log( x )•(1+ e 0 )•(1+ e 1 )•(1+ e 2 )对于-/ 2≤ e 0 , e 1 , e 2 ≤/ 2。而且错误当然是e y •log( x )•(1+ e 0 )•(1+ e 1 )•(1+ e 2 )− e < sup> y •log( x )。
然后,您可以开始分析该表达式的最大和最小值,取值范围为 e 0 , e 1 < / sub>和 e 2 。如果0 < y 和1 < x ,则当 e 0 = e < / em> 1 = e 2 = / 2。
请注意,exp
和log
的常见实现通常无法正确取整。几个ULP的错误可能很常见。因此,除非已证明例程已正确舍入,否则不应假定½ULP限制。
答案 1 :(得分:0)
最大浮点错误(对于
exp(y*log(x))
)
x == 0
错误是无限的;
x <0
OP的pow()
失败,但是当y
没有小数部分时,它应该完成。
x> 0
让z = y*log(x)
。该计算中的错误可能非常合理-只有几个ULPs或更小。给定通常的double
,让我们假设1个ULP或z_error = z*
2 -53 。
请考虑其影响:exp(z + error_z) = exp(z)*exp(error_z)
。
z
大约为710,exp(709.78)
大约为DBL_MAX
,所以让我们考虑到,更大的值会导致OP的pow()
无限大。
exp(some_small_value)
大约为1 + some_small_value
。那么exp(error_z)
是1 + 710*pow(2,-53)
。因此,最后的pow()
可能会损失大约log2(710)
或9、10以及一些精度。