Поскольку вы помечено пост 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
, чтобы быть более точным, всегда есть вероятность того, что результат не является идеальным, поэтому - при отображении значений с плавающей запятой - установите точность на уровень, достаточный для компенсации e для ошибок коммутации на уровне, который имеет смысл для вашей проблемы.
Точность представления действительных чисел может быть получена из 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, даже если вы удается выглядеть так:
(Spoiler: outpu является
d1 != d2
d1 almost equals d2
) ;-)
Ditch '#define PI', используйте M_PI из заголовка. –
@ н.м. это не стандартизованное определение – krzaq
[Родственный вопрос] (http://stackoverflow.com/questions/6566512/value-of-sine-180-is-coming-out-as-1-22465e-16) – njuffa