既然您标记了帖子 C++ 而不是 C,让我给您一些 C++ 提示:
- 数学的标准标题是
<cmath> 而不是<math.h>
- 在c++中有更好的方法来声明
#define的常量
- 浮点数不是实数的精确表示(不存在计算精确表示),因此您总是会出现舍入错误。
获得结果的更惯用方法是:
#include <cmath>
#include <iostream>
#include <iomanip>
int main ()
{
const auto PI = std::acos(-1); //let the computer to find out what PI is
double rate{}, result{}; //don't let uninitialized values
rate = 90.0;
result = std::cos (rate*PI/180);
std::cout<<"The cosine of " << // set outoput precison for floating point
std::setprecision(4) << rate << " degrees is " <<
std::setprecision(4) << result <<endl;
return 0;
}
注意我是如何让 std:: 显式:C++ <cmath> 的数学函数比 C 有更多的重载。
见:
还要注意,虽然更准确的 PI 会使result 更准确,但结果总是有可能不完美,因此 - 当显示浮点值时 - 将精度设置为足够的水平在对您的问题有意义的水平上补偿换向错误。
实数的表示精度可以从std::numeric_limits<double>::digits10(来自<limits>标头)获得:切掉2-3位总是好的。
此外,在进行减法或比较时,请考虑舍入误差:请参阅std::numeric_limits::epsilon 参考文档中的示例:
#include <cmath>
#include <limits>
#include <iomanip>
#include <iostream>
#include <type_traits>
#include <algorithm>
template<class T>
typename std::enable_if<!std::numeric_limits<T>::is_integer, bool>::type
almost_equal(T x, T y, int ulp)
{
// the machine epsilon has to be scaled to the magnitude of the values used
// and multiplied by the desired precision in ULPs (units in the last place)
return std::abs(x-y) < std::numeric_limits<T>::epsilon() * std::abs(x+y) * ulp
// unless the result is subnormal
|| std::abs(x-y) < std::numeric_limits<T>::min();
}
int main()
{
double d1 = 0.2;
double d2 = 1 / std::sqrt(5) / std::sqrt(5);
if(d1 == d2)
std::cout << "d1 == d2\n";
else
std::cout << "d1 != d2\n";
if(almost_equal(d1, d2, 2))
std::cout << "d1 almost equals d2\n";
else
std::cout << "d1 does not almost equal d2\n";
}
这表明 sqrt(5) 的平方不是... 5,即使您设法看起来是这样:
(剧透:输出是
d1 != d2
d1 almost equals d2
) ;-)