By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,646 Members | 1,175 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,646 IT Pros & Developers. It's quick & easy.

Can someone please tell me where I am going wrong??

P: n/a
I am trying to write a program which asks the user to enter a number
in the interval [1,2], the program then gives the natural logarithm of
that number, using the series for log(x+1)...

Here is what I have so far and can't figure out what i'm doing wrong.
any help would be greatly appreciated, thanks guys...

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

int main() {

int i,n;
double x;
float sum, term;

printf("Enter a number in the interval [1,2]");
scanf("%d", &x);

sum = 0;
i = 0;

do {
i = i+1;
x = (double) i;
term = pow(x, i)/i;
if(i % 2 == 1)
sum = sum + term;
else
sum = sum - term;

} while(i <= n);

printf("The answer is %lf\n",sum);

Mar 5 '07 #1
Share this Question
Share on Google+
15 Replies


P: n/a
E-Dot wrote:
I am trying to write a program which asks the user to enter a number
in the interval [1,2], the program then gives the natural logarithm of
that number, using the series for log(x+1)...

Here is what I have so far and can't figure out what i'm doing wrong.
any help would be greatly appreciated, thanks guys...

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

int main() {
If main is not going to accept command line parameters, specify void.
int i,n;
double x;
float sum, term;
Why not make sum and term double as well?
printf("Enter a number in the interval [1,2]");
Either end the printf string with a newline or call fflush(stdout)
just after printf. Otherwise, your output may appear delayed because
of buffering.
scanf("%d", &x);
You're telling scanf to look for a decimal integer value and store it
into a double object. Are you sure that this is what you want?
sum = 0;
i = 0;

do {
i = i+1;
x = (double) i;
And you're overwriting your previous value in x.
term = pow(x, i)/i;
Here x and i will have the same value due to your previous assignment.
if(i % 2 == 1)
sum = sum + term;
else
sum = sum - term;

} while(i <= n);
You're comparing i against an uninitialised value, (n); Undefined
behaviour.
printf("The answer is %lf\n",sum);
For printing a float-point object use the %f format specifier. The %lf
format specifier was added with C99, as an alternative, but many
compilers don't yet fully support it.

Mar 5 '07 #2

P: n/a
E-Dot wrote:
I am trying to write a program which asks the user to enter a number
in the interval [1,2], the program then gives the natural logarithm of
that number, using the series for log(x+1)...
it would be better if you posted all of the assignment.

Here is what I have so far and can't figure out what i'm doing wrong.
perhaps if you said what the symptom was... What is going wrong?

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

int main() {

int i,n;
double x;
float sum, term;

printf("Enter a number in the interval [1,2]");
scanf("%d", &x);

sum = 0;
i = 0;

do {
i = i+1;
could use (same result, but less to type)
i++;
x = (double) i;
term = pow(x, i)/i;
you can avoid calling pow() in the loop. What is the difference
between pow(x,i) and pow(x,i+1), is there a pattern?
if(i % 2 == 1)
sum = sum + term;
or
sum += term;
else
sum = sum - term;

} while(i <= n);
this isn't going to give you six decimal places is it?
And n is not initialised.
>
printf("The answer is %lf\n",sum);
if you did what the assignment said and printed x, sum and log(x)
you might have been able to debug this yourself (x would be wrong)
--
Nick Keighley

Mar 6 '07 #3

P: n/a

Nick Keighley wrote:
E-Dot wrote:
I am trying to write a program which asks the user to enter a number
in the interval [1,2], the program then gives the natural logarithm of
that number, using the series for log(x+1)...
note that's log(x + 1), not log(x)...

<snip>

--
Nick Keighley

Mar 6 '07 #4

P: n/a
"E-Dot" writes:
>I am trying to write a program which asks the user to enter a number
in the interval [1,2], the program then gives the natural logarithm of
that number, using the series for log(x+1)...
<snip>

You are still fighting basic I/0 instead of the thing your instructor is
dwelling on. I/O, in any language, is a bitch, plain and simple. You seem
to have tried so here is a skeleton you should be able to use as a test rig.
The stuff just before return 3.1416 needs a bit of refinement, which I will
leave to you. The getchar() sprinkled around are to make life simpler when
debugging with the compiler I happen to use. You may not need them.

#include <stdio.h>
#include <stdlib.h /* exit() */

double ln(double x)
{
if( x<-1 || x>+1)
{
printf("Argument provided to function ln out of range.\nAborting\n");
fflush(NULL);
getchar();
getchar();
exit(-1);
}
/* Need something here ... */
return 3.1416;
}
/******************/
int main(void)
{
double z, y;
printf("Enter a decimal number in the range 1..2\n");
scanf("%lf", &z);
y = ln(z-1);
printf("Natural log of %f is %f\n", z, y);
fflush(NULL);
getchar();
getchar();
return 0;
}
Mar 6 '07 #5

P: n/a
On Mar 6, 3:16 am, "Nick Keighley" <nick_keighley_nos...@hotmail.com>
wrote:
Nick Keighley wrote:
E-Dot wrote:
I am trying to write a program which asks the user to enter a number
in the interval [1,2], the program then gives the natural logarithm of
that number, using the series for log(x+1)...

note that's log(x + 1), not log(x)...
The series expansion for log(x+1) is:
x - x^2/2 + x^3/3 - x^4/4 ...
Handbook of Mathematical Functions, equation 4.1.24:
http://www.math.sfu.ca/~cbm/aands/page_68.htm

Mar 6 '07 #6

P: n/a
user923005 wrote:
Nick Keighley wrote:
>E-Dot wrote:
>>I am trying to write a program which asks the user to enter a
number in the interval [1,2], the program then gives the natural
logarithm of that number, using the series for log(x+1)...

note that's log(x + 1), not log(x)...

The series expansion for log(x+1) is:
x - x^2/2 + x^3/3 - x^4/4 ...
Handbook of Mathematical Functions, equation 4.1.24:
http://www.math.sfu.ca/~cbm/aands/page_68.htm
#include <stdlib.h>

double ln(double x) {
double lnx, lnxold, delta;
int n;

if ((x <= 0) || ((x = x - 1.0) >= 1.0)) exit(EXIT_FAILURE);
lnxold = 0; delta = x; n = 1;
while ((lnx = lnxold + delta) != lnxold) delta *= x / ++n;
return lnx;
} /* untested, known to be slow */

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
Mar 7 '07 #7

P: n/a
CBFalconer wrote:
>
user923005 wrote:
Nick Keighley wrote:
E-Dot wrote:

I am trying to write a program which asks the user to enter a
number in the interval [1,2], the program then gives the natural
logarithm of that number, using the series for log(x+1)...

note that's log(x + 1), not log(x)...
The series expansion for log(x+1) is:
x - x^2/2 + x^3/3 - x^4/4 ...
Handbook of Mathematical Functions, equation 4.1.24:
http://www.math.sfu.ca/~cbm/aands/page_68.htm

#include <stdlib.h>

double ln(double x) {
double lnx, lnxold, delta;
int n;

if ((x <= 0) || ((x = x - 1.0) >= 1.0)) exit(EXIT_FAILURE);
lnxold = 0; delta = x; n = 1;
while ((lnx = lnxold + delta) != lnxold) delta *= x / ++n;
return lnx;
} /* untested, known to be slow */
Correction, above is flawed: It also sums the wrong series! as
does the following. I leave it to the student to correct the value
of delta.

#include <stdio.h>
#include <stdlib.h>

double ln(double x) {
double lnx, lnxold, delta;
int n;

if ((x <= 0) || ((x = x - 1.0) >= 1.0)) exit(EXIT_FAILURE);
lnxold = 0; delta = x; n = 1;
while ((lnx = lnxold + delta) != lnxold) {
delta *= x / ++n;
lnxold = lnx;
}
return lnx;
} /* known to be slow */

/* ----------------- */

int main(int argc, char* *argv) {
double x;

if ((argc != 2) || (1 != sscanf(argv[1], "%lf", &x))) {
fprintf(stderr, "Usage: lnx value (>0 and <2\n");
exit(EXIT_FAILURE);
}
printf("Ln(%f) = %f\n", x, ln(x));
return 0;
}
--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
Mar 7 '07 #8

P: n/a
On Tue, 06 Mar 2007 21:40:38 -0500, CBFalconer <cb********@yahoo.com>
wrote:
>CBFalconer wrote:
>>
user923005 wrote:
Nick Keighley wrote:
E-Dot wrote:

I am trying to write a program which asks the user to enter a
number in the interval [1,2], the program then gives the natural
logarithm of that number, using the series for log(x+1)...

note that's log(x + 1), not log(x)...

The series expansion for log(x+1) is:
x - x^2/2 + x^3/3 - x^4/4 ...
Handbook of Mathematical Functions, equation 4.1.24:
http://www.math.sfu.ca/~cbm/aands/page_68.htm

#include <stdlib.h>

double ln(double x) {
double lnx, lnxold, delta;
int n;

if ((x <= 0) || ((x = x - 1.0) >= 1.0)) exit(EXIT_FAILURE);
lnxold = 0; delta = x; n = 1;
while ((lnx = lnxold + delta) != lnxold) delta *= x / ++n;
return lnx;
} /* untested, known to be slow */

Correction, above is flawed: It also sums the wrong series! as
does the following. I leave it to the student to correct the value
of delta.

#include <stdio.h>
#include <stdlib.h>

double ln(double x) {
double lnx, lnxold, delta;
int n;

if ((x <= 0) || ((x = x - 1.0) >= 1.0)) exit(EXIT_FAILURE);
lnxold = 0; delta = x; n = 1;
while ((lnx = lnxold + delta) != lnxold) {
delta *= x / ++n;
lnxold = lnx;
}
return lnx;
} /* known to be slow */

/* ----------------- */

int main(int argc, char* *argv) {
double x;

if ((argc != 2) || (1 != sscanf(argv[1], "%lf", &x))) {
fprintf(stderr, "Usage: lnx value (>0 and <2\n");
exit(EXIT_FAILURE);
}
printf("Ln(%f) = %f\n", x, ln(x));
return 0;
}
I don't get it.

When I run your program with an argument of 5.0, it returns
EXIT_FAILURE. But in my Windows Vista Calculator application, ln(5)
returns 1.6094379124341003746007593332262. I suspect the Windows Vista
Calculator is correct and your program is flawed, and the reason your
program is flawed has nothing to do with the value of delta--not
surprising (in my experience) for open source software.

--
jay

It's here:
http://www.microsoft.com/windows/products/windowsvista/
Mar 7 '07 #9

P: n/a
jaysome said:

<snip>
I don't get it.

When I run [CBFalconer's] program with an argument of 5.0, it returns
EXIT_FAILURE. But in my Windows Vista Calculator application, ln(5)
returns 1.6094379124341003746007593332262. I suspect the Windows Vista
Calculator is correct and your program is flawed,
No, the program is correct, and Windows Vista Calculator is also
correct. But they do different things.

You told the calculator to give you ln(5), and (presumably) it did
precisely that (unless you have any non-DRM-enabled equipment attached
to your machine, in which case I am given to understand that Windows
Vista may randomly corrupt your data - what fun!).

But you told the *program*, which is designed to tell you the logarithm
of a value in the interval [1,2], that the value in the interval [1,2]
that you had selected was 5. The program rightly rejected this value as
not being in the proper range for which the program was designed.

See the OP for details.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 7 '07 #10

P: n/a
jaysome wrote:
On Tue, 06 Mar 2007 21:40:38 -0500, CBFalconer <cb********@yahoo.com>
<snip>
Correction, above is flawed: It also sums the wrong series! as
does the following. I leave it to the student to correct the value
of delta.

#include <stdio.h>
#include <stdlib.h>

double ln(double x) {
double lnx, lnxold, delta;
int n;

if ((x <= 0) || ((x = x - 1.0) >= 1.0)) exit(EXIT_FAILURE);
lnxold = 0; delta = x; n = 1;
while ((lnx = lnxold + delta) != lnxold) {
delta *= x / ++n;
lnxold = lnx;
}
return lnx;
} /* known to be slow */

/* ----------------- */

int main(int argc, char* *argv) {
double x;

if ((argc != 2) || (1 != sscanf(argv[1], "%lf", &x))) {
fprintf(stderr, "Usage: lnx value (>0 and <2\n");
exit(EXIT_FAILURE);
}
printf("Ln(%f) = %f\n", x, ln(x));
return 0;
}

I don't get it.

When I run your program with an argument of 5.0, it returns
EXIT_FAILURE. But in my Windows Vista Calculator application, ln(5)
returns 1.6094379124341003746007593332262. I suspect the Windows Vista
Calculator is correct and your program is flawed, and the reason your
program is flawed has nothing to do with the value of delta--not
surprising (in my experience) for open source software.
It designed only to accept values between 1.0 and 2.0.

Mar 7 '07 #11

P: n/a
On Wed, 07 Mar 2007 08:19:24 +0000, Richard Heathfield
<rj*@see.sig.invalidwrote:
>jaysome said:

<snip>
>I don't get it.

When I run [CBFalconer's] program with an argument of 5.0, it returns
EXIT_FAILURE. But in my Windows Vista Calculator application, ln(5)
returns 1.6094379124341003746007593332262. I suspect the Windows Vista
Calculator is correct and your program is flawed,

No, the program is correct, and Windows Vista Calculator is also
correct. But they do different things.

You told the calculator to give you ln(5), and (presumably) it did
precisely that (unless you have any non-DRM-enabled equipment attached
to your machine, in which case I am given to understand that Windows
Vista may randomly corrupt your data - what fun!).

But you told the *program*, which is designed to tell you the logarithm
of a value in the interval [1,2], that the value in the interval [1,2]
that you had selected was 5. The program rightly rejected this value as
not being in the proper range for which the program was designed.

See the OP for details.
Sorry :(
Mar 7 '07 #12

P: n/a
jaysome wrote:
>
On Tue, 06 Mar 2007 21:40:38 -0500, CBFalconer <cb********@yahoo.com>
wrote:
CBFalconer wrote:
>
user923005 wrote:
Nick Keighley wrote:
E-Dot wrote:

I am trying to write a program which asks the user to enter a
number in the interval [1,2], the program then gives the natural
logarithm of that number, using the series for log(x+1)...

note that's log(x + 1), not log(x)...

The series expansion for log(x+1) is:
x - x^2/2 + x^3/3 - x^4/4 ...
Handbook of Mathematical Functions, equation 4.1.24:
http://www.math.sfu.ca/~cbm/aands/page_68.htm

#include <stdlib.h>

double ln(double x) {
double lnx, lnxold, delta;
int n;

if ((x <= 0) || ((x = x - 1.0) >= 1.0)) exit(EXIT_FAILURE);
lnxold = 0; delta = x; n = 1;
while ((lnx = lnxold + delta) != lnxold) delta *= x / ++n;
return lnx;
} /* untested, known to be slow */
Correction, above is flawed: It also sums the wrong series! as
does the following. I leave it to the student to correct the value
of delta.

#include <stdio.h>
#include <stdlib.h>

double ln(double x) {
double lnx, lnxold, delta;
int n;

if ((x <= 0) || ((x = x - 1.0) >= 1.0)) exit(EXIT_FAILURE);
lnxold = 0; delta = x; n = 1;
while ((lnx = lnxold + delta) != lnxold) {
delta *= x / ++n;
lnxold = lnx;
}
return lnx;
} /* known to be slow */

/* ----------------- */

int main(int argc, char* *argv) {
double x;

if ((argc != 2) || (1 != sscanf(argv[1], "%lf", &x))) {
fprintf(stderr, "Usage: lnx value (>0 and <2\n");
exit(EXIT_FAILURE);
}
printf("Ln(%f) = %f\n", x, ln(x));
return 0;
}

I don't get it.

When I run your program with an argument of 5.0, it returns
EXIT_FAILURE. But in my Windows Vista Calculator application, ln(5)
returns 1.6094379124341003746007593332262. I suspect the Windows Vista
Calculator is correct and your program is flawed, and the reason your
program is flawed has nothing to do with the value of delta--not
surprising (in my experience) for open source software.
Of course it does. The series does not converge for that value.
If you bother to read what I wrote it is also calculating the wrong
series. The point of publishing is the method of deciding that no
further improvement is possible, bu keeping track of delta and its
relationship to the actual series sum.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews
Mar 7 '07 #13

P: n/a
E-Dot wrote:
>
I am trying to write a program which asks the user to enter a number
in the interval [1,2], the program then gives the natural logarithm of
that number, using the series for log(x+1)...

Here is what I have so far and can't figure out what i'm doing wrong.
any help would be greatly appreciated, thanks guys...

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

int main() {

int i,n;
double x;
float sum, term;

printf("Enter a number in the interval [1,2]");
scanf("%d", &x);

sum = 0;
i = 0;

do {
i = i+1;
x = (double) i;
term = pow(x, i)/i;
if(i % 2 == 1)
sum = sum + term;
else
sum = sum - term;

} while(i <= n);

printf("The answer is %lf\n",sum);
/* BEGIN new.c */

#include <stdio.h>
#include <float.h>

double fs_log(double x);
double fs_sqrt(double x);

int main(void)
{
double x, e;

fputs("Enter a number in the interval [1,2]", stdout);
fflush(stdout);
if (scanf("%lf", &x) == 1) {
e = fs_log(x);
printf("The answer is %f\n", e);
} else {
puts("scanf(\"%lf\", &x) != 1");
}
return 0;
}

double fs_log(double x)
{
int n;
double a, b, c, epsilon;
static double A, B, C;
static int initialized;

if (x 0 && DBL_MAX >= x) {
if (!initialized) {
initialized = 1;
A = fs_sqrt(2);
B = A / 2;
C = fs_log(A);
}
for (n = 0; x A; x /= 2) {
++n;
}
while (B x) {
--n;
x *= 2;
}
a = (x - 1) / (x + 1);
x = C * n + a;
c = a * a;
n = 1;
epsilon = DBL_EPSILON * x;
if (0 a) {
if (epsilon 0) {
epsilon = -epsilon;
}
do {
n += 2;
a *= c;
b = a / n;
x += b;
} while (epsilon b);
} else {
if (0 epsilon) {
epsilon = -epsilon;
}
do {
n += 2;
a *= c;
b = a / n;
x += b;
} while (b epsilon);
}
x *= 2;
} else {
x = -DBL_MAX;
}
return x;
}

double fs_sqrt(double x)
{
int n;
double a, b;

if (x 0 && DBL_MAX >= x) {
for (n = 0; x 2; x /= 4) {
++n;
}
while (0.5 x) {
--n;
x *= 4;
}
a = x;
b = (1 + x) / 2;
do {
x = b;
b = (a / b + b) / 2;
} while (x b);
while (n 0) {
x *= 2;
--n;
}
while (0 n) {
x /= 2;
++n;
}
} else {
if (x != 0) {
x = DBL_MAX;
}
}
return x;
}

/* END new.c */

--
pete
Mar 11 '07 #14

P: n/a
pete wrote:
E-Dot wrote:
>I am trying to write a program which asks the user to enter a number
in the interval [1,2], the program then gives the natural logarithm
of that number, using the series for log(x+1)...

Here is what I have so far and can't figure out what i'm doing wrong.
any help would be greatly appreciated, thanks guys...
.... snip code ...
>
/* BEGIN new.c */
.... snip code ...

A while ago I cleaned up my series accumulator, but then my ISP
glitched and cut me off from Usenet. At any rate, here is the
result. It is very slow for inputs near to 0 or 2, but not bad for
values in the range 1/sqrt(2) through sqrt(2), which is quite
enough to allow calculating any ln whatsoever. The confusion
between 80 bit and 64 bit doubles on the X86 also appears to
prolong convergence.

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

/* Sum ((x-1) ** N) / N for N = 1 to whatever */
double ln(double x) {
double lnx, lnxold, delta;
unsigned long n;

if ((x <= 0) || ((x = x - 1.0) >= 1.0))
return 0.0/0.0; /* make a NAN */
lnxold = 0; delta = x; n = 1;
while ((lnx = lnxold + delta) != lnxold) {
delta *= -x * n / (n + 1);
if ((n 1) && !(n & 0xffffe)) /* for slow convergence */
printf("%10lu %27.19e %27.19e\n", n, delta, lnx);
lnxold = lnx;
n++;
if (!(n+1)) break; /* catch overflow */
}
return lnx;
} /* known to be slow */

/* ----------------- */

int main(int argc, char* *argv) {
double x;

if ((argc != 2) || (1 != sscanf(argv[1], "%lf", &x))) {
fprintf(stderr, "Usage: lnx value (>0 and <2\n");
exit(EXIT_FAILURE);
}
printf("Ln(%.10f) = %f\n", x, ln(x));
return 0;
}

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Mar 12 '07 #15

P: n/a
CBFalconer wrote:
>
pete wrote:
E-Dot wrote:
I am trying to write a program which asks the user to enter a number
in the interval [1,2], the program then gives the natural logarithm
of that number, using the series for log(x+1)...

Here is what I have so far and can't figure out what i'm doing wrong.
any help would be greatly appreciated, thanks guys...
... snip code ...

/* BEGIN new.c */
... snip code ...

A while ago I cleaned up my series accumulator, but then my ISP
glitched and cut me off from Usenet. At any rate, here is the
result. It is very slow for inputs near to 0 or 2, but not bad for
values in the range 1/sqrt(2) through sqrt(2), which is quite
enough to allow calculating any ln whatsoever. The confusion
between 80 bit and 64 bit doubles on the X86 also appears to
prolong convergence.

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

/* Sum ((x-1) ** N) / N for N = 1 to whatever */
double ln(double x) {
double lnx, lnxold, delta;
unsigned long n;

if ((x <= 0) || ((x = x - 1.0) >= 1.0))
return 0.0/0.0; /* make a NAN */
lnxold = 0; delta = x; n = 1;
while ((lnx = lnxold + delta) != lnxold) {
I wonder if that condition depends upon the value of FLT_ROUNDS?
delta *= -x * n / (n + 1);
if ((n 1) && !(n & 0xffffe)) /* for slow convergence */
printf("%10lu %27.19e %27.19e\n", n, delta, lnx);
lnxold = lnx;
n++;
if (!(n+1)) break; /* catch overflow */
}
return lnx;
} /* known to be slow */

/* ----------------- */

int main(int argc, char* *argv) {
double x;

if ((argc != 2) || (1 != sscanf(argv[1], "%lf", &x))) {
fprintf(stderr, "Usage: lnx value (>0 and <2\n");
exit(EXIT_FAILURE);
}
printf("Ln(%.10f) = %f\n", x, ln(x));
return 0;
}

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com
--
pete
Mar 13 '07 #16

This discussion thread is closed

Replies have been disabled for this discussion.