use*_*774 1 c++ floating-point
我的代码
double to_radians(double theta)
{
return (M_PI * theta) / 180.0;
}
int main()
{
std::vector<std::pair<double, double>> points;
for (double theta = 0.0; theta <= 360.0; theta += 30.0)
{
points.push_back(std::make_pair(std::cos(to_radians(theta)), std::sin(to_radians(theta))));
}
for (auto point : points)
std::cout << point.first << " " << point.second << "\n";
}
Run Code Online (Sandbox Code Playgroud)
我希望输出
1 0 0.866025 0.5 0.5 0.866025 0 1 -0.5 0.866025 -0.866025 0.5 -1 0 -0.866025 -0.5 -0.5 -0.866025 0 -1 0.5 -0.866025 0.866025 -0.5 1 0
输出我得到:
1 0 0.866025 0.5 0.5 0.866025 6.12303e-17 1 -0.5 0.866025 -0.866025 0.5 -1 1.22461e-16 -0.866025 -0.5 -0.5 -0.866025 -1.83691e-16 -1 0.5 -0.866025 0.866025 -0.5 1 -2.44921e-16
正如你所看到的,我得到的是这些奇怪的值,而不是零.有人可以解释为什么会这样吗?
Pas*_*uoq 10
6.12303e-17举个例子,代表值6.12303*10 -17,或0.00000000000000000612303.
你得到这个值的原因是你没有申请cosπ/ 2,这double无论如何都不能表示(它是无理的).该cos函数应用于double接近π/ 2,通过将90乘以M_PI并除以180得到.由于参数不是π/ 2,结果不必为0.实际上,因为浮点数更多密集接近于零,对于任何浮点格式来说,将正确舍入cos到任何浮点数的结果都非常不可能产生零结果.
事实上,由于cosπ/ 2 的导数是-1,因此表达式获得的值cos(M_PI/2.0)是M_PI/2π/ 2 之间的差值的近似值.这种差异确实是d*10 -17的顺序,因为双精度IEEE 754格式只能代表任意数字的前16个左右第一个十进制数字.
请注意,相同的参数适用于获取0.5结果cos(M_PI/3.0),甚至-1.0作为结果cos(M_PI).不同之处在于有许多浮点数,有些非常小,大约为0,这些可以非常精确地表示预期的非零结果.相比之下,0.5并且-1.0只有少数邻居,并且对于足够接近π/ 3和π的输入,数字0.5和-1.0最终作为最接近的可表示的双精度值返回到相应的数学结果(不是1/2)或-1,因为输入不是π/ 3或π).
解决问题的最简单方法是使用假设函数cosdeg,sindeg直接计算角度的余弦和正弦度.由于60和90可以完全表示为双精度浮点数,因此这些函数没有理由不返回0.5或0.0(也可以精确表示为双精度浮点数).我之前提出了一个与这些函数有关的问题,但没有人指出任何已经可用的实现.
的功能sinpi和cospi通过njuffa指出通常可用的,并且它们允许以计算正弦和余弦或π/ 2,π/ 4或甚至7.5*π,但不是π/ 3的,自号1/3他们将有要应用于二进制浮点不能完全表示.
| 归档时间: |
|
| 查看次数: |
315 次 |
| 最近记录: |