/* * interest - interest computation program. * * Usage: interest nom comp-den comp-num principal * * nom * nominal interest rate, in percent * comp-den, comp-num * denominator and numerator of the compounding fraction * to be applied to the interest rate * principal * principal amount to which the interest is to be applied * * For example, to use this to work out two months' interest, if the * rate is 4% per half-year ("8% per year compounded semi-annually"), * and interest really is done monthly, and the principal is * $36000.00, * interest 4 6 2 3600000 * will print the interest, rounded to the nearest cent. * * As another example, the same calculation but where interest is * calculated daily and the two months in question are June and July * of a non-leap-year (61 days out of 365/2=182.5), * interest 4 182.5 61 3600000 * would be appropriate. * * The "principal" value must always be an integer; the other three * values may be floating-point. The result is rounded to the nearest * integer for printing. */ #include #include #include extern const char *__progname; static double nom; static double comp_den; static double comp_num; static int principal; static void usage(void) { fprintf(stderr,"%s: usage: %s interest-rate comp-den comp-num principal\n",__progname,__progname); } static int intarg(const char *arg, int *vp, const char *tag) { char *cp; *vp = strtol(arg,&cp,0); if ((cp == arg) || *cp) { fprintf(stderr,"%s: invalid %s value `%s'\n",__progname,tag,arg); return(1); } return(0); } static int floatarg(const char *arg, double *vp, const char *tag) { char *cp; *vp = strtod(arg,&cp); if ((cp == arg) || *cp) { fprintf(stderr,"%s: invalid %s value `%s'\n",__progname,tag,arg); return(1); } return(0); } static void handleargs(int ac, char **av) { int skip; int errs; int argno; skip = 0; errs = 0; argno = 0; for (ac--,av++;ac;ac--,av++) { if (skip > 0) { skip --; continue; } if (**av != '-') { switch (argno++) { case 0: errs += floatarg(*av,&nom, "interest rate" ); break; case 1: errs += floatarg(*av,&comp_den, "compounding denominator"); break; case 2: errs += floatarg(*av,&comp_num, "compounding numerator" ); break; case 3: errs += intarg (*av,&principal,"principal" ); break; default: fprintf(stderr,"%s: extra argument `%s'\n",__progname,*av); errs ++; break; } continue; } #if 0 if (0) { needarg:; fprintf(stderr,"%s: %s needs a following argument\n",__progname,*av); errs ++; continue; } #define WANTARG() do { if (++skip >= ac) goto needarg; } while (0) if (!strcmp(*av,"-display")) { WANTARG(); displayname = av[skip]; continue; } if (!strcmp(*av,"-sync")) { sync = 1; continue; } #undef WANTARG #endif fprintf(stderr,"%s: unrecognized option `%s'\n",__progname,*av); errs ++; } if (argno < 4) { fprintf(stderr,"%s: not enough arguments\n",__progname); errs ++; } if (errs) { usage(); exit(1); } } static int roundint(double d) { int i; double f; i = d; f = d - i; if (f < -.5) i--; else if (f > .5) i ++; return(i); } int main(int, char **); int main(int ac, char **av) { handleargs(ac,av); printf("%d\n",roundint(expm1((log1p(nom/100)*comp_num)/comp_den)*principal)); exit(0); }