Como dices, tu solución carece de "valor" en tanto que utilizas la librería <math.h>, que resuelve el problema que se te pide.
El cálculo de funciones trigonométricas se puede abordar desde muchos puntos de vista (calculo numérico, teoremas de trigonometría), pero todos ellos serán imprecisos en sus resultados en la medida que el sistema de tipos de C, (float) esta limitado en su capacidad para representar, no digamos ya cualquier número real, si no muchos números racionales, por ejemplo (1/3).
El clásico método para
aproximar la función seno ( el resto, coseno y tangente, investigalos por tu cuenta) se basa en el Teorema de Taylor que permite el cómputo del valor de sen en términos de operraciones elementales, productos, sumas, potencias y divisiones:
sinus(x) = sum i : 0<= i : (((-1)^i)/(2i+1)!)*x^(2i+1)
Como no es posible extenderme puesto que no es un curso de análisis numérico, baste decir que en toda implementación hay que tener en cuenta la precisión con la que abordamos el problema, en nuestro caso, hasta las diezmilésimas (10^-4)
Allá va el código. La línea central, la más compleja de elaborar, es la 28. Expplicar de donde se saca es un poco complejo sin entrar en manipulaciones algebraicas. Baste decir que t es el sumando correspondeinte al valor n. Lo que hace 28 es actualizar t para la siguiente vuelta, y esto se puede hacer en función del valor que tiene actualmente t.
#include <iostream>
#include <iomanip> // To format floats into screen
/* Uses Taylor formula to compute sin(x), x in gradiants
sinus(x) = sum i : 0<= i : (((-1)^i)/(2i+1)!)*x^(2i+1)
Any computer program makes a finite computation, hence
we only add summands up to epsilon (in our case, 10^-4)
*/
#define PI 3.1416
#define G2R(g) (g*PI/180)
#define EPSILON 0.0001
#define ABS(x) ((x>=0)?x:-x)
using namespace std;
/* P: r given in radians */
float sinus(const float r)
{
int n;
float s,t;
for(n=s=0,t=r; ABS(t) >= EPSILON ; n++)
{
s+=t;
t = ((-1)*r*r*t)/((2*n+3.0)*(2*n+2.0));
}
return s;
}
int main(int argc, char *args[])
{
float g;
for ( ; cin >> g ; )
{
const float r = G2R(g);
std::cout << std::fixed << std::setw( 11 ) << std::setprecision(4)
<< g << " " << r << " " << sinus(r) << endl;
}
}
Y a continuación, la salida a algunos casos de angulos conocidos, como son aquellos de seno 0,1,-1 y 0.5.
La primera columna marca el ánglo en grados, la segunda en radianes (aproximado) y la tercera la función seno del mismo....Se aprecia como en el caso de 360 grados cuyo seno es 0, arroja una aproximaci'on de 0,0001
0 90 180 270 360
0.0000 0.0000 0.0000
90.0000 1.5708 1.0000
180.0000 3.1416 0.0000
270.0000 4.7124 -1.0000
360.0000 6.2832 0.0001
30 150 210 330
30.0000 0.5236 0.5000
150.0000 2.6180 0.5000
210.0000 3.6652 -0.5000
330.0000 5.7596 -0.5000
1200
1200.0000 20.9440 5.4417
El último caso es llamativo, pues da un error incoherente...El seno sólo puede ser entre -1 y 1. Nuevamente, se debe a la imprecisión para representar numeros grandes, y ciertamente, si te fijas en el producto del código de la línea 28, esta incluye un valor "relativamente grande", que float es incapaz de representar. Ojo a los errores en el cálculo numérico!