new version of SINE

This commit is contained in:
Perry Kivolowitz 2023-04-06 18:47:47 -05:00
parent 902fb172af
commit 664e952785
3 changed files with 74 additions and 36 deletions

View file

@ -17,7 +17,9 @@ sin x = x - x^3/3! + x^5/5! - x^7/7! ...
Notice each term flips from addition to subtraction.
Notice each term is based on the odd integers starting at 1.
Notice each term is based on the odd integers starting at 1. While the
"1" case might look different, it is the same as all the others since
1 is just 1 to the first power divided by 1 factorial.
## Command line
@ -29,40 +31,76 @@ arguments are therefore required.
be a double.
* The number of terms to evaluate. The number of terms must lie between
1 and 10 inclusive.
1 and 10 inclusive. Note the value of 10 as an upper bound in new. It
was 8.
## C version
To assist your efforts, [here](./c_version.c) is a version of this
project written in C.
project written in C. This has been updated to print nice debugging
output which is not part of the project.
## Errors to stderr
Error messages must be sent to `stderr`.
If you are using the convergence macros to allow your program to build
on both Apple Silicon Mac OS and Linux, note the special casing needed
to deal with `stderr`. If this is you, compile the C version on Mac OS
with the `-S` compiler option to see the generated assembly language and
search for `stderr`.
This C version also demonstrates a different way of calculating the
toggle. This version flips the sign of the toggle by multiplying by -1.
The previous version used odd and even values of the term.
## Sample executions
```text
SINE % ./a.out 0 8
The sine of 0.00 degrees is 0.000000 in radians.
SINE % ./a.out 90 8
The sine of 90.00 degrees is 1.000000 in radians.
SINE % ./a.out 180 8
The sine of 180.00 degrees is -0.000001 in radians.
SINE % ./a.out 180 82
pk_taylor_series > gcc main.S -o a
pk_taylor_series > ./a 0 10
The sine of 0.00 degrees is 0.00000000.
pk_taylor_series > ./a 30 10
The sine of 30.00 degrees is 0.50000000.
pk_taylor_series > ./a 45 10
The sine of 45.00 degrees is 0.70710678.
pk_taylor_series > ./a 90 10
The sine of 90.00 degrees is 1.00000000.
pk_taylor_series > ./a 180 10
The sine of 180.00 degrees is -0.00000000.
pk_taylor_series > ./a 360 10
The sine of 360.00 degrees is -0.00104818.
pk_taylor_series > ./a 360 100
Number of terms is out of range.
SINE % ./a.out 180 -10
pk_taylor_series > ./a 360 -1
Number of terms is out of range.
SINE % echo $?
1
pk_taylor_series >
```
## Floating point instructions I used
These are the floating point instructions I used in my implementation.
* fmov
* scvtf
* fmul
* fdiv
* fadd
## How I broke up the program
I have functions named:
* main
* HandleOptions
* Factorial
* IntegerPower - x to the nth power
* ComputeSine - The main calculation
* PrintAnswer
* ConvertTheta - Wrap D2R
* D2R - Degrees to radians
## CSC3510
The following applies to Carthage College CSC3510 students.
@ -74,4 +112,3 @@ Work is to be done solo.
### What to hand in
Just the .S file. **Your name must be at the top of the file.**

Binary file not shown.

View file

@ -1,13 +1,14 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double pi = 3.14159265359;
double pi = 3.14159265358979323846;
double D2R(double d) {
return d * pi / 180.0;
}
long Factorial(int n) {
double Factorial(int n) {
long retval = 1;
if (n > 0) {
@ -15,7 +16,7 @@ long Factorial(int n) {
retval = retval * n--;
}
}
return retval;
return (double) retval;
}
double IntegerPower(double b, int e) {
@ -48,20 +49,20 @@ int main(int argc, char ** argv) {
double r_angle = D2R(angle);
double toggle = 1.0;
for (int term = 0, base = 1; term < terms; term++, base += 2) {
double toggle = (term & 1) ? -1.0 : 1.0;
if (toggle > 0) {
printf("%+03.8e + %+03.8e / %+03.8e [term %2d is %+03.8e]\n", sin, IntegerPower(r_angle, base),
Factorial(base), term + 1, toggle * IntegerPower(r_angle, base) / Factorial(base));
} else {
printf("%+03.8e - %+03.8e / %+03.8e [term %2d is %+03.8e]\n", sin, IntegerPower(r_angle, base),
Factorial(base), term + 1, toggle * IntegerPower(r_angle, base) / Factorial(base));
}
sin += toggle *
IntegerPower(r_angle, base) / Factorial(base);
/*
if (toggle > 0) {
printf("adding %d p/b intermediate: %f\n", base, sin);
} else {
printf("subtracting %d p/b intermediate: %f\n", base, sin);
}
*/
toggle = toggle * -1;
}
printf("The sine of %.2f degrees is %f in radians.\n", angle, sin);
printf("The sine of %0.4f degrees is %0.10f.\n", angle, sin);
return 0;
}