Итак, я задаю вопрос на С++ о синусе.
В нем говорится, что sin x может быть аппроксимирован полиномом x-(x^3/6)+(x^5/120)-(x^7/5040), и он говорит мне вывести как аппроксимированное значение sin, так и значение sin вычисляется с помощью cmath.
Входные данные в градусах, и мы должны сначала преобразовать их в радианы, а затем найти sin.
Пример запуска (только 45 входных данных, остальное наш вывод):
Угол: 45 приблизительно Sin = 0,70710647 cmath sin = 0,70710678
Я попытался написать код для этого. Когда я нажимаю команду + R, ничего не происходит, несмотря на то, что программа говорит «сборка выполнена успешно». Я новичок в Xcode, поэтому я не уверен, использовал ли я Xcode неправильно или неправильно написал программу. Кто-нибудь может помочь?
#define _USE_MATH_DEFINES
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
double approxSin(double angleDeg) {
if (-180<angleDeg<180) return approxSin(angleDeg-(angleDeg*angleDeg*angleDeg)/6+(angleDeg*angleDeg*angleDeg*angleDeg*angleDeg)/120-(angleDeg*angleDeg*angleDeg*angleDeg*angleDeg*angleDeg*angleDeg)/5040);
}
int main(){
float angleDeg;
cin >> angleDeg;
if (angleDeg>180) {
while (angleDeg>180) {
angleDeg = angleDeg-360;
}
} else if (angleDeg<-180) {
while (angleDeg<-180) {
angleDeg = angleDeg+360;
}
}
cout << "approxSin = " << &approxSin << endl;
cout << "cmath sin = " << setprecision(8) << sin(angleDeg);
return 0;
}
cout << "approxSin = " << &approxSin << endl; Это печатает адрес функции approxSin, но не вызывает ее. Разве не должно быть approxSin(angleDeg)?
(-180<angleDeg<180) не делает то, во что вы верите, это умирает, вам нужно написать (-180<angleDeg && angleDeg<180). И вы забыли другой случай.
-180<angleDeg<180 не то, что вы ожидаете, и где часть еще?
Условие -180<angleDeg<180 тоже неверное, а также показатель того, что вам нужно читать дальше. Условие равно -180<(angleDeg<180), что означает, что вы сравниваете -180 с логический результатangleDeg<180.
Вы можете использовать std::pow... слава богу, вам не пришлось делать x^100 в своем коде....
О, ты, делать, знаешь, как вызвать свою функцию approxSin, поскольку ты делаешь это рекурсивно внутри себя. Но я не думаю, что вы действительно должны это делать... Не то, чтобы это имело значение здесь, поскольку функция не вызывается с самого начала. И когда условие не выполняется, вы не возвращаете что-либо. Опять же, возьмите книгу, пожалуйста!
Я только новичок в C++, я полагаю, что-то не так с "приблизительноSin"? Я просто скопировал это из вопроса:





Мой предполагать о вашей проблеме: вы запускаете программу, и она терпеливо ждет вашего ввода.
С участием
cin >> angleDeg;
ваша программа, по-видимому, останавливается, ожидая, пока вы что-нибудь введете в окне консоли IDE. Поскольку вы не написали никакого приглашения, нет вывода, чтобы сообщить вам, что он ожидает ввода.
Я предлагаю вам сначала добавить некоторый вывод, чтобы запросить ввод:
cout << "Please enter angle in degrees: ";
cin >> angleDeg;
Я так и сделал, но получаю сообщение, что мой код ничего не возвращает. Какую часть я сделал неправильно?
When I pressed command+R, nothing happens despite the program saying "build successful".
Я предполагаю, что отвечать от Какой-то программист чувак должен решить эту проблему, но, как отмечено в комментариях, в опубликованном коде есть гораздо более серьезные проблемы, вероятно, связанные с непониманием того, как функции должны объявляться и вызываться в C++.
Учти это:
double approxSin(double angleDeg) {
if (-180<angleDeg<180) return approxSin(/* Some unreadable expression */);
}
Достаточно сгенерировать пару предупреждений:
prog.cc:7:22: warning: result of comparison of constant 180 with expression of type 'bool'
is always true [-Wtautological-constant-out-of-range-compare]
if (-180<angleDeg<180) return approxSin(angleDeg-(...));
~~~~~~~~~~~~~^~~~
prog.cc:6:35: warning: all paths through this function will call itself [-Winfinite-recursion]
double approxSin(double angleDeg) {
^
Реляционные операторы оцениваются слева направо, поэтому такие выражения, как -180<angleDeg<180, читаются компилятором как (-180 < angleDeg) < 180. Результатом -180 < angleDeg является bool, что приводит к любезному предупреждению компилятора о том, что это выражение всегда истинно.
Его можно записать как -180 < angle && angle < 180, но, учитывая назначение ОП, угол следует проверить на соответствие плюс или минус пи. Кроме того, альтернативная ветка также должна быть написана.
Второе предупреждение касается рекурсивного вызова функции, что не имеет смысла, без какого-либо альтернативного пути. Я могу только догадываться, что ОП неверно истолковал, как значения возвращаются из функции.
Сам многочлен можно было бы оценить более читабельным способом, используя std::pow или применяя метод Хорнера. Я покажу пример позже.
Другая большая проблема (в каком-то смысле зеркальная) заключается в сайте «вызов», который вообще не является вызовом:
cout << "approxSin = " << &approxSin << endl;
В итоге печатается 1, а причины можно найти в этом Q&A: Как печатать указатели функций с помощью cout?
Наконец, я хотел бы отметить, что, хотя задание специально требует преобразования введенного угла из градусов в радианы (как аргумент std::sin), опубликованный код проверяет только диапазон в градусах без какого-либо преобразования.
Следующая реализация сравнивает различные методы оценки функции sin().
#define _USE_MATH_DEFINES
#include <iostream>
#include <iomanip>
#include <cmath>
namespace my {
// M_PI while widespread, isn't part of the ISO standard
#ifndef M_PI
constexpr double pi = 3.141592653589793115997963468544185161590576171875;
#else
constexpr double pi = M_PI;
#endif
constexpr double radians_from_degrees(double degrees)
{
return degrees * pi / 180.0;
}
constexpr double convert_angle_to_plus_minus_pi(double angle)
{
while ( angle < -pi )
angle += 2.0 * pi;
while ( angle > pi ) {
angle -= 2.0 * pi;
}
return angle;
}
// Approximates sin(angle), with angle between [-pi, pi], using a polynomial
// Evaluate the polynomial using Horner's method
constexpr double sin_a(double angle)
{
// A radian is passed, but the approximation is good only in [-pi, pi]
angle = convert_angle_to_plus_minus_pi(angle);
// Evaluates p(a) = a - a^3 / 6 + a^5 / 120 - a^7 / 5040
double sq_angle = angle * angle;
return angle * ( 1.0 + sq_angle * (-1.0/6.0 + sq_angle * ( 1.0/120.0 - sq_angle / 5040.0)));
}
double sin_b(double angle) {
angle = convert_angle_to_plus_minus_pi(angle);
return angle - pow(angle, 3) / 6.0 + pow(angle, 5) / 120.0 - pow(angle, 7) / 5040.0;
}
} // End of namespace 'my'
int main()
{
std::cout << " angle std::sin my::sin_a my::sin_b\n"
<< "-----------------------------------------------\n"
<< std::setprecision(8) << std::fixed;
for (int i = -90; i < 475; i += 15)
{
double angle = my::radians_from_degrees(i);
std::cout << std::setw(5) << i
<< std::setw(14) << std::sin(angle)
<< std::setw(14) << my::sin_a(angle)
<< std::setw(14) << my::sin_b(angle) << '\n';
}
return 0;
}
@AMU Да: wandbox.org/permlink/geiScVeDx3np38Pi . Приспособить его под свои нужды не составит труда. Пожалуйста, скажите мне, если есть что-то неясное.
Могу я предложить вам сделать шаг назад и вернуться к своим книгам, учебникам или классным заметкам? Потому что вы не вызов свою функцию
approxSin. Однако вы правильно вызываете стандартную функциюsin, так что вы точно знаете, как вызывать функции. Что заставляет вас думать, что есть разница между определяемой вами функцией и одной из стандартных функций? Если у вас нет книг, вот список хороших книг.