2016-10-13 53 views
0

Я новичок в C++ и написал небольшую программу, чтобы узнать значения синуса и косинуса угла. Мой пример кода выглядит следующим образом:Найти значения синуса и косинуса угла в 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 в качестве результата для соз (90). Есть ли способ получить 0 в качестве результата (в переменной результата) вместо этого формата? одна и та же проблема - извинение за грех 180 градусов. Я хочу, чтобы общее решение тех случаев, когда полученное значение будет 0.

+1

Ditch '#define PI', используйте M_PI из заголовка. –

+3

@ н.м. это не стандартизованное определение – krzaq

+0

[Родственный вопрос] (http://stackoverflow.com/questions/6566512/value-of-sine-180-is-coming-out-as-1-22465e-16) – njuffa

ответ

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

Но он не сохраняет фактически 0 в переменной результата. правильно? @rishabhgupta – user76289

+0

'printf' и' ostream' могут использовать различную точность для печати, но это касается только симптома. – StoryTeller

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

Есть ли способ сохранить точное значение в переменной результата для будущего использования? @FrancisHoo – user76289

+0

значение результата все равно 1.7949e-009, оно не изменено ключевым словом fixed и setprecision (2). ключевое слово fixed и setprecision (2) просто ограничивают выходной формат. –

+0

Да, я говорю это. но что мне нужно сделать, чтобы сохранить точное значение для использования? @FrancisHoo – user76289

0

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

3

Поскольку вы помечено пост 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.

См:

Следует также отметить, что, хотя более точным 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 

) ;-)

0

Есть ли способ получить 0 в качестве результата [для косинуса (90 °)]?

Шаг 1, использовать более точную машину PI

Шаг 2: Вместо того, чтобы преобразовать в радианах, а затем вызвать cos(), уменьшить диапазон и затем преобразовать в радианах, а затем вызвать cos().

Дальность действия может быть выполнена exactly с fmod(x,360.0) и далее с различными trigonometric identifies.

This answer предоставит информацию об общем подходе и подробно sind(double degrees). Ниже приводится общее решение случаев, когда результирующее значение будет равно 0. This post обсуждает проблемы -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; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^