1

So I am doing a C++ question about sine.

It says that sin x can be approximated via the polynomial x-(x^3/6)+(x^5/120)-(x^7/5040), and it tells me to output both the approximated sin value and the sin value calculated via cmath.

The input is in degrees, and we have to first convert it to radians then find out sin.

Sample run (only 45 is the input, other our output):

Angle: 45 approxSin = 0.70710647 cmath sin = 0.70710678

I have attempted to write a code for this. When I pressed command+R, nothing happens despite the program saying "build successful". I am new to Xcode, so I am not sure whether I used Xcode incorrectly or I wrote the program incorrectly. Can anyone help?

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

my code

AMU
  • 13
  • 4
  • 2
    May I suggest that you take a step back, and go back to your books, tutorials or class-notes? Because you don't *call* your function `approxSin`. You do however properly call the standard `sin` function, so you clearly know how to call functions. What makes you think that there's a difference between a function you define, and one of the standard functions? If you don't have any books then [here's a list of good books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282). – Some programmer dude Feb 24 '19 at 08:41
  • `cout << "approxSin = " << &approxSin << endl;` This prints the address of function `approxSin` but doesn't call it. Shouldn't it be `approxSin(angleDeg)`? – Scheff's Cat Feb 24 '19 at 08:42
  • The condition `-180 – Some programmer dude Feb 24 '19 at 08:44
  • You may want to use `std::pow`...thanks god you did not have to do `x^100` in your code.... – jpo38 Feb 24 '19 at 08:46
  • Oh you *do* know how to call your `approxSin` function, since you do it recursively inside itself. But I don't think you're really supposed to do that... Not that it matters here since the function isn't called to begin with. And when condition fails you don't return *anything*. Again, *get a book, please!* – Some programmer dude Feb 24 '19 at 08:50
  • I am just a beginner with C++, I suppose there is something wrong with "approxSin"? I just copied it from the question: – AMU Feb 24 '19 at 08:58

2 Answers2

0

My guess about your problem: You run the program, and it patiently waits for your input.

With

cin >> angleDeg;

your program seemingly halts, while it's waiting for you to give some input in the IDE console window. Since you haven't written any prompt there's no output to tell you it's waiting for input.

I suggest you add some output first to ask for the input:

cout << "Please enter angle in degrees: ";
cin >> angleDeg;
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • I have done so, but I get the message that my code returns nothing. Which part did I do wrong? – AMU Feb 24 '19 at 10:38
0

When I pressed command+R, nothing happens despite the program saying "build successful".

I guess that the answer by Some programmer dude should solve this issue, but, as noted in the comments, there are much worse problems in the posted code, probably depending by a misunderstanding of how functions should be declared and called in C++.

Consider this:

double approxSin(double angleDeg) {
    if (-180<angleDeg<180) return approxSin(/* Some unreadable expression */);
}

It's enough to generate a couple of warning:

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&ltangleDeg&lt180) return approxSin(angleDeg-(...));
        ~~~~~~~~~~~~~^~~~
prog.cc:6:35: warning: all paths through this function will call itself [-Winfinite-recursion]
double approxSin(double angleDeg) {
                                  ^

The relational operators are evaluated left-to-right, so that an expressions like -180<angleDeg<180 is read by the compiler as (-180 < angleDeg) < 180. The result of -180 < angleDeg is a bool which leads to the kind warning by the compiler about that expression beeing always true.

It could be written as -180 < angle && angle < 180, but given the OP's assignment, the angle should be tested against plus or minus pi. Also, the alternative branch should be written as well.

The second warning is about the recursive call of the function, which makes no sense, without any alternative path. I can only guess that the OP has misinterpreted how values are returned from a function.

The polynomial itself could be evaluated in a more readable way using std::pow or applying Horner's method. I'll show an example later.

The other big problem (specular, someway) is in the "call" site, which isn't a call at all:

cout << "approxSin = " << &approxSin << endl;

It ends up printing 1 and the reasons can be found in this Q&A: How to print function pointers with cout?

Last, I'd note that while the assignment specifically requires to convert the inputted angle from degrees to radians (as the argument of std::sin is), the posted code only checks the range in degrees, without any conversion.

The following implementation compares different methods for evaluating the sin() function

#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;
}
Bob__
  • 12,361
  • 3
  • 28
  • 42
  • @AMU Yes: https://wandbox.org/permlink/geiScVeDx3np38Pi . It shouldn't be difficult to adapt it to your needs. Please tell me if there's something unclear. – Bob__ Feb 25 '19 at 09:43