Я новичок в C ++ и написал небольшую программу, чтобы узнать значения синуса и косинуса угла. Мой пример кода выглядит следующим образом:
#include <math.h>
#include <iostream>
#include <iomanip>
using namespace std;
#define PI 3.14159265
int main ()
{
double rate, result;
rate = 90.0;
result = cos (rate*PI/180);
cout<<"The cosine of " << rate << " degrees is " << result <<endl;
return 0;
}
Я получаю 1.7949e-009 в результате для cos (90). Есть ли способ получить 0 в качестве результата (в переменной результата) вместо этого формата? та же проблема случается за грех 180 градусов. Я хочу общее решение случаев, когда результирующее значение будет 0.
Поскольку вы отметили пост C ++, а не C, позвольте мне дать вам несколько советов по C ++:
<cmath>
и не <math.h>
#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.
Увидеть:
Отметим также, что, хотя более точный ИП делает result
чтобы быть более точным, всегда существует вероятность того, что результат не будет идеальным, поэтому при отображении значений с плавающей запятой установите точность на уровень, достаточный для компенсации ошибок коммутации на уровне, который имеет смысл для вашей проблемы.
Точность представления действительных чисел может быть получена из std::numeric_limits<double>::digits10
(от <limits>
заголовок): всегда хорошо вырезать 2-3 цифры.
Кроме того, учитывайте ошибки округления при выполнении вычитаний или сравнений: см. Пример в СТД :: numeric_limits :: эпсилон справочный документ:
#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
) 😉
#include <stdio.h>
#include <math.h>
#define PI 3.14159265
int main (){
double param, result;
param = 30.0;
result = sin (param*PI/180);
printf ("The sine of %f degrees is %f.\n", param, result );
return 0;
}
Я пробовал M_PI, 3.141592653589793238L или acos (-1l). Все эти приближения PI не дают ровно 0 в вашей программе.
Однако, по крайней мере, вы можете использовать std :: setprecision и std :: fixed (в iomanip) для отображения 0.
Или, может быть, вы можете использовать пользовательский эпсилон, чтобы округлить результат.
результат 1.7949e-009, это научный способ, вы можете использовать фиксированный способ, даже указать точность точки.
На самом деле 1.7949e-009 составляет около 0,0000000017949.
пользователь krzaq указывает формат вывода, который должен быть зафиксирован, и устанавливает точность 2, он напечатает:
the cosine of 90.0 degree is 0.00
кроме того, ваш PI не является достаточно точным.
чтобы получить высокую точность, единственное, что вам нужно сделать, это загрузить glm. glm — выдающаяся математическая вечеринка, она отлично работает в математической функции OpenGL.
вот код, использующий glm:
#include <iostream>
#include <glm.hpp>
int main()
{
double Angle, Result;
Angle = 90.0;
Result = glm::cos(glm::radians(Angle));
std::cout << "The cosine of " << Angle << " degrees is " << std::fixed << Result << std::endl;
return 0;
}
Есть ли способ получить 0 как результат [для косинуса (90 °)]?
Шаг 1, используйте более точную машину PI
Шаг 2: Вместо преобразования в радианы, а затем вызвать cos()
уменьшить диапазон и затем преобразовать в радианы, а затем вызвать cos()
,
Уменьшение дальности может быть сделано именно так с fmod(x,360.0)
и далее с различными тригонометрические идентификаторы.
Этот ответ предоставить информацию об общем подходе и подробный sind(double degrees)
, Ниже приведено общее решение случаев, когда результирующее значение будет 0. Эта почта обсуждается -0.0
проблемы.
// cos() of 90.0 degrees is 6.1232339957367660e-17
// cosd() of 90.0 degrees is 0.0000000000000000e+00
#include <cmath>static double d2r(double d) {
static const auto PI = std::acos(-1);
return (d / 180.0) * PI;
}
double cosd(double x /* degrees */) {
if (!isfinite(x)) {
return std::cos(x);
}
int quo;
double x90 = std::remquo(std::fabs(x), 90.0, &quo);
double xr = d2r(x90);
switch (quo % 4) {
case 0:
return std::cos(xr);
case 1:
// Use + 0.0 to avoid -0.0
return std::sin(-xr + 0.0);
case 2:
return -std::cos(xr);
case 3:
return std::sin(xr + 0.0);
}
return 0.0;
}