Code:
/*
** Copyright: New Ink -- Henry
** For display and educational purposes at cprogramming.com.
**
** Problem statement:
** Calculate compound interest (to the nearest whole percent), using
** only integer data types.
**
** Compound interest formula:
** at = a0 * (1 + r)^t
** with at, a0 and r elements of the (two decimal place [2D]) real numbers and
** t an element of the natural numbers.
**
** Let:
** a0 = round(A0 / 1000),
** r = R / 100, and
** at = round(At / 1000)
**
** Substituting:
** At/1000 = A0/1000 * (1 + R/100)^t
** with At, A0, R and t elements of the natural numbers
** At = 10^(-2t) * A0 * (100 + R)^t
**
** Now to manage the precision on the interest compounded:
** Since, (100 + R)^t will grow rather quickly, it is advantageous to
** calculate how many digits are participating in the multiplication.
**
** t = 1 ==> 105 (both decimal places) or 1.05
** t = 2 ==> 11025 (four decimal places) or 1.1025
** t = 3 ==> 1157625 (six decimal places) or 1.157625 of which only six
** participate in the calculation to the nearest fraction of a penny.
** t = 4 ==> 121550625 (eight decimal places) or 1.21550625 of which only six
** pariticpate...
**
** Inductively this appears as 0, 0, 0, 2, 4, 6...divisions by 10 as t is
** increased by one. Since, 2n produces the even number sequence, offset it
** it by three even numbers to produce 2n - 6, or -4, -2, 0, 2, 4. Because, -4,
** -2 and 0 are not larger than the loop variable the loop does not run.
**
** Taking this into account with the 3 signficant digits on the amount,
** t = 1 ==> 2D + 3D = 5D of which we only require 3
** t = 2 ==> 4D + 3D = 7D
** t = 3 ==> 6D + 3D = 9D because we constrained the interest to three
** extra digits
** t = 4 ==> 6D + 3D = 9D...
*/
#include <stdio.h>
unsigned long long int myPow( int base, int exp );
void printIntroduction();
void printColumns();
void printDecimal( int integer, int decimal );
void printTable( const int duration, const int principle, const int rate );
int main()
{
int duration;
int principle;
int rate;
printIntroduction();
principle = (1000.00f) * 1000;
rate = (0.05f) * 100;
duration = 10;
printTable( duration, principle, rate );
return 0;
}
unsigned long long int myPow( int base, int exp )
{
unsigned long long int result = 1ULL;
while( 0 < exp )
{
result *= (unsigned long long int)base;
exp--;
}
return result;
}
void printIntroduction()
{
fprintf( stdout, "This program calculates compound interest.\n\n" );
return;
}
void printColumns()
{
fprintf( stdout, "%4s%21s\n", "Year", "Amount on deposit" );
return;
}
void printDecimal( int integer, int decimal )
{
if( 0 > decimal || 99 < decimal )
{
fprintf( stderr, "Number format error: %d.%d\n", integer, decimal );
}
else if( 10 > decimal )
{
fprintf( stdout, "%18d.0%d", integer, decimal );
}
else
{
fprintf( stdout, "%18d.%d", integer, decimal );
}
return;
}
void printTable( const int duration, const int principle, const int rate )
{
unsigned long long int result;
int year;
int k;
printColumns();
for( year = 1; year <= duration; year++ )
{
result = ((unsigned long long int)myPow( 100 + rate, year ));
// truncate extra digits from the interest
for( k = 0; k < 2*year - 6; k++ )
{
result /= 10ULL;
}
// multiply principle
result *= ((unsigned long long int)principle);
// truncate extra digits from the principle*growth
if( 1 == year )
{
result /= 100ULL;
}
else if( 2 == year )
{
result /= 10000ULL;
}
else
{
result /= 1000000ULL;
}
// round to the nearest fraction of a penny
if( 5 <= ( result % 10 ) )
{
result += 10ULL;
}
// truncate the fraction of a penny
result /= 10ULL;
fprintf( stdout, "%4d", year );
printDecimal( result / 100ULL, result % 100 );
fprintf( stdout, "\n" );
}
return;
}
The output is: