Mortgage calculator floating point math wrong result in Rust

Viewed 62

I am learning rust and I thought I would try to make a mortgage calculator with it.

/*
input:
home sale price: 100k
down payment amount: 0
interest rate and the terms of interest rate, ie 5yr 5% fixed, so 60 payments
amortization period: 30 yr mortgage
payment frequency: monthly 
 
*/  

#![allow(unused_variables)]
#![allow(dead_code)]
#![allow(unused_must_use)]

use std::process;
use std::error::Error;

struct Mortgage {
    f64_purchase_price: f64,
    f64_down_payment: f64,
    i32_amortization_period: i32,
    f64_interest_rate1: f64,
    i32_interest_rate_term1: i32,
}


impl Mortgage {
    fn parse_args(args: &[String]) -> Result<Mortgage, &'static str> {

        if args.len() < 5 {
            return Err("not enough arguments");
        }
        
        
        let purchase_price= &args[1];
        let down_payment= &args[2];
        let amortization_period= &args[3]; // in months
        

        let interest_rate1 = &args[4];
        let interest_rate_term1 = &args[5];// in months

        
    

        let f64_purchase_price: f64 = purchase_price.parse().unwrap();
        let f64_down_payment: f64 = down_payment.parse().unwrap();
        let i32_amortization_period: i32 = amortization_period.parse().unwrap();
        

        let f64_interest_rate1_annual: f64= interest_rate1.parse().unwrap(); //assume monthly
        let f64_interest_rate1=f64_interest_rate1_annual/12.0;
        let i32_interest_rate_term1 :i32= interest_rate_term1.parse().unwrap();

        
        println!("purchase price {:?} down payment {:?} amortization period {:?} interest rate montly {:?} term {:?} ", f64_purchase_price, f64_down_payment, i32_amortization_period, f64_interest_rate1,i32_interest_rate_term1);



        Ok(Mortgage{f64_purchase_price, f64_down_payment,i32_amortization_period,f64_interest_rate1,i32_interest_rate_term1})


    }
}
 
fn calculate(mortgage: Mortgage) -> Result<(), Box<dyn Error>> { 

    let principle: f64 = mortgage.f64_purchase_price-mortgage.f64_down_payment;
 
    let bottom_rate: f64 = 1.0+mortgage.f64_interest_rate1;
    let bottom_rate_power: f64 = bottom_rate.powf(f64::from(mortgage.i32_interest_rate_term1));
    let bottom = bottom_rate_power - 1.0;
 
    let top: f64 = mortgage.f64_interest_rate1*bottom_rate_power;

    let monthly_payment=principle*(top/bottom);

    
    println!("principle payment: {:?}", principle);
    println!("top: {:?}", top);
    println!("bottom: {:?}", bottom);
    println!("monthly payment: {:?}", monthly_payment);

    Ok(())
}
fn main() {
    let args: Vec<String> = std::env::args().collect(); // get all arguments passed to app 
      
    let mortgage = Mortgage::parse_args(&args).unwrap_or_else(|err| {
        println!("Problem parsing arguments: {err}");
        process::exit(1);
    });


    calculate(mortgage);
 

}

So I ran it with 100k, 30 yr mortgage, 5% interest, 5 yr term


cargo run -- 100000 0 360 0.05 60
purchase price 100000.0 down payment 0.0 amortization period 360 interest rate montly 0.004166666666666667 term 60 
principle payment: 100000.0
top: 0.0053473278270979654
bottom: 0.2833586785035118
monthly payment: 1887.1233644010988

This payment is off from the online calculator here: https://itools-ioutils.fcac-acfc.gc.ca/MC-CH/MCCalc-CHCalc-eng.aspx. My program's monthly payment is 1887 while the online tool is closer to 500 dollars.

the top and bottom mentioned in the code corresponds to this formula: M = P [ i(1 + i)^n ] / [ (1 + i)^n – 1] the P is the principle, top is the stuff above the division line and bottom is the stuff below the division line.

So is the issue I am having because I am using float 64? I don't think I implemented the formula wrong but why I am getting 41k for motnly payment. I thought float 64 would make sense because you can have 100000.34 for price, and interest rate is 5.5%.

0 Answers
Related