Re: compound interest



/*
Here is your opportunity to show us how it can be improved.
This is an interest calculation simulation.
Please improve the algorithm so that it is significantly faster.
*/
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>

double yearly_interest(double principal, double rate, double
years)
{
double amount = principal * pow(1.0 + rate, years) -
principal;
return amount;
}

double quarterly_interest(double principal, double rate,
double years)
{
double amount = principal * pow(1.0 + rate * 0.25, 4.0 *
years) - principal;
return amount;
}

static const double years_per_month = 1.0 / 12.0;

double monthly_interest(double principal, double rate, double
years)
{
double amount = principal * pow(1.0 + rate *
years_per_month, 12.0 * years) - principal;
return amount;
}

static const double years_per_day = 1.0 / 365.2421875;

double daily_interest(double principal, double rate, double
years)
{
double amount = principal * pow(1.0 + rate *
years_per_day, 365.2421875 * years) - principal;
return amount;
}

double continuous_interest(double principal, double rate,
double years)
{
double amount = principal * exp(rate * years) -
principal;
return amount;
}

typedef enum frequency {
YEARLY = 0, QUARTERLY, MONTHLY, DAILY, CONTINUOUSLY
} frequency;

typedef struct customer_record {
int custid;
double last_balance;
double deposits;
double withdrawls;
double fees;
double rate;
time_t date_of_last_balance;
enum frequency freq;
} customer_record;

static const double seconds_per_day = 1.0 / 86400.0;

/* round number n to d decimal points */

static double round(double n, unsigned d)
{
return floor(n * pow(10., d) + .5) / pow(10., d);
}

void make_500k_customers(void)
{
FILE *foutput = fopen("customer_extract.inp", "wb");
customer_record cr = {0};
int i;
for (i = 1; i <= 500000; i++) {
int irate;
cr.custid = i;
cr.last_balance = rand() * rand() + rand() / (rand() + 1);
cr.last_balance = round(cr.last_balance, 2);
cr.deposits = rand() + rand() / (rand() + 1);
cr.withdrawls = rand() / (rand() + 1);
cr.fees = rand() / (rand() + 1);
irate = 3 + rand() / (rand() + 1);
cr.rate = irate % 200;
cr.rate *= .01;
cr.date_of_last_balance = time(NULL) - rand();
cr.freq = (frequency) rand() % 5;
if (fwrite(&cr, sizeof cr, 1, foutput) != 1) {
printf("Error processing customer %d\n", cr.custid);
}
}
fclose(foutput);
}

int main(int argc, char **argv)
{
double average_balance;
double interest;
customer_record cr;
FILE *finput;
FILE *foutput;
clock_t start, end;
if (argc > 1) {
start = clock();
puts("Creating customers...");
puts("Time includes customer creation.");
make_500k_customers();

}
else
{
puts("Time does not include customer creation.");
start = clock();
}
finput = fopen("customer_extract.inp", "rb");
foutput = fopen("customer_extract.out", "wb");
while (fread(&cr, sizeof cr, 1, finput) == 1) {
double ending_balance = cr.last_balance + cr.deposits
- (cr.withdrawls + cr.fees);
time_t now = time(NULL);
double duration_in_seconds = difftime(now,
cr.date_of_last_balance);
double days = duration_in_seconds * seconds_per_day;
double years = days * years_per_day;
average_balance = (cr.last_balance + ending_balance) * 0.5;
if (average_balance > 0) {
switch (cr.freq) {
case YEARLY:
interest = yearly_interest(average_balance, cr.rate,
years);
break;
case QUARTERLY:
interest = quarterly_interest(average_balance,
cr.rate, years);
break;
case MONTHLY:
interest = monthly_interest(average_balance, cr.rate,
years);
break;
case DAILY:
interest = daily_interest(average_balance, cr.rate,
years);
break;
case CONTINUOUSLY:
interest = continuous_interest(average_balance,
cr.rate, years);
break;
default:
printf("Unexpected interst rate type for customer %d
\n", cr.custid);
break;
}
cr.last_balance += interest;
cr.last_balance = round(cr.last_balance, 2);
cr.deposits = 0;
cr.withdrawls = 0;
cr.fees = 0;
cr.date_of_last_balance = now;
if (fwrite(&cr, sizeof cr, 1, foutput) != 1) {
printf("Error processing customer %d\n", cr.custid);
}
fflush(foutput);
}
}
if (finput)
fclose(finput);
if (foutput)
fclose(foutput);
end = clock();
printf("Total clock ticks to process the interest rates in the
customer file was %u\n", (unsigned) end - start);
return 0;
}
/*
Sample output:
C:\tmp\inp\Release>inp 1
Creating customers...
Time includes customer creation.
Total clock ticks to process the interest rates in the customer file
was 2468

C:\tmp\inp\Release>inp
Time does not include customer creation.
Total clock ticks to process the interest rates in the customer file
was 1875

C:\tmp\inp\Release>inp
Time does not include customer creation.
Total clock ticks to process the interest rates in the customer file
was 1765
*/


.



Relevant Pages

  • Re: Transverse paradox parallel question
    ... To decelerate, that space ship has ... to have a force exerted on it and the gravity mechanism. ... The earth is staying in the same inertial frame. ... Both clocks on the space ship will disagree with their ...
    (sci.physics.relativity)
  • Re: Rate Customers by Invoiced this Year Field
    ... a negative amount in the "Invoiced This Year" field. ... Dim dbAny As DAO.Database ... rank each customer should receive. ... Is it based on a customer's percentage of total company invoices? ...
    (microsoft.public.access.modulesdaovba)
  • Re: Charge for not paying by DD
    ... The difference with a or DC SO is that it is easier for the customer to ... credits the internal account with the amount as being 'paid' at the same ... The account is then debited if the DD bounces, ... So what exactly is the extra cost. ...
    (uk.legal)
  • Re: Adding numeric value to a text "Value list"
    ... let's look at a simple Customer Order system. ... Customer, Order, LineItem, Inventory, Payment ... BalanceDue, a numeric calc field, total order amount minus total payment ...
    (comp.databases.filemaker)
  • Re: Adding numeric value to a text "Value list"
    ... let's look at a simple Customer Order system. ... Customer, Order, LineItem, Inventory, Payment ... BalanceDue, a numeric calc field, total order amount minus total payment ...
    (comp.databases.filemaker)