Calculating sine to full precision of given fixed point type, when to stop?
I'm writing a sine implementation for my own fixedpoint library without using precomputed tables or library functions, so just basic mathematical operations (add, subtract, multiply, divide). I want to calculate this sine value to the full precision of whatever fixed point type the result is in, e.g. one with 16 fractional bits.
As far as I know the Taylor series is the only way of doing this, and it gets more precise the more terms I add, but how do I determine when to stop adding terms? Is it enough to just check if the next term would be smaller than the target precision? Is it even practical to use the Taylor series in this way or do I need to use something else?
I'm using C and want to make the number of fractional bits of my fixedpoint type (or types) configurable, which is why I need to be able to generalize my stopping condition in this way.
1 answer

Following is not a fixed point solution, but a floating point one. So it may provide insight for a fixed point one.
It does use a library function
remainder()
for range reduction, but that could also be replaced once detailed coding goals are expressed.It uses recursion to add the smaller terms together first. With higher precision floating point, this may make for a deep stack excursion.
The recursion termination here is a test with 1.0, which makes sense for floating point. I'd expect a compare against an epsilon for fixed point.
static double sin_r_helper(double term, double xx, unsigned i) { if (1.0 + term == 1.0) return term; return term  sin_r_helper(term * xx / ((i + 1) * (i + 2)), xx, i + 2); } double sin_r(double x /* radians */) { x = remainder(x, 2 * M_PI); return x * sin_r_helper(1.0, x * x, 1); }
See also questions close to this topic

HTTP request to log into email
I would like to write a program, that would log into my email account automaticly. I have already built the sockets etc, but now I need to know how to write my http request. I have also tried reading my own web requests using the developer tools in my browser, but that did not work. I am asking for either a full example request or a way to find out how to write my own.

C Reversi Program, Loop stops iterating in the middle
I am trying to program a game somewhat like Reversi. However I am having great difficulty getting my game loop to work! (Referring to the do while loop in the main function).My code refuses to iterate properly and ask the user for his second move. (Note the code and output doesn't include the AI making move as it is not related to this problem).
As you can see from this output, it outputs Test spot 1 but doesn't reach test spot 2 even though the only code separating them is variable decelerations. Output
Code where problem is occuring (main function):
int main(void) { int n; int p; char oppChar; char playChar; int i; int pTurn; int deltaRow; int deltaCol; int endGame = 999; printf("Enter the board dimension: "); scanf("%d",&n); printf("Computer plays (B/W) "); scanf(" %c",&oppChar); if (oppChar == 'B'){ pTurn = 0; playChar = 'W'; } else { pTurn = 1; playChar = 'B';} char board [n][26]; int movesAvalB[n][26]; int movesAvalW[n][26]; int AIBoard[n][26]; for (i = 0;i < n;i++){ for (p = 0; p < n; p++){ board [i][p] = 'U'; }} board [(n/2)1][(n/2)1] = 'W'; board [(n/2)1][(n/2)] = 'B'; board [(n/2)][(n/2)1] = 'B'; board [n/2][n/2] = 'W'; printBoard(board,n); printf(" \n"); int q = 0; do { q++; //testing printf("Turn Number %d ",pTurn); printf("Test Spot 1"); printf("\n"); //variable decleration int k= 0; int y = 0; int x = 0; int max = 0; int temp = 0; char c[3] = " "; printf("Test Spot 2"); //arrays are all 0 for (i = 0;i < n;i++){ for(p = 0; p < 26;p++){ AIBoard[i][p] = 0; movesAvalB[i][p]=0; movesAvalW[i][p]=0;}} //moves avaliable to W for (y = 0;y < n;y++){ for(x = 0;x < n;x++){ if(moves(n,x,y,board,'W')){ movesAvalW[y][x] = 1;}}} //moves avaliable to B for (y = 0;y < n;y++){ for(x = 0;x < n;x++){ if(moves(n,x,y,board,'B')){ movesAvalB[y][x] = 1;}}} //pTurn = pTurn%2; printf("Enter a move for colour %c (RowCol): ",playChar); scanf("%s",&c); if (positionInBounds(n,c[0],c[1])){ int y = c[0]  97; int x = c[1]  97; if (playChar == 'B'){ if (movesAvalB[y][x] == 1){ for (deltaRow = 1;deltaRow <= 1;deltaRow++){ for (deltaCol = 1;deltaCol <= 1;deltaCol++){ if(positionIntBounds(n,(x+deltaRow),(y+deltaCol))){ i = 1; while((positionIntBounds(n,(y+(i*deltaRow)),(x+(i*deltaCol)))) && (board[y+(i*deltaRow)][x+(i*deltaCol)] == 'W')){ i++; if((positionIntBounds(n,(y+(i*deltaRow)),(x+(i*deltaCol)))) && (board[y+(i*deltaRow)][x+(i*deltaCol)] == 'B')){ while (i != 0){i; board[y+(i*deltaRow)][x+(i*deltaCol)] = 'B';} }}}}} for (deltaRow = 1;deltaRow <= 1;deltaRow++){ for (deltaCol = 1;deltaCol <= 1;deltaCol++){ if (board[y+deltaRow][x+deltaCol] == 'W'){ board[y+deltaRow][x+deltaCol] == 'B';}}} printBoard(board,n); } else{ printf("Invalid Move."); }} if (playChar == 'W'){ if (movesAvalW[y][x] == 1){ for (deltaRow = 1;deltaRow <= 1;deltaRow++){ for (deltaCol = 1;deltaCol <= 1;deltaCol++){ if(positionIntBounds(n,(x+deltaRow),(y+deltaCol))){ i = 1; while((positionIntBounds(n,(y+(i*deltaRow)),(x+(i*deltaCol)))) && (board[y+(i*deltaRow)][x+(i*deltaCol)] == 'B')){ i++; if((positionIntBounds(n,(y+(i*deltaRow)),(x+(i*deltaCol)))) && (board[y+(i*deltaRow)][x+(i*deltaCol)] == 'W')){ while (i != 0){i; board[y+(i*deltaRow)][x+(i*deltaCol)] = 'W';} }}}}} for (deltaRow = 1;deltaRow <= 1;deltaRow++){ for (deltaCol = 1;deltaCol <= 1;deltaCol++){ if (board[y+deltaRow][x+deltaCol] == 'B'){ board[y+deltaRow][x+deltaCol] == 'W';}}} printBoard(board,n);} else{ printf("Invalid Move."); }}} else { printf("Invalid Move."); } pTurn++; } while (q <= 5); printf("were out"); }
Secondary functions, i dont think the problem is here but i might aswell include.
void printBoard(char board[][26], int n){ int i; char alpha[27] = "abcdefghijklmnopqrstuvwxyz"; printf(" "); for (i = 0;i < n;i++){ printf("%c", alpha[i]); } int p; int q; for (p = 0;p < n;p++){ printf("\n"); printf("%c", alpha[p]); for (q = 0;q < n;q++){ printf("%c",board[p][q]); } } } bool positionInBounds(int n, char row, char col){ int p = row  97; int d = col  97; if (p > n){ return false;} if (d > n){ return false;} if (0 > p){ return false;} if (0 > d){ return false;} return true; } bool positionIntBounds(int n, int row, int col){ if (row > n){ return false;} if(col > n){ return false;} if(0 > row){ return false;} if(0 > col){ return false;} return true; } bool checkLegalInDirection(char board[][26], int n, char row, char col, char colour,int deltaRow, int deltaCol){ int i = 0; while((positionIntBounds(n,(row+(i*deltaRow)),(col+(i*deltaCol)))) && (board[row+(i*deltaRow)][col+(i*deltaCol)] != colour) && (board[row+(i*deltaRow)][col+(i*deltaCol)] != 'U')){ i++; if((positionIntBounds(n,(row+(i*deltaRow)),(col+(i*deltaCol)))) && (board[row+(i*deltaRow)][col+(i*deltaCol)] == colour)){ return true;}} return false; } bool moves(int n,int x, int y, char board[][26],char colour) { int deltaRow; int deltaCol; if(board[y][x] == 'U'){ for (deltaRow = 1;deltaRow <= 1;deltaRow++){ for (deltaCol = 1;deltaCol <= 1;deltaCol++){ if(positionIntBounds(n,(x+deltaRow),(y+deltaCol))){ if(checkLegalInDirection(board,n,(x + deltaRow),(y + deltaCol),colour,deltaRow,deltaCol)){ return true; }}}}} return false; }
if you help me you are a lifesaver im pulling my hair out!

Using od command
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(int argc, char* argv[]) { char *filename = argv[1]; char *store = malloc(2); FILE *fh = fopen(filename, "wb"); for(int i = 0; i < 100; i++) { sprintf(store, "%u", i); if (fh != NULL) { fwrite (store, sizeof (store), 1, fh); } } fclose (fh); return 0; }
I want my output to look like this > https://imgur.com/a/nt2ly. The output it produces currently is all garabge.

How to generate a horizontal sinusoidal text in C without graphics.h?
I am trying to write a program on generating a sinusoidal text in C. I tried the code below and got a vertical sine wave. Is it possible to make it horizontal? I am new to C programming, so if you could, please explain the code in simplest manner. Thank you!
#include <stdio.h> #include <math.h> int main() { // declarations int x; char y[80]; char str[] = "This is a test string"; // setting entire array to spaces for(x = 0; x < 79; x++) y[x] = ' '; y[79] = '\0'; // print 20 lines, for one period (2 pi radians) for(x = 0; str[x]!='\0'; x++) { y[40 + (int) (40 * sin(M_PI * (float) x /10))] = str[x]; printf("%s\n", y); y[40 + (int) (40 * sin(M_PI * (float) x / 10))] = ' '; } // exit return 0; }
Output:
T h i s s a t e s t s t r i n g
Is it possible to make the wave horizontal without changing the existing code? Thank you!
 Generating sine wave using Xilinx blockset in Matlab

Generating lower frequency sine wave using numpy.array
I've been looking for an effective way to generate a sine wave sound in pygame, but my code is very picky about what can work without interrupting the wave. The code from this previous question: error when playing sine wave via pygame.sndarray
wave = numpy.array([[1,1], [2,2], [3,3]], dtype="int8") # default pygame.sndarray.make_sound(wave)
Is the only one I've come across that works. But the sound it generates is extremely high pitched. I don't understand what's happening with the values, could someone please explain to me what the
[1,1], [2,2], [3,3]]
values do, and how I can change them to create a lower frequency sound? 
How approximate sinus using Taylor series
I need to approximate sinus function without internal libraries. I used Taylor series in 0 to solve this, but my program works for some values, but for others awful results. The program gets x value, unit (degrees or radians) and how many words we want use for the approximation. For values like
1 rad, 5 words results are ok: sin(1 pi) = 0.833333 Difference: 0.00813765;
sin(0.5 pi) = 0.479167 Difference: 0.000258872
But for values like 125.6 rad it returns 2.60145e+008 and C++ sin() function gives 0.0636631, so the result is completely unreal.
Also it doesn't work for values in degrees although I convert degrees on radians. E.g. sin(4.71239 pi) = 6.63667 and real result should be 1. I completely don't have any idea why it doesn't work properly, could anyone tell me what could cause these problems?
#include <iostream> #include <math.h> #ifndef M_PI #define M_PI 3.14159265358979323846 #endif using namespace std; double degConverter(double); void approximate(double, int, int); double compareWithNorm(double, double); double inline reductionFormula(double); double inline degConverter(double x) { return x * M_PI / 180.0; } void approximate(double x, int unit, int words) { double result = 0; double xVal = 0; int factorial = 1; x = reductionFormula(x); if (unit == 1) { xVal = x; } else if (unit == 0) { xVal = degConverter(x); x = xVal; } if (words > 1) { for (int i = 1; i < words; i++) { switch (i % 4) { case 1: result += xVal / (double)silnia; break; case 3: result = xVal / (double)silnia; break; } xVal *= x; factorial *= i + 1; } } //Comparing with sin() function from math.h lib cout << "Difference between sin C++ and Taylor: " << compareWithNorm(x, result) << endl; } double compareWithNorm(double x, double result) { double diff = 0; double pattern = sin(x); diff = pattern  result; if (diff < 0) diff *= 1; return diff; } double inline reductionFormula(double x) { if (x > 2) { x = fmod(x, 2.0 * M_PI); } return x; } int main() { double x; int unit = 1; int words = 1; cout << "Type x [degrees / rad]: "; cin >> x; cout << "\nType unit [deg = 0 / rad = 1]: "; cin >> unit; cout << "\nHow many words?: "; cin >> words; cout << endl; approximate(x, unit, words); return 0; }

modelling an infinite series in R
I'm trying to write a code to approximate the following infinite Taylor series from the Theis hydrogeological equation in R.
I'm pretty new to functional programming, so this was a challenge! This is my attempt:
Wu < function(u, repeats = 100) { result < numeric(repeats) for (i in seq_along(result)){ result[i] < ((u)^i)/(i * factorial(i)) } return(sum(result)  log(u)0.5772) }
I've compared the results with values from a data table available here: https://pubs.usgs.gov/wsp/wsp1536E/pdf/wsp_1536E_b.pdf  see below (excuse verbose code  should have made a csv, with hindsight):
Wu_QC < data.frame(u = c(1.0*10^15, 4.1*10^14,9.9*10^13, 7.0*10^12, 3.7*10^11, 2.3*10^10, 6.8*10^9, 5.7*10^8, 8.4*10^7, 6.3*10^6, 3.1*10^5, 7.4*10^4, 5.1*10^3, 2.9*10^2,8.7*10^1, 4.6,9.90), Wu_table = c(33.9616, 30.2480, 27.0639, 25.1079, 23.4429, 21.6157, 18.2291, 16.1030, 13.4126, 11.3978, 9.8043,6.6324, 4.7064,2.9920,0.2742, 0.001841,0.000004637)) Wu_QC$rep_100 < Wu(Wu_QC$u,100)
The good news is the formula gives identical results for repeats = 50, 100, 150 and 170 (so I've just given you the 100 version above). The bad news is that, while the function performs well for u < ~10^3, it goes off the rails and gives negative outputs for numbers within an order of magnitude or so of 1. This doesn't happen when I just call the function on an individual number. i.e:
> Wu(4.6) [1] 0.001856671
Which is the correct answer to 2sf.
Can anyone spot what I've done wrong and/or suggest a better way to code this equation? I think the problem is something to do with my for loop and/or an issue with the factorials generating infinite numbers as u gets larger, but I'm not at all certain.
Thanks!

Creating a custom sine function
I tried to create a custom
sine
function usingc
and the Taylor Series for calculatingsin
with 10 terms in the series, but I'm getting the wrong results when I try to find thesine(x)
wherex > 6
.It works well for
5 < x < 5
, but anything out of that range isn't producing the correct results.I expect
sin(10)
to return something close to0.5440
, but get1418.0269775391
I've put everything in a single file so it's easier.
#include <stdio.h> #include <stdlib.h> double factorial(double n); double power(double n, double pow); double sine(double n); // This is supposed to all go in a .c file and reference the .h stuff above // This is the actual implementation of the functions declared above double factorial(double n) { // 0! = 1 so just return it if(n == 0) { return 1; } // Recursively call factorial with n1 until n == 0 return n * (factorial(n  1)); } double power(double n, double power) { double result = n; // Loop as many times as the power and just multiply itself power amount of times for(int i = 1; i < power; i++) { result = n * result; } return result; } double sine(double n) { double result = n; double coefficent = 3; // Increment this by 2 each loop for(int i = 0; i < 10; i++) { // Change 10 to go out to more/less terms double pow = power(n, coefficent); double frac = factorial(coefficent); printf("Loop %d:\n%2.3f ^ %2.3f = %2.3f\n", i, n, coefficent, pow); printf("%2.3f! = %2.3f\n", coefficent, frac); // Switch between adding/subtracting if(i % 2 == 0) { // If the index of the loop is divided by 2, the index is even, so subtract result = result  (pow/frac); // x  ((x^3)/(3!))  ((x^5)/(5!))... } else { result = result + (pow/frac); // x  ((x^3)/(3!)) + ((x^5)/(5!))... } coefficent = coefficent + 2; printf("Result = %2.3f\n\n", result); } return result; } // main starting point. This is suppossed to #include "functions.c" which contain the above functions in it int main(int argc, char** argv) { double number = atof(argv[1]); // argv[1] = "6" double sineResult = sine(number); printf("%1.10f", sineResult); return (0); }