使用std::acos从std::cos(角度)恢复精确的角度

Restoring the exact angle from std::cos(angle) using std::acos

本文关键字:std 恢复 角度 acos cos 使用      更新时间:2023-10-16

如果angle在[0,Pi]范围内,c++标准是否保证angle == std::acos(std::cos(angle)),或者换句话说,在给定上述范围限制的情况下,使用std::acosstd::cos的结果恢复angle的确切原始值是可能的?

省略angleinfinityNaN时的边缘情况

答案:

标准不能保证这一点,因为std::cos的结果可能不能用double精确地表示,所以你会得到一个截断错误,这将影响std::acos的结果。

From cppreference.com:

如果没有错误发生,[acos返回]arg (arccos(arg))在[0;π)

以度为单位,从0到180,包括,对应于余弦值1到-1,包括。

超出这个范围,你甚至不能得到一个近似的对应关系。计算余弦会丢弃关于超出该范围的角度的信息。没有办法取回那些信息。

信息如何被丢弃:

首先,对于任意整数K, cos(x) = cos(K*360 + x),其次,cos(x) = cos(-x)。这就产生了大量的角度值,产生相同的余弦值。

同样,尽管所有读者可能都知道这一点,但为了完整:因为正弦和余弦都是非常无理数,通常不是简单的分数,你不能期望精确的结果,除了余弦1,它对应于0度。

按标准:

本国际标准对准确度没有要求的浮点运算;参见18.3.2。

http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/n4606.pdf

即使在数学上这也是不可能的。例如,cos(2*PI)是0,cos(4*PI)也是0。