What should I change so that my arctan(x) approximation can display x=1 and x=-1 properly?












-1














One of my C assignments was it to write an approximation of arctan(x) in the language C. The equation which I should base it on is



arctan(x)=sum {k=0}^{infty }(-1)^{k} tfrac{x^{2k+1}}{2k+1}



enter image description here



In addition x is only defined as -1<=x<=1.



Here is my code.



#include <stdio.h>
#include <math.h>


double main(void) {

double x=1;
double k;
double sum;
double sum_old;
int count;

double pw(double y, double n) {
double i;
double number = 1;

for (i = 0; i < n; i++) {
number *= y;
}
return(number);
}

double fc (double y) {
double i;
double number = 1;

for (i = 1; i <= y; i++){
number *= i;
}
return(number);
}

if(x >= (-1) && x <= 1) {
for(k=0; sum!=sum_old; k++) {
sum_old = sum;
sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
count++;

printf("%d || %.17lfn", count, sum);
}



printf("My result is: %.17lfn",sum);
printf("atan(%f) is: %.17fn", x, atan(x));
printf("My result minus atan(x) = %.17lfn", sum - atan(x));
} else {
printf("x is not defined. Please choose an x in the intervall [-1, 1]n");
}



return 0;
}


It seemingly works fine with every value, except value 1 and -1. If x=1, then the output ends with:



...
7207 || 0.78543285189457468
7208 || 0.78536


Whereas the output should look more like this. In this case x=0.5.



25 || 0.46364760900080587
26 || 0.46364760900080587
My result is: 0.46364760900080587
atan(0.500000) is: 0.46364760900080609
My result minus atan(x) atan(x) = -0.00000000000000022


How can I improve my code so that it can run with x=1 and x=-1.



Thanks in advance.



PS: I use my own created pw() function instead of pow(), because I wanted to bybass the restriction of not using pow() as we didn't had that in our lectures yet.



PPS: I'd appreciate any advice as to how to improve my code.










share|improve this question
























  • Why are you defining functions within main?
    – Fiddling Bits
    Nov 19 '18 at 20:50






  • 1




    @Arhama I have not seen C functions declared inside main like that, looks like java to me. Prototype all your functions at the top of the file and define then at the bottom, thats normally how we do it. I suppose what you have is fine assuming it works, it just makes main harder to read imo.
    – Bwebb
    Nov 19 '18 at 20:51












  • @Bwebb Apparently, GCC (for example) is a C language extension and allows nested functions. I didn't know that it was still legal.
    – Fiddling Bits
    Nov 19 '18 at 20:53












  • What is x=1 and x=-1 supposed to output? I looked up the graph and is seems close enough, whats the problem exactly? The number of iterations it takes?
    – Bwebb
    Nov 19 '18 at 20:55






  • 1




    It is wasteful to compute pw from scratch every time. Instead, remember the factors in the term (-1^k and x^(2k+1)) and just update them in each iteration.
    – Eric Postpischil
    Nov 19 '18 at 21:16
















-1














One of my C assignments was it to write an approximation of arctan(x) in the language C. The equation which I should base it on is



arctan(x)=sum {k=0}^{infty }(-1)^{k} tfrac{x^{2k+1}}{2k+1}



enter image description here



In addition x is only defined as -1<=x<=1.



Here is my code.



#include <stdio.h>
#include <math.h>


double main(void) {

double x=1;
double k;
double sum;
double sum_old;
int count;

double pw(double y, double n) {
double i;
double number = 1;

for (i = 0; i < n; i++) {
number *= y;
}
return(number);
}

double fc (double y) {
double i;
double number = 1;

for (i = 1; i <= y; i++){
number *= i;
}
return(number);
}

if(x >= (-1) && x <= 1) {
for(k=0; sum!=sum_old; k++) {
sum_old = sum;
sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
count++;

printf("%d || %.17lfn", count, sum);
}



printf("My result is: %.17lfn",sum);
printf("atan(%f) is: %.17fn", x, atan(x));
printf("My result minus atan(x) = %.17lfn", sum - atan(x));
} else {
printf("x is not defined. Please choose an x in the intervall [-1, 1]n");
}



return 0;
}


It seemingly works fine with every value, except value 1 and -1. If x=1, then the output ends with:



...
7207 || 0.78543285189457468
7208 || 0.78536


Whereas the output should look more like this. In this case x=0.5.



25 || 0.46364760900080587
26 || 0.46364760900080587
My result is: 0.46364760900080587
atan(0.500000) is: 0.46364760900080609
My result minus atan(x) atan(x) = -0.00000000000000022


How can I improve my code so that it can run with x=1 and x=-1.



Thanks in advance.



PS: I use my own created pw() function instead of pow(), because I wanted to bybass the restriction of not using pow() as we didn't had that in our lectures yet.



PPS: I'd appreciate any advice as to how to improve my code.










share|improve this question
























  • Why are you defining functions within main?
    – Fiddling Bits
    Nov 19 '18 at 20:50






  • 1




    @Arhama I have not seen C functions declared inside main like that, looks like java to me. Prototype all your functions at the top of the file and define then at the bottom, thats normally how we do it. I suppose what you have is fine assuming it works, it just makes main harder to read imo.
    – Bwebb
    Nov 19 '18 at 20:51












  • @Bwebb Apparently, GCC (for example) is a C language extension and allows nested functions. I didn't know that it was still legal.
    – Fiddling Bits
    Nov 19 '18 at 20:53












  • What is x=1 and x=-1 supposed to output? I looked up the graph and is seems close enough, whats the problem exactly? The number of iterations it takes?
    – Bwebb
    Nov 19 '18 at 20:55






  • 1




    It is wasteful to compute pw from scratch every time. Instead, remember the factors in the term (-1^k and x^(2k+1)) and just update them in each iteration.
    – Eric Postpischil
    Nov 19 '18 at 21:16














-1












-1








-1







One of my C assignments was it to write an approximation of arctan(x) in the language C. The equation which I should base it on is



arctan(x)=sum {k=0}^{infty }(-1)^{k} tfrac{x^{2k+1}}{2k+1}



enter image description here



In addition x is only defined as -1<=x<=1.



Here is my code.



#include <stdio.h>
#include <math.h>


double main(void) {

double x=1;
double k;
double sum;
double sum_old;
int count;

double pw(double y, double n) {
double i;
double number = 1;

for (i = 0; i < n; i++) {
number *= y;
}
return(number);
}

double fc (double y) {
double i;
double number = 1;

for (i = 1; i <= y; i++){
number *= i;
}
return(number);
}

if(x >= (-1) && x <= 1) {
for(k=0; sum!=sum_old; k++) {
sum_old = sum;
sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
count++;

printf("%d || %.17lfn", count, sum);
}



printf("My result is: %.17lfn",sum);
printf("atan(%f) is: %.17fn", x, atan(x));
printf("My result minus atan(x) = %.17lfn", sum - atan(x));
} else {
printf("x is not defined. Please choose an x in the intervall [-1, 1]n");
}



return 0;
}


It seemingly works fine with every value, except value 1 and -1. If x=1, then the output ends with:



...
7207 || 0.78543285189457468
7208 || 0.78536


Whereas the output should look more like this. In this case x=0.5.



25 || 0.46364760900080587
26 || 0.46364760900080587
My result is: 0.46364760900080587
atan(0.500000) is: 0.46364760900080609
My result minus atan(x) atan(x) = -0.00000000000000022


How can I improve my code so that it can run with x=1 and x=-1.



Thanks in advance.



PS: I use my own created pw() function instead of pow(), because I wanted to bybass the restriction of not using pow() as we didn't had that in our lectures yet.



PPS: I'd appreciate any advice as to how to improve my code.










share|improve this question















One of my C assignments was it to write an approximation of arctan(x) in the language C. The equation which I should base it on is



arctan(x)=sum {k=0}^{infty }(-1)^{k} tfrac{x^{2k+1}}{2k+1}



enter image description here



In addition x is only defined as -1<=x<=1.



Here is my code.



#include <stdio.h>
#include <math.h>


double main(void) {

double x=1;
double k;
double sum;
double sum_old;
int count;

double pw(double y, double n) {
double i;
double number = 1;

for (i = 0; i < n; i++) {
number *= y;
}
return(number);
}

double fc (double y) {
double i;
double number = 1;

for (i = 1; i <= y; i++){
number *= i;
}
return(number);
}

if(x >= (-1) && x <= 1) {
for(k=0; sum!=sum_old; k++) {
sum_old = sum;
sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
count++;

printf("%d || %.17lfn", count, sum);
}



printf("My result is: %.17lfn",sum);
printf("atan(%f) is: %.17fn", x, atan(x));
printf("My result minus atan(x) = %.17lfn", sum - atan(x));
} else {
printf("x is not defined. Please choose an x in the intervall [-1, 1]n");
}



return 0;
}


It seemingly works fine with every value, except value 1 and -1. If x=1, then the output ends with:



...
7207 || 0.78543285189457468
7208 || 0.78536


Whereas the output should look more like this. In this case x=0.5.



25 || 0.46364760900080587
26 || 0.46364760900080587
My result is: 0.46364760900080587
atan(0.500000) is: 0.46364760900080609
My result minus atan(x) atan(x) = -0.00000000000000022


How can I improve my code so that it can run with x=1 and x=-1.



Thanks in advance.



PS: I use my own created pw() function instead of pow(), because I wanted to bybass the restriction of not using pow() as we didn't had that in our lectures yet.



PPS: I'd appreciate any advice as to how to improve my code.







c loops for-loop math types






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 19 '18 at 20:54









davedwards

5,22021132




5,22021132










asked Nov 19 '18 at 20:43









ArhamaArhama

1




1












  • Why are you defining functions within main?
    – Fiddling Bits
    Nov 19 '18 at 20:50






  • 1




    @Arhama I have not seen C functions declared inside main like that, looks like java to me. Prototype all your functions at the top of the file and define then at the bottom, thats normally how we do it. I suppose what you have is fine assuming it works, it just makes main harder to read imo.
    – Bwebb
    Nov 19 '18 at 20:51












  • @Bwebb Apparently, GCC (for example) is a C language extension and allows nested functions. I didn't know that it was still legal.
    – Fiddling Bits
    Nov 19 '18 at 20:53












  • What is x=1 and x=-1 supposed to output? I looked up the graph and is seems close enough, whats the problem exactly? The number of iterations it takes?
    – Bwebb
    Nov 19 '18 at 20:55






  • 1




    It is wasteful to compute pw from scratch every time. Instead, remember the factors in the term (-1^k and x^(2k+1)) and just update them in each iteration.
    – Eric Postpischil
    Nov 19 '18 at 21:16


















  • Why are you defining functions within main?
    – Fiddling Bits
    Nov 19 '18 at 20:50






  • 1




    @Arhama I have not seen C functions declared inside main like that, looks like java to me. Prototype all your functions at the top of the file and define then at the bottom, thats normally how we do it. I suppose what you have is fine assuming it works, it just makes main harder to read imo.
    – Bwebb
    Nov 19 '18 at 20:51












  • @Bwebb Apparently, GCC (for example) is a C language extension and allows nested functions. I didn't know that it was still legal.
    – Fiddling Bits
    Nov 19 '18 at 20:53












  • What is x=1 and x=-1 supposed to output? I looked up the graph and is seems close enough, whats the problem exactly? The number of iterations it takes?
    – Bwebb
    Nov 19 '18 at 20:55






  • 1




    It is wasteful to compute pw from scratch every time. Instead, remember the factors in the term (-1^k and x^(2k+1)) and just update them in each iteration.
    – Eric Postpischil
    Nov 19 '18 at 21:16
















Why are you defining functions within main?
– Fiddling Bits
Nov 19 '18 at 20:50




Why are you defining functions within main?
– Fiddling Bits
Nov 19 '18 at 20:50




1




1




@Arhama I have not seen C functions declared inside main like that, looks like java to me. Prototype all your functions at the top of the file and define then at the bottom, thats normally how we do it. I suppose what you have is fine assuming it works, it just makes main harder to read imo.
– Bwebb
Nov 19 '18 at 20:51






@Arhama I have not seen C functions declared inside main like that, looks like java to me. Prototype all your functions at the top of the file and define then at the bottom, thats normally how we do it. I suppose what you have is fine assuming it works, it just makes main harder to read imo.
– Bwebb
Nov 19 '18 at 20:51














@Bwebb Apparently, GCC (for example) is a C language extension and allows nested functions. I didn't know that it was still legal.
– Fiddling Bits
Nov 19 '18 at 20:53






@Bwebb Apparently, GCC (for example) is a C language extension and allows nested functions. I didn't know that it was still legal.
– Fiddling Bits
Nov 19 '18 at 20:53














What is x=1 and x=-1 supposed to output? I looked up the graph and is seems close enough, whats the problem exactly? The number of iterations it takes?
– Bwebb
Nov 19 '18 at 20:55




What is x=1 and x=-1 supposed to output? I looked up the graph and is seems close enough, whats the problem exactly? The number of iterations it takes?
– Bwebb
Nov 19 '18 at 20:55




1




1




It is wasteful to compute pw from scratch every time. Instead, remember the factors in the term (-1^k and x^(2k+1)) and just update them in each iteration.
– Eric Postpischil
Nov 19 '18 at 21:16




It is wasteful to compute pw from scratch every time. Instead, remember the factors in the term (-1^k and x^(2k+1)) and just update them in each iteration.
– Eric Postpischil
Nov 19 '18 at 21:16












4 Answers
4






active

oldest

votes


















1














In each iteration, you add (-1)kx2k+1 / (2k+1), and you stop when there is no change to the sum.



If this were calculated with ideal arithmetic (exact, infinitely precise arithmetic), it would never stop for non-zero x, since you are always changing the sum. When calculating with fixed-precision arithmetic, it stops when the term is so small it does not change the sum because of the limited precision.



When |x| is less than one by any significant amount, this comes quickly because x2k+1 gets smaller. When |x| is one, the term becomes just 1 / (2k+1), which gets smaller very slowly. Not until k is around 253 would the sum stop changing.



You might consider changing your stopping condition to be when sum has not changed from sum_old very much rather than when it has not changed at all.






share|improve this answer





























    0














    if(x >= (-1) && x <= 1) {
    for(k=0; sum!=sum_old; k++) {
    sum_old = sum;
    sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
    count++;

    printf("%d || %.17lfn", count, sum);
    }


    Comparing doubles can be tricky. The conventional way to compare doubles is to test within epsilon. There should be an epsilon value defined somewhere, but for your purposes how many digits are enough to approximate? If you only need like 3 or 4 digits you can instead have



    #define EPSILON 0.0001 //make this however precise you need to approximate.

    if(x >= (-1) && x <= 1) {
    for(k=0; fabs(sum - sum_old) > EPSILON; k++) {
    sum_old = sum;
    sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
    count++;

    printf("%d || %.17lfn", count, sum);
    }


    If the issue is that -1,1 iterate too many times either reduce the precision or increase the step per iteration. I am not sure that is what you're asking though, please clarify.






    share|improve this answer





























      0














      I think the cause of this is for a mathematical reason rather than a programming one.



      Away from the little mistakes and adjustments that you should do to your code, putting x = 1 in the infinite series of arctan, is a boundary condition:
      arctan infinite series
      In this series, we add a negative value to a positive value then a negative value. This means the sum will be increasing, decreasing, increasing, ... and this will make some difference each iteration. This difference will be smaller until the preciseness of double won't catch it, so the program will stop and give us the value.



      But in the sum equation. When we set z = 1 and n goes from 0 to ∞, this will make this term (-1^n) equal to 1 in one time and -1 in the next iteration. Also,
      the value of the z-term will be one and the denominator value when n approaches infinity will = ∞ .



      So the sum several iterations will be like +1/∞ -1/∞ +1/∞ -1/∞ ... (where ∞ here represents a big number). That way the series will not reach a specific number. This is because z = 1 is a boundary in this equation. And that is causing infinite iterations in your solution without reaching a number.



      If you need to calculate arctan(1) I think you should use this formula:arctan 2



      All formulas are from this Wikipedia article.






      share|improve this answer































        0














        Here is some modifications that make your code more compact and has less errors:



        #include <stdio.h>
        #include <math.h>

        #define x 0.5 //here x is much easier to change

        double pw(double, double); //declaration of the function should be done

        int main() { //the default return type of main is int.

        double k;
        double sum = 0 ; //you should initiate your variables.
        double sum_old = 1 ; //=1 only to pass the for condition first time.
        //you don't need to define counter here
        if(x < -1 || x > 1){
        printf("x is not defined. Please choose an x in the interval [-1, 1]n");
        return 0;
        }
        for(k=0; sum!=sum_old; k++) {
        sum_old = sum;
        sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
        printf("%.0f || %.17lfn", k, sum);
        }

        printf("My result is: %.17lfn",sum);
        printf("atan(%f) is: %.17fn", x, atan(x));
        printf("My result minus atan(x) = %.17lfn", sum - atan(x));

        return 0;
        }

        double pw(double y, double n) { //functions should be declared out of the main function
        double i;
        double number = 1;

        for (i = 0; i < n; i++) {
        number *= y;
        }
        return(number);
        }

        double fc (double y) {
        double i;
        double number = 1;

        for (i = 1; i <= y; i++){
        number *= i;
        }
        return(number);
        }





        share|improve this answer





















          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53382349%2fwhat-should-i-change-so-that-my-arctanx-approximation-can-display-x-1-and-x-1%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          4 Answers
          4






          active

          oldest

          votes








          4 Answers
          4






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          In each iteration, you add (-1)kx2k+1 / (2k+1), and you stop when there is no change to the sum.



          If this were calculated with ideal arithmetic (exact, infinitely precise arithmetic), it would never stop for non-zero x, since you are always changing the sum. When calculating with fixed-precision arithmetic, it stops when the term is so small it does not change the sum because of the limited precision.



          When |x| is less than one by any significant amount, this comes quickly because x2k+1 gets smaller. When |x| is one, the term becomes just 1 / (2k+1), which gets smaller very slowly. Not until k is around 253 would the sum stop changing.



          You might consider changing your stopping condition to be when sum has not changed from sum_old very much rather than when it has not changed at all.






          share|improve this answer


























            1














            In each iteration, you add (-1)kx2k+1 / (2k+1), and you stop when there is no change to the sum.



            If this were calculated with ideal arithmetic (exact, infinitely precise arithmetic), it would never stop for non-zero x, since you are always changing the sum. When calculating with fixed-precision arithmetic, it stops when the term is so small it does not change the sum because of the limited precision.



            When |x| is less than one by any significant amount, this comes quickly because x2k+1 gets smaller. When |x| is one, the term becomes just 1 / (2k+1), which gets smaller very slowly. Not until k is around 253 would the sum stop changing.



            You might consider changing your stopping condition to be when sum has not changed from sum_old very much rather than when it has not changed at all.






            share|improve this answer
























              1












              1








              1






              In each iteration, you add (-1)kx2k+1 / (2k+1), and you stop when there is no change to the sum.



              If this were calculated with ideal arithmetic (exact, infinitely precise arithmetic), it would never stop for non-zero x, since you are always changing the sum. When calculating with fixed-precision arithmetic, it stops when the term is so small it does not change the sum because of the limited precision.



              When |x| is less than one by any significant amount, this comes quickly because x2k+1 gets smaller. When |x| is one, the term becomes just 1 / (2k+1), which gets smaller very slowly. Not until k is around 253 would the sum stop changing.



              You might consider changing your stopping condition to be when sum has not changed from sum_old very much rather than when it has not changed at all.






              share|improve this answer












              In each iteration, you add (-1)kx2k+1 / (2k+1), and you stop when there is no change to the sum.



              If this were calculated with ideal arithmetic (exact, infinitely precise arithmetic), it would never stop for non-zero x, since you are always changing the sum. When calculating with fixed-precision arithmetic, it stops when the term is so small it does not change the sum because of the limited precision.



              When |x| is less than one by any significant amount, this comes quickly because x2k+1 gets smaller. When |x| is one, the term becomes just 1 / (2k+1), which gets smaller very slowly. Not until k is around 253 would the sum stop changing.



              You might consider changing your stopping condition to be when sum has not changed from sum_old very much rather than when it has not changed at all.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Nov 19 '18 at 21:10









              Eric PostpischilEric Postpischil

              72.1k878158




              72.1k878158

























                  0














                  if(x >= (-1) && x <= 1) {
                  for(k=0; sum!=sum_old; k++) {
                  sum_old = sum;
                  sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
                  count++;

                  printf("%d || %.17lfn", count, sum);
                  }


                  Comparing doubles can be tricky. The conventional way to compare doubles is to test within epsilon. There should be an epsilon value defined somewhere, but for your purposes how many digits are enough to approximate? If you only need like 3 or 4 digits you can instead have



                  #define EPSILON 0.0001 //make this however precise you need to approximate.

                  if(x >= (-1) && x <= 1) {
                  for(k=0; fabs(sum - sum_old) > EPSILON; k++) {
                  sum_old = sum;
                  sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
                  count++;

                  printf("%d || %.17lfn", count, sum);
                  }


                  If the issue is that -1,1 iterate too many times either reduce the precision or increase the step per iteration. I am not sure that is what you're asking though, please clarify.






                  share|improve this answer


























                    0














                    if(x >= (-1) && x <= 1) {
                    for(k=0; sum!=sum_old; k++) {
                    sum_old = sum;
                    sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
                    count++;

                    printf("%d || %.17lfn", count, sum);
                    }


                    Comparing doubles can be tricky. The conventional way to compare doubles is to test within epsilon. There should be an epsilon value defined somewhere, but for your purposes how many digits are enough to approximate? If you only need like 3 or 4 digits you can instead have



                    #define EPSILON 0.0001 //make this however precise you need to approximate.

                    if(x >= (-1) && x <= 1) {
                    for(k=0; fabs(sum - sum_old) > EPSILON; k++) {
                    sum_old = sum;
                    sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
                    count++;

                    printf("%d || %.17lfn", count, sum);
                    }


                    If the issue is that -1,1 iterate too many times either reduce the precision or increase the step per iteration. I am not sure that is what you're asking though, please clarify.






                    share|improve this answer
























                      0












                      0








                      0






                      if(x >= (-1) && x <= 1) {
                      for(k=0; sum!=sum_old; k++) {
                      sum_old = sum;
                      sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
                      count++;

                      printf("%d || %.17lfn", count, sum);
                      }


                      Comparing doubles can be tricky. The conventional way to compare doubles is to test within epsilon. There should be an epsilon value defined somewhere, but for your purposes how many digits are enough to approximate? If you only need like 3 or 4 digits you can instead have



                      #define EPSILON 0.0001 //make this however precise you need to approximate.

                      if(x >= (-1) && x <= 1) {
                      for(k=0; fabs(sum - sum_old) > EPSILON; k++) {
                      sum_old = sum;
                      sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
                      count++;

                      printf("%d || %.17lfn", count, sum);
                      }


                      If the issue is that -1,1 iterate too many times either reduce the precision or increase the step per iteration. I am not sure that is what you're asking though, please clarify.






                      share|improve this answer












                      if(x >= (-1) && x <= 1) {
                      for(k=0; sum!=sum_old; k++) {
                      sum_old = sum;
                      sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
                      count++;

                      printf("%d || %.17lfn", count, sum);
                      }


                      Comparing doubles can be tricky. The conventional way to compare doubles is to test within epsilon. There should be an epsilon value defined somewhere, but for your purposes how many digits are enough to approximate? If you only need like 3 or 4 digits you can instead have



                      #define EPSILON 0.0001 //make this however precise you need to approximate.

                      if(x >= (-1) && x <= 1) {
                      for(k=0; fabs(sum - sum_old) > EPSILON; k++) {
                      sum_old = sum;
                      sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
                      count++;

                      printf("%d || %.17lfn", count, sum);
                      }


                      If the issue is that -1,1 iterate too many times either reduce the precision or increase the step per iteration. I am not sure that is what you're asking though, please clarify.







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Nov 19 '18 at 21:04









                      BwebbBwebb

                      3358




                      3358























                          0














                          I think the cause of this is for a mathematical reason rather than a programming one.



                          Away from the little mistakes and adjustments that you should do to your code, putting x = 1 in the infinite series of arctan, is a boundary condition:
                          arctan infinite series
                          In this series, we add a negative value to a positive value then a negative value. This means the sum will be increasing, decreasing, increasing, ... and this will make some difference each iteration. This difference will be smaller until the preciseness of double won't catch it, so the program will stop and give us the value.



                          But in the sum equation. When we set z = 1 and n goes from 0 to ∞, this will make this term (-1^n) equal to 1 in one time and -1 in the next iteration. Also,
                          the value of the z-term will be one and the denominator value when n approaches infinity will = ∞ .



                          So the sum several iterations will be like +1/∞ -1/∞ +1/∞ -1/∞ ... (where ∞ here represents a big number). That way the series will not reach a specific number. This is because z = 1 is a boundary in this equation. And that is causing infinite iterations in your solution without reaching a number.



                          If you need to calculate arctan(1) I think you should use this formula:arctan 2



                          All formulas are from this Wikipedia article.






                          share|improve this answer




























                            0














                            I think the cause of this is for a mathematical reason rather than a programming one.



                            Away from the little mistakes and adjustments that you should do to your code, putting x = 1 in the infinite series of arctan, is a boundary condition:
                            arctan infinite series
                            In this series, we add a negative value to a positive value then a negative value. This means the sum will be increasing, decreasing, increasing, ... and this will make some difference each iteration. This difference will be smaller until the preciseness of double won't catch it, so the program will stop and give us the value.



                            But in the sum equation. When we set z = 1 and n goes from 0 to ∞, this will make this term (-1^n) equal to 1 in one time and -1 in the next iteration. Also,
                            the value of the z-term will be one and the denominator value when n approaches infinity will = ∞ .



                            So the sum several iterations will be like +1/∞ -1/∞ +1/∞ -1/∞ ... (where ∞ here represents a big number). That way the series will not reach a specific number. This is because z = 1 is a boundary in this equation. And that is causing infinite iterations in your solution without reaching a number.



                            If you need to calculate arctan(1) I think you should use this formula:arctan 2



                            All formulas are from this Wikipedia article.






                            share|improve this answer


























                              0












                              0








                              0






                              I think the cause of this is for a mathematical reason rather than a programming one.



                              Away from the little mistakes and adjustments that you should do to your code, putting x = 1 in the infinite series of arctan, is a boundary condition:
                              arctan infinite series
                              In this series, we add a negative value to a positive value then a negative value. This means the sum will be increasing, decreasing, increasing, ... and this will make some difference each iteration. This difference will be smaller until the preciseness of double won't catch it, so the program will stop and give us the value.



                              But in the sum equation. When we set z = 1 and n goes from 0 to ∞, this will make this term (-1^n) equal to 1 in one time and -1 in the next iteration. Also,
                              the value of the z-term will be one and the denominator value when n approaches infinity will = ∞ .



                              So the sum several iterations will be like +1/∞ -1/∞ +1/∞ -1/∞ ... (where ∞ here represents a big number). That way the series will not reach a specific number. This is because z = 1 is a boundary in this equation. And that is causing infinite iterations in your solution without reaching a number.



                              If you need to calculate arctan(1) I think you should use this formula:arctan 2



                              All formulas are from this Wikipedia article.






                              share|improve this answer














                              I think the cause of this is for a mathematical reason rather than a programming one.



                              Away from the little mistakes and adjustments that you should do to your code, putting x = 1 in the infinite series of arctan, is a boundary condition:
                              arctan infinite series
                              In this series, we add a negative value to a positive value then a negative value. This means the sum will be increasing, decreasing, increasing, ... and this will make some difference each iteration. This difference will be smaller until the preciseness of double won't catch it, so the program will stop and give us the value.



                              But in the sum equation. When we set z = 1 and n goes from 0 to ∞, this will make this term (-1^n) equal to 1 in one time and -1 in the next iteration. Also,
                              the value of the z-term will be one and the denominator value when n approaches infinity will = ∞ .



                              So the sum several iterations will be like +1/∞ -1/∞ +1/∞ -1/∞ ... (where ∞ here represents a big number). That way the series will not reach a specific number. This is because z = 1 is a boundary in this equation. And that is causing infinite iterations in your solution without reaching a number.



                              If you need to calculate arctan(1) I think you should use this formula:arctan 2



                              All formulas are from this Wikipedia article.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Nov 19 '18 at 22:30

























                              answered Nov 19 '18 at 22:19









                              Gamal OthmanGamal Othman

                              599




                              599























                                  0














                                  Here is some modifications that make your code more compact and has less errors:



                                  #include <stdio.h>
                                  #include <math.h>

                                  #define x 0.5 //here x is much easier to change

                                  double pw(double, double); //declaration of the function should be done

                                  int main() { //the default return type of main is int.

                                  double k;
                                  double sum = 0 ; //you should initiate your variables.
                                  double sum_old = 1 ; //=1 only to pass the for condition first time.
                                  //you don't need to define counter here
                                  if(x < -1 || x > 1){
                                  printf("x is not defined. Please choose an x in the interval [-1, 1]n");
                                  return 0;
                                  }
                                  for(k=0; sum!=sum_old; k++) {
                                  sum_old = sum;
                                  sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
                                  printf("%.0f || %.17lfn", k, sum);
                                  }

                                  printf("My result is: %.17lfn",sum);
                                  printf("atan(%f) is: %.17fn", x, atan(x));
                                  printf("My result minus atan(x) = %.17lfn", sum - atan(x));

                                  return 0;
                                  }

                                  double pw(double y, double n) { //functions should be declared out of the main function
                                  double i;
                                  double number = 1;

                                  for (i = 0; i < n; i++) {
                                  number *= y;
                                  }
                                  return(number);
                                  }

                                  double fc (double y) {
                                  double i;
                                  double number = 1;

                                  for (i = 1; i <= y; i++){
                                  number *= i;
                                  }
                                  return(number);
                                  }





                                  share|improve this answer


























                                    0














                                    Here is some modifications that make your code more compact and has less errors:



                                    #include <stdio.h>
                                    #include <math.h>

                                    #define x 0.5 //here x is much easier to change

                                    double pw(double, double); //declaration of the function should be done

                                    int main() { //the default return type of main is int.

                                    double k;
                                    double sum = 0 ; //you should initiate your variables.
                                    double sum_old = 1 ; //=1 only to pass the for condition first time.
                                    //you don't need to define counter here
                                    if(x < -1 || x > 1){
                                    printf("x is not defined. Please choose an x in the interval [-1, 1]n");
                                    return 0;
                                    }
                                    for(k=0; sum!=sum_old; k++) {
                                    sum_old = sum;
                                    sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
                                    printf("%.0f || %.17lfn", k, sum);
                                    }

                                    printf("My result is: %.17lfn",sum);
                                    printf("atan(%f) is: %.17fn", x, atan(x));
                                    printf("My result minus atan(x) = %.17lfn", sum - atan(x));

                                    return 0;
                                    }

                                    double pw(double y, double n) { //functions should be declared out of the main function
                                    double i;
                                    double number = 1;

                                    for (i = 0; i < n; i++) {
                                    number *= y;
                                    }
                                    return(number);
                                    }

                                    double fc (double y) {
                                    double i;
                                    double number = 1;

                                    for (i = 1; i <= y; i++){
                                    number *= i;
                                    }
                                    return(number);
                                    }





                                    share|improve this answer
























                                      0












                                      0








                                      0






                                      Here is some modifications that make your code more compact and has less errors:



                                      #include <stdio.h>
                                      #include <math.h>

                                      #define x 0.5 //here x is much easier to change

                                      double pw(double, double); //declaration of the function should be done

                                      int main() { //the default return type of main is int.

                                      double k;
                                      double sum = 0 ; //you should initiate your variables.
                                      double sum_old = 1 ; //=1 only to pass the for condition first time.
                                      //you don't need to define counter here
                                      if(x < -1 || x > 1){
                                      printf("x is not defined. Please choose an x in the interval [-1, 1]n");
                                      return 0;
                                      }
                                      for(k=0; sum!=sum_old; k++) {
                                      sum_old = sum;
                                      sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
                                      printf("%.0f || %.17lfn", k, sum);
                                      }

                                      printf("My result is: %.17lfn",sum);
                                      printf("atan(%f) is: %.17fn", x, atan(x));
                                      printf("My result minus atan(x) = %.17lfn", sum - atan(x));

                                      return 0;
                                      }

                                      double pw(double y, double n) { //functions should be declared out of the main function
                                      double i;
                                      double number = 1;

                                      for (i = 0; i < n; i++) {
                                      number *= y;
                                      }
                                      return(number);
                                      }

                                      double fc (double y) {
                                      double i;
                                      double number = 1;

                                      for (i = 1; i <= y; i++){
                                      number *= i;
                                      }
                                      return(number);
                                      }





                                      share|improve this answer












                                      Here is some modifications that make your code more compact and has less errors:



                                      #include <stdio.h>
                                      #include <math.h>

                                      #define x 0.5 //here x is much easier to change

                                      double pw(double, double); //declaration of the function should be done

                                      int main() { //the default return type of main is int.

                                      double k;
                                      double sum = 0 ; //you should initiate your variables.
                                      double sum_old = 1 ; //=1 only to pass the for condition first time.
                                      //you don't need to define counter here
                                      if(x < -1 || x > 1){
                                      printf("x is not defined. Please choose an x in the interval [-1, 1]n");
                                      return 0;
                                      }
                                      for(k=0; sum!=sum_old; k++) {
                                      sum_old = sum;
                                      sum += pw((-1), k) * pw(x, (2*k) + 1)/((2*k) + 1);
                                      printf("%.0f || %.17lfn", k, sum);
                                      }

                                      printf("My result is: %.17lfn",sum);
                                      printf("atan(%f) is: %.17fn", x, atan(x));
                                      printf("My result minus atan(x) = %.17lfn", sum - atan(x));

                                      return 0;
                                      }

                                      double pw(double y, double n) { //functions should be declared out of the main function
                                      double i;
                                      double number = 1;

                                      for (i = 0; i < n; i++) {
                                      number *= y;
                                      }
                                      return(number);
                                      }

                                      double fc (double y) {
                                      double i;
                                      double number = 1;

                                      for (i = 1; i <= y; i++){
                                      number *= i;
                                      }
                                      return(number);
                                      }






                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Nov 19 '18 at 22:41









                                      Gamal OthmanGamal Othman

                                      599




                                      599






























                                          draft saved

                                          draft discarded




















































                                          Thanks for contributing an answer to Stack Overflow!


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid



                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.


                                          To learn more, see our tips on writing great answers.




                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function () {
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53382349%2fwhat-should-i-change-so-that-my-arctanx-approximation-can-display-x-1-and-x-1%23new-answer', 'question_page');
                                          }
                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          Popular posts from this blog

                                          MongoDB - Not Authorized To Execute Command

                                          How to fix TextFormField cause rebuild widget in Flutter

                                          in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith