使用std::acos从std::cos(角度)恢复精确的角度
Restoring the exact angle from std::cos(angle) using std::acos
如果angle
在[0,Pi]范围内,c++标准是否保证angle == std::acos(std::cos(angle))
,或者换句话说,在给定上述范围限制的情况下,使用std::acos
从std::cos
的结果恢复angle
的确切原始值是可能的?
省略angle
为infinity
或NaN
时的边缘情况
答案:
标准不能保证这一点,因为
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度。
按标准:
http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/n4606.pdf本国际标准对准确度没有要求的浮点运算;参见18.3.2。
即使在数学上这也是不可能的。例如,cos(2*PI)
是0,cos(4*PI)
也是0。
相关文章:
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- 如何在不接触函数本身的情况下暂停和恢复 C++11 std::thread 的功能
- 使用std ::螺纹暂停/恢复异步过程
- 如何在使用管道后将std::cin恢复到键盘上
- 是否可以从std::abort中恢复
- 如何保存和恢复 std::istringstream 的缓冲区?
- c++std::normal_distribution在从文件恢复时给出不一致的随机数
- 使用 std::atomic 与 std::condition_variable 在 C++ 中暂停和恢复 std::thread 的方法
- 如何保存std::mersenne_twister_engine的状态以便以后恢复
- 使用std::acos从std::cos(角度)恢复精确的角度
- 存储和恢复std::vector数据
- 使用std::string键从boost::无序::无序映射中恢复值时出错