# Using a math function in C.

Discussion in 'C Programming' started by David, Aug 30, 2003.

1. ### DavidGuest

Here is some code. I am trying to figure out how to raise, say, x to
the yth power. I know that isn't explicitly what is in the code but
that is the idea I am trying to solve. See the 2nd for loop>>3 errors.

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

int main(void)
{
#define p 100000;
int j, k, t, s;
float i;
double m, a, r, q;

printf(" Mortgage Payment Plan");
printf("Principle Interest Rate Duration Monthly Payment
Total Payment");

for(i=0.06; i<0.11; i+0.01)
{
for(t=5; t<35; t+5)
{
s = t*12;
r = (1/ (1+i/12));
q = pow(double r, int s);
m = (p*i/12) / (1-q);
a = m*t*12;
printf("%d %.2f %d %.2f %.2f", p, i, t, m, a);
}
}
return 0;
}

The style isn't very good. But, I just need to produce an output for
class. Hey, thanks for your help with this one. I appreciate it.
David

David, Aug 30, 2003

2. ### MalcolmGuest

"David" <> wrote in message
> Here is some code. I am trying to figure out how to raise, say, x to
> the yth power. I know that isn't explicitly what is in the code but
> that is the idea I am trying to solve. See the 2nd for loop>>3 errors.
>
> #include <stdio.h>
> #include <math.h>
>
> int main(void)
> {
> #define p 100000;

This #define has a trailing semi-colon, which will cause problems.
Also, "p" isn't a particularly good label to #define
> int j, k, t, s;
> float i;
> double m, a, r, q;
>

We also have the problem here that the variables are all single letters, so
it is difficult to understand what they are used for.
>
> printf(" Mortgage Payment Plan");
> printf("Principle Interest Rate Duration Monthly Payment
> Total Payment");
>

You probably want newlines at the end of these printf()s.
>
> for(i=0.06; i<0.11; i+0.01)
>

This is totally confusing. Why does i go from 0.06 to 0.11 in increments of
0.01? You need a comment.
You should also be aware that floating point arithemtic isn't exact. The
test i<0.11 might not compare false at the exact point you expect it to.
>
> {
> for(t=5; t<35; t+5)
> {
> s = t*12;
> r = (1/ (1+i/12));
> q = pow(double r, int s);

This is a syntax error. You call a C function without the types.
q = pow(r, s);
Note that s will automatically be promoted to a double - pow() handles
non-integral powers.
A good exercise would be to speed it up by writing your own integerpow()
function.
> m = (p*i/12) / (1-q);
> a = m*t*12;
> printf("%d %.2f %d %.2f %.2f", p, i, t, m, a);
> }
> }
> return 0;
> }
>
> The style isn't very good. But, I just need to produce an output for
> class. Hey, thanks for your help with this one. I appreciate it.
> David

Malcolm, Aug 30, 2003

3. ### Juan =?ISO-8859-15?Q?=C1ngel?=Guest

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

David wrote:
> Here is some code. I am trying to figure out how to raise, say, x to
> the yth power. I know that isn't explicitly what is in the code but
> that is the idea I am trying to solve. See the 2nd for loop>>3 errors.

A fast way to do so is:
x^y = z then
log(x^y) = log(z) then
y*log(x) = log(z)
You could use the math funcion "log" to solve the left logarithm (natural
logarithm), then use "exp" to raise the result to get 'z'.
For a "normal" way of doing it, look for "pow".

Note: log(base,number) = log(2,number) / log(2,base), and working with powers
of two is much faster than with non-power ones.
- --
Juan Ángel
PGP key on pgp.rediris.es (8FAF18B7)
or search on http://www.rediris.es/cert/servicios/keyserver/

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.3 (GNU/Linux)

iD8DBQE/UOLCaQjbS4+vGLcRAtrzAKCC+BABlw4hvjUZQQ7Ha0kipqO9BQCgjOeS
feR5OnYYA1yAerd8or7ZlNA=
=BW9h
-----END PGP SIGNATURE-----

Juan =?ISO-8859-15?Q?=C1ngel?=, Aug 30, 2003
4. ### Martin AmbuhlGuest

David wrote:

> Here is some code. I am trying to figure out how to raise, say, x to
> the yth power. I know that isn't explicitly what is in the code but
> that is the idea I am trying to solve. See the 2nd for loop>>3 errors.

The problem with "raising x to the yth power" is this line,
> q = pow(double r, int s);

This should simply be
q = pow(r,s);
Note that pow() takes two double arguments; the integer 's' will have its
value passed as a double, because the prototype for pow() in <math.h> tells
the compiler that the second argument needs to be promoted to a double.

I have preserved your code at EOM for anyone who missed your post and wants
to comment on it. Here is, I believe, a translation of your code in
somewhat more idiomatic C. Note that the BASICy single character names
that you use are obfuscating. If I erred in interpreting them, that is the
normal result of trying to read such code. You will see an attempt to make
your output table less susceptible to guessing what the output specifiers
will produce, a cleaner way to handle loops involving floating-point
quantities, replacement of floats with doubles, and, of course, correction
of the invocation of pow(). I neither guarantee that the logic -- which is
yours -- is correct nor assert that the program could not be further improved.

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

int main(void)
{
const double principle = 100000.;
int years, months;
double nominalrate;
double monthypayment, totalpayment, monthlyrate, actualrate;
int irate;

printf("%-10s %-7s %-5s %-9s\n", "", "Mortgage", "Payment",
"Plan");
printf("%-10s %-7s %-5s %-9s %-15s %-15s\n", "Principle",
"Interest", "Rate", "Duration", "Monthly Payment",
"Total Payment");

for (irate = 6; irate < 11; irate++) {
nominalrate = irate / 100.;
for (years = 5; years < 35; years += 5) {
months = years * 12;
monthlyrate = (1 / (1 + nominalrate / 12));
actualrate = pow(monthlyrate, months);
monthypayment =
(principle * nominalrate / 12) / (1 - actualrate);
totalpayment = monthypayment * years * 12;
printf("%10.0f %7.2f %5d %9d %15.2f %15.2f\n",
principle, nominalrate, 12, years,
monthypayment, totalpayment);
}
}
return 0;
}

[David's code]

> #include <stdio.h>
> #include <math.h>
>
> int main(void)
> {
> #define p 100000;
> int j, k, t, s;
> float i;
> double m, a, r, q;
>
> printf(" Mortgage Payment Plan");
> printf("Principle Interest Rate Duration Monthly Payment
> Total Payment");
>
> for(i=0.06; i<0.11; i+0.01)
> {
> for(t=5; t<35; t+5)
> {
> s = t*12;
> r = (1/ (1+i/12));
> q = pow(double r, int s);
> m = (p*i/12) / (1-q);
> a = m*t*12;
> printf("%d %.2f %d %.2f %.2f", p, i, t, m, a);
> }
> }
> return 0;
> }
>
> The style isn't very good. But, I just need to produce an output for
> class. Hey, thanks for your help with this one. I appreciate it.
> David

--
Martin Ambuhl

Martin Ambuhl, Aug 30, 2003