The reason you're getting incorrect values is that π
is not 3.14159, that's just an approximation to its real value. In fact, any non-infinite series of decimal digits will be an approximation but, the more digits you have, the closer i * val
will be to the correct value you should be passing to your trigonometric calls.
A far better value would be M_PI
from math.h
, which has far more precision than what you currently have.
You still may not get your expected values due to the limited precision of even the double
type. If that happens, you will need to adjust what you get before working things out in floating point.
For example, the following functions could be used to get more acceptable values, forcing very specific values on quadrant boundaries so as to avoid even the smallest possibility of imprecision in those results:
double mySin(int degrees) {
int mod360 = degrees % 360;
if (mod360 == 0) return 0.0;
if (mod360 == 90) return 1.0;
if (mod360 == 180) return 0.0;
if (mod360 == 270) return -1.0;
return sin(degrees % 360 * M_PI / 180.0);
}
double myCos(int degrees) {
return mySin(degrees + 90);
}
double myTan(int degrees) {
int mod360 = degrees % 360;
if (mod360 == 0) return 0.0;
if (mod360 == 90) return 1.0 / 0.0;
if (mod360 == 180) return 0.0;
if (mod360 == 270) return -1.0 / 0.0;
return tan(mod360 * M_PI / 180.0);
}
double myCot(int degrees) {
// Now that tan() works properly for the quadrant
// boundaries, just use normal formula.
return 1.0 / myTan(degrees);
}
These are built from the ground up to use degree inputs rather than radians and, because you trap the infinite value cases before doing any floating point math (which is inherently imprecise when you're dealing with transcendentals), you can give the correct results for those cases.
A complete program, integrating these functions and getting rid of stuff you don't need is shown below. There's no point storing all those values in an array and then printing out the array (with no other use of it) when you can just print the values immediately:
#include <cmath>
#include <cstdio>
using namespace std;
double mySin(int degrees) {
int mod360 = degrees % 360;
if (mod360 == 0) return 0.0;
if (mod360 == 90) return 1.0;
if (mod360 == 180) return 0.0;
if (mod360 == 270) return -1.0;
return sin(mod360 * M_PI / 180.0);
}
double myCos(int degrees) {
return mySin(degrees + 90);
}
double myTan(int degrees) {
int mod360 = degrees % 360;
if (mod360 == 0) return 0.0;
if (mod360 == 90) return 1.0 / 0.0;
if (mod360 == 180) return 0.0;
if (mod360 == 270) return -1.0 / 0.0;
return tan(mod360 * M_PI / 180.0);
}
double myCot(int degrees) {
// Now that tan() works properly for the quadrant
// boundaries, just use normal formula.
return 1.0 / myTan(degrees);
}
int main()
{
printf("İstenen Tablo\n");
printf("-------------\n");
printf("\t ACI \t SIN \t COS \t TAN \t COT\n");
printf("\t------------\t-----------\t-----------\t-----------\t-----------\n");
for (int i = 0; i < 360; i += 10) {
printf("\t%12d\t%9.9lf\t%9.9lf\t%9.9lf\t%9.9lf\n",
i, mySin(i), myCos(i), myTan(i), myCot(i));
}
return 0;
}
The output of that is:
İstenen Tablo
-------------
ACI SIN COS TAN COT
------------ ----------- ----------- ----------- -----------
0 0.000000000 1.000000000 0.000000000 inf
10 0.173648178 0.984807753 0.176326981 5.671281820
20 0.342020143 0.939692621 0.363970234 2.747477419
30 0.500000000 0.866025404 0.577350269 1.732050808
40 0.642787610 0.766044443 0.839099631 1.191753593
50 0.766044443 0.642787610 1.191753593 0.839099631
60 0.866025404 0.500000000 1.732050808 0.577350269
70 0.939692621 0.342020143 2.747477419 0.363970234
80 0.984807753 0.173648178 5.671281820 0.176326981
90 1.000000000 0.000000000 inf 0.000000000
100 0.984807753 -0.173648178 -5.671281820 -0.176326981
110 0.939692621 -0.342020143 -2.747477419 -0.363970234
120 0.866025404 -0.500000000 -1.732050808 -0.577350269
130 0.766044443 -0.642787610 -1.191753593 -0.839099631
140 0.642787610 -0.766044443 -0.839099631 -1.191753593
150 0.500000000 -0.866025404 -0.577350269 -1.732050808
160 0.342020143 -0.939692621 -0.363970234 -2.747477419
170 0.173648178 -0.984807753 -0.176326981 -5.671281820
180 0.000000000 -1.000000000 0.000000000 inf
190 -0.173648178 -0.984807753 0.176326981 5.671281820
200 -0.342020143 -0.939692621 0.363970234 2.747477419
210 -0.500000000 -0.866025404 0.577350269 1.732050808
220 -0.642787610 -0.766044443 0.839099631 1.191753593
230 -0.766044443 -0.642787610 1.191753593 0.839099631
240 -0.866025404 -0.500000000 1.732050808 0.577350269
250 -0.939692621 -0.342020143 2.747477419 0.363970234
260 -0.984807753 -0.173648178 5.671281820 0.176326981
270 -1.000000000 0.000000000 -inf -0.000000000
280 -0.984807753 0.173648178 -5.671281820 -0.176326981
290 -0.939692621 0.342020143 -2.747477419 -0.363970234
300 -0.866025404 0.500000000 -1.732050808 -0.577350269
310 -0.766044443 0.642787610 -1.191753593 -0.839099631
320 -0.642787610 0.766044443 -0.839099631 -1.191753593
330 -0.500000000 0.866025404 -0.577350269 -1.732050808
340 -0.342020143 0.939692621 -0.363970234 -2.747477419
350 -0.173648178 0.984807753 -0.176326981 -5.671281820
Note the disparity between signs on the infinities and forced zeros. While both 0 / 1
and 0 / -1
can be treated as zero (there are no negative zeros despite the fact IEEE754 allows them), the values for 1 / 0
and -1 / 0
are given +inf
and -inf
respectively.
My more advanced mathematical buddies may disagree but I think I've got that right.