Calculate Sinx in C++

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
https://en.wikipedia.org/wiki/Radian
You need to input your value in radians, not degrees.
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.
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;
}

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
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
sin(35) = 0.57
That's the mathematical correct result. How would you get -0.428183 for 35 degree with sin()?
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?
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()?
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.




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

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.