Calculate Sinx in C++

Jan 27, 2021 at 6:50am
Hello,

I'd like to calculate sinx with the below formula.
My answer is wrong. for example sin(35) is 0.42 but my program gave me -0.42


Formula:
https://i.ibb.co/G0VPSFC/Screenshot-2021-01-27-014840.jpg

Thanks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
#include<math.h>
using namespace std;

double myPow(double x)
{
	//return sqrt(1-cos(2*x));
	return sqrt(1 - pow(cos(x),2));
}

int main()
{

	double d; cin >> d;
	cout << myPow(d);

	return 0;
}
Last edited on Jan 27, 2021 at 7:11am
Jan 27, 2021 at 7:03am
https://en.wikipedia.org/wiki/Radian
You need to input your value in radians, not degrees.
Jan 27, 2021 at 7:07am
cout << myPow(d) << " vs " << sin(d) << '\n'; prints for d=35:
0.428183 vs -0.428183


http://www.cplusplus.com/reference/cmath/cos/ says that parameter of cos():
Value representing an angle expressed in radians.
One radian is equivalent to 180/PI degrees.
Jan 27, 2021 at 7:16am
Thank you for your answer,
I don't understand.
My output is 0.428183 but it should be -0.428183.

Now I changed and answer is wrong again and sin(35) = 0.57 !

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include<math.h>
using namespace std;
#define PI 3.14159265

double myPow(double x)
{
	x = x * PI / 180.0;
	return sqrt(1 - pow(cos(x), 2));
}

int main()
{

	double r; cin >> r;

	cout << myPow(r);

	return 0;
}

Jan 27, 2021 at 8:18am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <cmath>

double sin( double x )
{
    const double cosx = std::cos(x) ;
    return std::sqrt( 1 - cosx*cosx ) ;
}

double radians( double deg )
{
    constexpr double pi = 3.14159265 ;
    return deg * pi / 180 ;
}


int main()
{
    std::cout << std::fixed << "degrees    radians      sin    std::sin\n"
                               "-------    --------  --------  --------\n" ;

    for( double d = 10 ; d < 91 ; d += 5 )
    {
        const double r = radians(d) ;
        std::cout << d << "  " << r << "  " << sin(r) << "  " << std::sin(r) << '\n' ;
    }
}


http://coliru.stacked-crooked.com/a/fa962b568a0e8053
Jan 27, 2021 at 9:25am
Try extending the range:
for( double d = -360 ; d < 361 ; d += 10 )

You've got something seriously wrong with those sine functions ("both" of them). The sine of an angle will be negative between 180 and 360 degrees (and also between -180 and 0 degrees).

(Clearly, sticking std:: there doesn't do what one might expect in terms of distinguishing functions, either!!!)



Try
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

const double PI = 4.0 * atan( 1.0 );
const double DEGTORAD = PI / 180.0;
const double TWOPI = 2.0 * PI;


double sine( double x )
{
   double cosx = cos(x);
   double s = x - TWOPI * floor( x / TWOPI ) < PI ? 1 : -1;
   return s * sqrt( 1 - cosx * cosx );                        // get the SIGN right
}


int main()
{
   #define FMT << ' ' << right << fixed << setw( 12 ) <<
   cout FMT "deg" FMT "rad" FMT "sine" FMT "std::sin\n";
   for( double deg = -360; deg < 361; deg += 10 )
   {
      double rad = deg * DEGTORAD;
      cout FMT deg FMT rad FMT sine( rad ) FMT sin( rad ) << '\n';
   }
}

Last edited on Jan 27, 2021 at 11:00am
Jan 27, 2021 at 10:51am
sin(35) = 0.57
That's the mathematical correct result. How would you get -0.428183 for 35 degree with sin()?
Jan 27, 2021 at 11:01am
sin(35 degrees) is 0.573576
sin(35 radians) is -0.428182

So sin(35) is never 0.42.

Also, as lastchance points out, just using the result of the sqrt() always provides a zero/positive result which is only correct when 0 <= x <= PI Otherwise the result is negative.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#define _USE_MATH_DEFINES
#include <cmath>
#include <iostream>
using namespace std;

double myPow(double x)
{
	const auto M_TWOPI {M_PI + M_PI};
	const auto cosx {cos(x)};
	const auto s {x - M_TWOPI * floor(x / M_TWOPI) < M_PI ? 1 : -1};

	return s * sqrt(1 - cosx * cosx);
}

constexpr double radians(double deg)
{
	return deg * M_PI / 180.0;
}

int main()
{
	double d {};

	cout << "Enter angle in degrees: ";
	cin >> d;

	cout << myPow(radians(d));
}


But this is a strange way to obtain the value of sine() by using cosine() - and calling the function myPow(). What was the original requirement?
Jan 27, 2021 at 12:19pm
But this is a strange way to obtain the value of sine() by using cosine() - and calling the function myPow().

To calculate sine from cosine is math. Simple exercise, isn't it?
Alas, the "formula" is correct for only half of the angles and then there are the rad/deg conversions.
Still, simple exercise that teaches something about <cmath>.

"myPow()" ... is clearly not an intuitive name for function that computes sine. Perhaps her_sin()?
Jan 27, 2021 at 2:30pm
a "simple" problem? https://ijarcce.com/wp-content/uploads/2015/10/IJARCCE-10.pdf

you can do it less efficiently by chasing the unit circle. Use the equation of a circle, the known radius of 1, and distance formula or slope of the hypotenuse ... find points on the circle and you can get the angle and its trig values from sin = O/H tan = O/A etc. The points will have the +- signs for their quadrants and the signs will also work out. Not very efficient, but its a way to do it. The slope of the hypo is opposite over adjacent (aka rise over run) is the tangent which is sin(x)/cosin(x) blah blah..

you can of course use the taylor series as well. Its a very simple one.




Jan 27, 2021 at 5:23pm
For a 'straight forward' non iterative/recursive method of calculating sine in degrees, consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>

double sine_d(double x)
{
	const auto T2 {[](auto x) { return 2 * x * x - 1; }};
	const auto T3 {[](auto x) { return 4 * x * x * x - 3 * x; }};
	const auto T4 {[](auto x) { return 8 * x * x * x * x - 8 * x * x + 1; }};
	const auto T5 {[](auto x) { return 16 * x * x * x * x * x - 20 * x * x * x + 5 * x; }};

	constexpr double C0 {1.276278962};
	constexpr double C1 {-.285261569};
	constexpr double C2 {0.009118016};
	constexpr double C3 {-.000136587};
	constexpr double C4 {0.000001185};
	constexpr double C5 {-.000000007};

	x = fmod(x, 360.0);

	if (x < 0)
		x += 360.0;

	if (x > 90.0 && x <= 270.0)
		x = 180.0 - x;
	else
		if (x > 270.0)
			x = x - 360.0;

	const double w {4.0 * x / 360.0};
	const double z {2.0 * w * w - 1.0};

	return (C0 + C1 * z + C2 * T2(z) + C3 * T3(z) + C4 * T4(z) + C5 * T5(z)) * w;
}

int main()
{
	double a {};

	std::cout << "Enter angle in degrees: ";
	std::cin >> a;

	std::cout << sine_d(a) << '\n';
}

Jan 28, 2021 at 10:56am
I know the OP didn't want recursion, but I quite like this method. It's sweeter than the Taylor-series approach. For large angles it could be improved by reducing to the [0,2.pi] interval first, but that spoils the recursion a bit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;

const double PI = 4.0 * atan( 1.0 );
const double DEGTORAD = PI / 180.0;
const double TWOPI = 2.0 * PI;


double sine( double x )
{
   const double eps = 1.0e-6;
   if ( abs( x ) < eps ) return x;
   double S = sine( x / 3 );
   return 3 * S - 4 * S * S * S;
}


int main()
{
   #define FMT << ' ' << right << fixed << setw( 12 ) <<
   cout FMT "deg" FMT "rad" FMT "sine" FMT "std::sin\n";
   for( double deg = -360; deg < 361; deg += 10 )
   {
      double rad = deg * DEGTORAD;
      cout FMT deg FMT rad FMT sine( rad ) FMT sin( rad ) << '\n';
   }
}
Topic archived. No new replies allowed.