-1

I was interested to see a weird error when performing the following:

int width = 300;
int var1 = width/3;
int var2 = width * 1/3;
int var3 = width * 2/3;
int var4 = width*(1/3);
int var5 = width * (int)(1/3);
int var6 = (int)(width*(1/3));

System.out.println("Var1: " + var1);
System.out.println("Var2: " + var2);
System.out.println("Var3: " + var3);
System.out.println("Var4: " + var4);
System.out.println("Var5: " + var5);
System.out.println("Var6: " + var6);

Output is this:

Var1: 100
Var2: 100
Var3: 200
Var4: 0
Var5: 0
Var6: 0

Why do the last three operations return 0? The parenthesis around the 1/3 seems to change something with how it performs the calculation, but even trying to case it into an int did not change the output.

I'm using the BlueJ IDE and Java version 1.7.0_17


EDIT

I found the answer. It's due to the order of operation. The parens cause the division to occur first, and with an int 1/3 or 2/3 will always equal 0. If I allow the width * 2 to occur before dividing by 3 everything is OK because the number is larger than 1.

Sometimes it's just basic math... :)

ProfessionalAmateur
  • 4,447
  • 9
  • 46
  • 63
  • 1
    just try printing `1/3` as an int and you will see why. – Praveen Lobo Jun 18 '13 at 02:35
  • 1
    It's not the order that matters as much as the _semantics_ of the `/` operator in Java. If a division is applied between two integers the result is an integer, possibly truncating values. That's why `1/3 == 0` and `1/3.0 ~= 0.3333333` – Óscar López Jun 18 '13 at 02:42

2 Answers2

3

For the fourth case try this, notice that by adding a decimal point we're forcing a decimal division, not an integer division as it was before:

int var4 = width*(1/3.0);

For the last two cases, try this instead - although this ends up being equivalent to other cases before!

int var5 = width * (1/3);
int var6 = (width*(1/3));

Notice that (int)1/3 is 0, the cast is making the division return 0, and 0 times anything will return ... well, 0. There's no way those two cases are going to work if you leave the cast in place.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • Which option are you referring to? The one where I cast the whole operation as an `int`? Why do `var1`, `var2` & `var3` work and the others do not? Order of operation? – ProfessionalAmateur Jun 18 '13 at 02:32
  • Downvoter, care to comment? I cleaned up my explanation, I believe is fine now. – Óscar López Jun 18 '13 at 02:39
  • I didnt down vote you. The issue is due to the order of operation, you are correct that 1/3 as an in will be zero, the first 3 test above work because the multiplication occurs before the division and the answer is always greater than 1. If I try to perform the division first the answer will always be zero. I feel like an idiot because I knew this and just didn't think it through and thought I could cast away the issue. Whoops. Appreciate the answer. – ProfessionalAmateur Jun 18 '13 at 02:43
1

It's relevant, so see Order of Precedence as well.

Ken
  • 30,811
  • 34
  • 116
  • 155