Reputation: 39
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
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
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
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
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
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