математика — поиск значений синуса и косинуса угла в переполнении стека

Я новичок в 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.

0

Решение

Поскольку вы отметили пост C ++, а не C, позвольте мне дать вам несколько советов по C ++:

  1. Стандартный заголовок для математики <cmath> и не <math.h>
  2. в C ++ есть лучший способ объявить константы, которые #define
  3. Числа с плавающей запятой не являются точным представлением действительного числа (для которого не может существовать точное вычислительное представление), поэтому вы всегда получаете ошибки округления.

Более идиотский способ прийти к результату может быть таким:

#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

) 😉

3

Другие решения

#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;
}
0

Я пробовал M_PI, 3.141592653589793238L или acos (-1l). Все эти приближения PI не дают ровно 0 в вашей программе.
Однако, по крайней мере, вы можете использовать std :: setprecision и std :: fixed (в iomanip) для отображения 0.
Или, может быть, вы можете использовать пользовательский эпсилон, чтобы округлить результат.

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

Есть ли способ получить 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;
}
0
По вопросам рекламы [email protected]