Colin Seng
Colin Seng

Reputation: 39

Why is the value I'm getting different for 2 similar programs below even though i only changed the type for the method's value

Code 1: Class 1

import java.text.NumberFormat;

public class testing2 {
int balance;

void addInterest(int rate) {
    balance += balance*(rate/100);

}

void display() {
    NumberFormat currency = NumberFormat.getCurrencyInstance();

    System.out.print ("The balance is ");
    System.out.print(currency.format(balance));

    }
}

Class 2

import java.util.Random;

public class testing {

public static void main (String args[]) {

    testing2 aTesting = new testing2();
    Random Myrandom = new Random();

    aTesting.balance = Myrandom.nextInt(501);
    int rate2 = 5;

    System.out.println("Current balance: " + aTesting.balance);
    System.out.println("Current rate: " + rate2);

    aTesting.addInterest(rate2);

    aTesting.display();

    System.out.println();
    }
}

OUTPUT:

Current balance: 327 Current rate: 5 The balance is MYR327.00

Code 2: Class 1

import java.text.NumberFormat;

public class testing2 {
double balance;

void addInterest(double rate) {
    balance += balance*(rate/100);

}

void display() {
    NumberFormat currency = NumberFormat.getCurrencyInstance();

    System.out.print ("The balance is ");
    System.out.print(currency.format(balance));

    }
}

Class 2

import java.util.Random;

public class testing {

public static void main (String args[]) {

    testing2 aTesting = new testing2();
    Random Myrandom = new Random();

    aTesting.balance = Myrandom.nextInt(501);
    double rate2 = 5;

    System.out.println("Current balance: " + aTesting.balance);
    System.out.println("Current rate: " + rate2);

    aTesting.addInterest(rate2);

    aTesting.display();

    System.out.println();
    }
}

OUTPUT:

Current balance: 170.0 Current rate: 5.0 The balance is MYR178.50

CONCLUSION: The first program does not change the final value of the balance whilst the 2nd program does. What is the reason for this? I only changed the type of the variable from int to double and nothing more.

Upvotes: 1

Views: 71

Answers (5)

Persixty
Persixty

Reputation: 8589

This is a classic problem for beginners. I'm surprised I can't find a really good explanation. This one is a bit helpful:

Why is the result of 1/3 == 0?

In Java how an operation like division (/) is performed depends on the types of the operands. In a/b a and b are the operands. If you divide integer by integer it performs integer division. The means taking the whole number part and discarding the remainder. In that method (56/100) == 0 but (156/100) == 1 no rounding.

To force floating point arithmetic make sure one of the operands is double for example try:

void addInterest(int rate) {
    balance += balance*(rate/100.0);
}

The compiler will interpret 100.0 as double then perform the calculation in floating point arithmetic (probably what you were expecting) and then take the integer value to add to balance.

Footnote 1: Never use double for currency values. Use java.math.BigDecimal there a number of rounding oddities in double arithmetic that cause problems in financial calculations. double can't represent 0.01 precisely and accumulating rounding errors inevitably cause some confusion when (0.01+0.01+0.01+0.01+0.01+0.01)!=0.06 for example. You can fudge round it with tolerances but in financial systems of any real size you will eventually go outside it.

Footnote 2: Why does Java work like this? Integer arithmetic is useful for many algorithms and in loops performing millions of increments will never 'drift off' like we can see happening after just 6 operations above!

Upvotes: 0

Vasu
Vasu

Reputation: 22442

The first program does not change the final value of the balance whilst the 2nd program does. What is the reason for this ?

It is all about double vs integer arithmetic.

void addInterest(double rate) {
   balance += balance*(rate/100);
}

In the second program, when you call addInterest(double rate), the value of rate passed from main() will be type-casted into double variable (which is the type defined by addInterest method signature) and then balance*(rate/100) will be calculated like below:

When rate is double: rate/100 = 5/100 = 0.05

But, when rate is integer: rate/100 = 5/100 = 0 (intgers strip all decimals)

Upvotes: 1

Sweeper
Sweeper

Reputation: 272895

If you declare two variables as integers and divide them:

int a = 4;
int b = 5;
System.out.println(a / b);

You'll not get 0.8.

In Java, an integer divided by an integer is always an integer and since the mathematical result, 0.8 is not an integer, it is rounded down to get 0. If you want to get the result 0.8, you need to make either a or b a double.

In Code 1, your addInterest method gets a argument value of 5 and this happens:

balance += balance*(rate/100);

Since rate and 100 are all integers, the result must be an integer. Therefore, the mathematical result 0.05 is rounded down to get 0. And as we all know, anything that is multiplied by 0 is 0. As a result, after the right side is evaluated, the assignment statement looks like this:

balance += 0;

Upvotes: 1

Kacper
Kacper

Reputation: 4818

In first case you're doing

int balance = 327;
int rate = 5;
balance += balance * (rate / 100);

When you do division on int result is also int, so result of division rate / 100 is (int)rate / 100 what gives(int)0.05 which is 0. What gives balance += balance * 0 that's why balance hasn't changed in first program.

When you change your variables and parameters to double there is no truncating values so all calculations go as you expect.

Upvotes: 1

DevilsHnd - 退した
DevilsHnd - 退した

Reputation: 9192

It's because in your first you have:

int rate2 = 5;

and in your second you have:

double rate2 = 5;

You should be using double when dealing with currency type values.

Upvotes: 0

Related Questions