Luke Thomson
Luke Thomson

Reputation: 1

Compounding interest calculator

My goal is to create a program that asks the user for an amount, asks for the interest rate per year, month or day, asks for how it will be compounded, then asks for the term in either months, days or years.

It ill then print the future value along with the total interest gained. This is what I have so far and the numbers are incorrect. if anyone could help revise this and make it work i would be very grateful.


import java.util.Scanner;

public class Compunding {

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        double compoundingTerms;
        double period = 0;

        System.out.println("Enter an amount of money: ");
        double amount = sc.nextDouble();
        System.out.println("Enter an rate of Interest: ");
        double rate = sc.nextDouble();
        System.out.println("Enter per years, months, or days: ");
        String time = sc.next();
        System.out.println("Enter how it will be componded monthly, semi-anually, quarterlly, anually: ");
        String compoundRate = sc.next();
        System.out.println("Enter the term amount: ");
        double term = sc.nextDouble();
        System.out.println("Enter the term type (Monthy,Yearly,Daily}: ");
        String termType = sc.next();

        if (time.equals("years")) {
            period = 1;
        }
        if (time.equals("months")) {
            period = 12;
        }
        if (time.equals("days")) {
            period = 365;
        }

        if (compoundRate.equals("monthly")) {
            rate = (rate / 100) / 12;
            term = term * 12;
        }
        if (compoundRate.equals("semi-anually")) {
            rate = (rate / 100) / 2;
            term = term * 2;
        }
        if (compoundRate.equals("quarterlly")) {
            rate = (rate / 100) / 4;
            term = term * 4;
        }
        if (compoundRate.equals("anually")) {
            rate = rate / 100;
            term = term * 1;
        }

        double compoundPayment = 0;

        for (int i = 1; i <= term; i++ ) {
            if (i % period == 0 ) {
                colInterest(amount, rate);
            }
            compoundPayment = amount * (1.0 + rate);
        }

        System.out.println("The Final payment will be: " + compoundPayment);
    }

    public static double colInterest(double valueAmount, double valueInterest) {
        return valueAmount * valueInterest;
    }
}

Upvotes: 0

Views: 336

Answers (1)

Jeremy Kahan
Jeremy Kahan

Reputation: 3826

So there were a number of issues with the original calculation and what was posted. compoundPayment was set outside the for loop, and only once, so that compounding did not occur. Also, the term type was requested but not used, so every term was assumed to be years. I think it's also just hard to follow the logic of the for loop with the mod (I get it, that when we hit a day on which things are compounded, we give interest), but it's tricky to keep track of the various units (so I went for years, but one could make a case for days and a loop like yours). I did simplify and assume the rate given was annual, but you could make it daily and multiply by 365, or monthly and multiply by 12, or, just make sure your period and days have the same unit.

It's also the case that the choice of Double as opposed to BigDecimal to represent the money is one where I followed you lead and am answering the question asked. I'm not arguing what I'm answering here is the best possible approach (and one could enhance by using Currency as opposed to assuming it's in dollars).

One different approach would be to use exponents to work with repeated multiplications, or, even if not, to simplify the for loop (which allows you to do things like print statements along the way and allow for rounding of currency).

I am not fixing potential enhancements like that there aren't always 365 days in a year or formatting the decimals nicely or checking input more vigorously. I am trying to give a sense of a possible way to go.

One subtlety is the cast to (int) for numPeriods, which will, assuming the other parts worked (and I tested that 364 days compounded annually gave no interest, but 365 did), make sure not to give partial interest for periods not completed.

I hope that helps.

import java.util.Scanner;

public class Compounding {
private Scanner sc;

Compounding() {
    sc = new Scanner(System.in);
}


public double getAmount() {
    //enhancement: catch number format exceptions, negative numbers, etcetera, and presumbaly use a loop to retry
    System.out.println("Enter an amount of money: ");
    return sc.nextDouble();
}

//return interest as a rate
public double getInterestRate() {
    //enhancement, validate input, catch errors
    System.out.println("Enter an annual percent rate of interest: ");
    double rate = sc.nextDouble();
    return rate / 100;
}

public int getTimesCompoundedPerYear() {
    System.out.println("Enter how it will be componded monthly, semi-anually, quarterly, anually: ");
    String compoundRate = sc.next();
    if (compoundRate.equals("monthly")) {
        return 12;
    } else if (compoundRate.equals("semi-anually")) {
        return 2;
    } else if (compoundRate.equals("quarterly")) {
        return 4;
    } else if (compoundRate.equals("annually")) {
        return 1;
    } else {
        System.out.println("Unrecognized compounding, defaulting to monthly");
        return 12;
    }
}



//return term amount, units still tbd
//allowing for decimals in case someone says 6.5 years for dsomey=thing compounded more than once a year
public double getTermAmount() {
    //enhancement, validate input, catch errors
    System.out.println("Enter term amount: ");
    return sc.nextDouble();
}

public String getTermUnits() {
    System.out.println("Enter the term type (years, months, days): ");
    String termType = sc.next();
    if (termType.equals("years") || termType.equals("months") || termType.equals("days")) {
        return termType;
    } else {
        System.out.println("Unrecognized time period, defaulting to years.");
        return "years";
    }
}


public static void main(String[] args) {
    Compounding compounding = new Compounding();
    double period = 12;
    double amount = compounding.getAmount();
    double annualRate = compounding.getInterestRate(); //interest rates are always quoted as annual, no need to vary that
    int timesCompoundedPerYear = compounding.getTimesCompoundedPerYear();
    double term = compounding.getTermAmount();
    String termUnits = compounding.getTermUnits();
    double ratePerPeriod = annualRate / timesCompoundedPerYear;
    double timeInYears = term;
    if (termUnits.equals("months")) {
        timeInYears /= 12;
    } else if (termUnits.equals("days")) {
        timeInYears /= 365;
    }
    int numPeriods = (int) timeInYears * timesCompoundedPerYear;



    double compoundPayment = amount * Math.pow(1 + ratePerPeriod, numPeriods);

    System.out.println("The Final payment will be: " + compoundPayment);
}
}

Upvotes: 1

Related Questions