atan2 函数在什么时候会在 C++ 中出现零值域错误?
At what point will the atan2 function reach a domain error for a zero value in c++?
如果我有类似这样的功能:
c=atan2( a, 0 )
我试图弄清楚 a
值应该限制在什么范围内,以确保 atan2() 不会导致任何域错误。所以问题是在引发域错误之前可以得到多接近零。这个 atan2 函数可以计算小至 0.0000001 的数字吗?什么时候读为零?
找出答案的最佳方法是亲自尝试!
#include <iostream>
#include <stdio.h>
#include <limits>
#include <math.h>
using namespace std;
int main()
{
int powers[12] = {10, 11, 12, 13, 14, 15, 20, 22, 24, 26, 28, 30};
for (auto i : powers)
{
try
{
double a = pow(10, -i);
printf("a = 10^-%d; atan2(a, 0) = %.10e\n", i, atan2(a, 0));
// cout << "a = 10^" << -i << "; atan2(a, 0) = " << atan2(a, 0) << endl;
}
catch (int e)
{
cout << "Failed to compute atan2(10^" << -i << ", 0)" << endl;
}
}
double minvalue = numeric_limits<double>::min();
try
{
printf("a = %.10e; atan2(a, 0) = %.10e\n", minvalue, atan2(minvalue, 0));
// cout << "a = " << minvalue << "; atan2(a, 0) = " << atan2(minvalue, 0) << endl;
}
catch (int e)
{
cout << "Failed to compute atan2(" << minvalue << ", 0)" << endl;
}
return 0;
}
输出:
a = 10^-10; atan2(a, 0) = 1.5707963268e+00
a = 10^-11; atan2(a, 0) = 1.5707963268e+00
a = 10^-12; atan2(a, 0) = 1.5707963268e+00
a = 10^-13; atan2(a, 0) = 1.5707963268e+00
a = 10^-14; atan2(a, 0) = 1.5707963268e+00
a = 10^-15; atan2(a, 0) = 1.5707963268e+00
a = 10^-20; atan2(a, 0) = 1.5707963268e+00
a = 10^-22; atan2(a, 0) = 1.5707963268e+00
a = 10^-24; atan2(a, 0) = 1.5707963268e+00
a = 10^-26; atan2(a, 0) = 1.5707963268e+00
a = 10^-28; atan2(a, 0) = 1.5707963268e+00
a = 10^-30; atan2(a, 0) = 1.5707963268e+00
a = 2.2250738585e-308; atan2(a, 0) = 1.5707963268e+00
对于尽可能小的正双精度效果非常好。
它甚至适用于 5E-324
,这是最小的正非正规双精度数。
double minvalue = std::numeric_limits<double>::denorm_min();
printf("a = %.10e; atan2(a, 0) = %.10e\n", minvalue, atan2(minvalue, 0));
输出:
a = 4.9406564584e-324; atan2(a, 0) = 1.5707963268e+00
如果我有类似这样的功能:
c=atan2( a, 0 )
我试图弄清楚 a
值应该限制在什么范围内,以确保 atan2() 不会导致任何域错误。所以问题是在引发域错误之前可以得到多接近零。这个 atan2 函数可以计算小至 0.0000001 的数字吗?什么时候读为零?
找出答案的最佳方法是亲自尝试!
#include <iostream>
#include <stdio.h>
#include <limits>
#include <math.h>
using namespace std;
int main()
{
int powers[12] = {10, 11, 12, 13, 14, 15, 20, 22, 24, 26, 28, 30};
for (auto i : powers)
{
try
{
double a = pow(10, -i);
printf("a = 10^-%d; atan2(a, 0) = %.10e\n", i, atan2(a, 0));
// cout << "a = 10^" << -i << "; atan2(a, 0) = " << atan2(a, 0) << endl;
}
catch (int e)
{
cout << "Failed to compute atan2(10^" << -i << ", 0)" << endl;
}
}
double minvalue = numeric_limits<double>::min();
try
{
printf("a = %.10e; atan2(a, 0) = %.10e\n", minvalue, atan2(minvalue, 0));
// cout << "a = " << minvalue << "; atan2(a, 0) = " << atan2(minvalue, 0) << endl;
}
catch (int e)
{
cout << "Failed to compute atan2(" << minvalue << ", 0)" << endl;
}
return 0;
}
输出:
a = 10^-10; atan2(a, 0) = 1.5707963268e+00
a = 10^-11; atan2(a, 0) = 1.5707963268e+00
a = 10^-12; atan2(a, 0) = 1.5707963268e+00
a = 10^-13; atan2(a, 0) = 1.5707963268e+00
a = 10^-14; atan2(a, 0) = 1.5707963268e+00
a = 10^-15; atan2(a, 0) = 1.5707963268e+00
a = 10^-20; atan2(a, 0) = 1.5707963268e+00
a = 10^-22; atan2(a, 0) = 1.5707963268e+00
a = 10^-24; atan2(a, 0) = 1.5707963268e+00
a = 10^-26; atan2(a, 0) = 1.5707963268e+00
a = 10^-28; atan2(a, 0) = 1.5707963268e+00
a = 10^-30; atan2(a, 0) = 1.5707963268e+00
a = 2.2250738585e-308; atan2(a, 0) = 1.5707963268e+00
对于尽可能小的正双精度效果非常好。
它甚至适用于 5E-324
,这是最小的正非正规双精度数。
double minvalue = std::numeric_limits<double>::denorm_min();
printf("a = %.10e; atan2(a, 0) = %.10e\n", minvalue, atan2(minvalue, 0));
输出:
a = 4.9406564584e-324; atan2(a, 0) = 1.5707963268e+00