问题的后续行动cmath exp() 和 log() 函数是否总是对称的?
double x;
double y = exp(log(x));
assert(x == y);
本质上,如果一个人写入log(x)
磁盘并exp()
在另一个系统上进行计算——c 语言在多大程度上保证了对称性?考虑到可能在不同系统上的一长串,人们应该担心结果 exp(log())
离原来有多远?x
问题的后续行动cmath exp() 和 log() 函数是否总是对称的?
double x;
double y = exp(log(x));
assert(x == y);
本质上,如果一个人写入log(x)
磁盘并exp()
在另一个系统上进行计算——c 语言在多大程度上保证了对称性?考虑到可能在不同系统上的一长串,人们应该担心结果 exp(log())
离原来有多远?x
在这个答案中,我解决了系统之间的差异,而不是exp(log(x))
. 正如您在另一个问题中所指出的那样,往返结果通常不等于输入,即使使用 and 的最佳实现也是exp
如此log
。
在实践中,数学库函数的准确性并不能保证,并且不同的提供者使用不同的算法和近似值,因此结果因平台而异。
最好的商业库以亚 ULP 精度为目标,这意味着每个结果都在精确数学结果的最后一位(浮点格式)的一个单位内。对于数学库中一些更深奥的函数,这通常无法实现。并非所有图书馆都以此为目标。即使两个不同的库都保证 sub-ULP 的准确性,它们也不会总是返回相同的结果。
有一个学术项目CRlibm,其目标是提供数学库例程的正确舍入实现。正确舍入的实现返回与所选舍入方法中的精确数学结果最接近的唯一可表示值(最接近、接近零、接近无穷大或接近 - 无穷大)。考虑到浮点格式的限制,正确舍入的结果可能是最准确的结果。crlibm-1.0beta3.pdf 提供 和 的正确舍入实现,log
并exp
带有证明。
因为正确舍入的结果是唯一定义的,所以两个具有正确舍入实现的库将返回彼此相同的结果。
作为一般规则,像这样的浮点运算(尤其是在 的不同实现之间log
等)永远不能保证具有精确的逆运算。所以我的答案是