What should I change so that my arctan(x) approximation can display x=1 and x=-1 properly?
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}
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
|
show 2 more comments
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}
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
Why are you defining functions withinmain
?
– 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 computepw
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
|
show 2 more comments
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}
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
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}
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
c loops for-loop math types
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 withinmain
?
– 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 computepw
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
|
show 2 more comments
Why are you defining functions withinmain
?
– 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 computepw
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
|
show 2 more comments
4 Answers
4
active
oldest
votes
In each iteration, you add (-1)k • x2k+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.
add a comment |
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.
add a comment |
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:
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:
All formulas are from this Wikipedia article.
add a comment |
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);
}
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
In each iteration, you add (-1)k • x2k+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.
add a comment |
In each iteration, you add (-1)k • x2k+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.
add a comment |
In each iteration, you add (-1)k • x2k+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.
In each iteration, you add (-1)k • x2k+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.
answered Nov 19 '18 at 21:10
Eric PostpischilEric Postpischil
72.1k878158
72.1k878158
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 19 '18 at 21:04
BwebbBwebb
3358
3358
add a comment |
add a comment |
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:
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:
All formulas are from this Wikipedia article.
add a comment |
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:
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:
All formulas are from this Wikipedia article.
add a comment |
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:
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:
All formulas are from this Wikipedia article.
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:
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:
All formulas are from this Wikipedia article.
edited Nov 19 '18 at 22:30
answered Nov 19 '18 at 22:19


Gamal OthmanGamal Othman
599
599
add a comment |
add a comment |
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);
}
add a comment |
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);
}
add a comment |
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);
}
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);
}
answered Nov 19 '18 at 22:41


Gamal OthmanGamal Othman
599
599
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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