6

When I do something like this

int test = 5 + 3 * (4 - 1) / 2;

I get 9. I suspected this was because int rounds down. However, when I do this

float test = 5 + 3 * (4 - 1) / 2;

I also get 9. However, when I do this

float test1 = 5;
float test2 = 4.5;
float test = test1 + test2;

Test finally outputs 9.5. Could someone explain the logic behind this? Why don't I get 9.5 in the second example? Thanks.

glcohen
  • 193
  • 1
  • 1
  • 11
  • Integer division is done this way in lots of languages, not just Java. All the C languages act this way: C, C++, C#, Java, JavaScript. – duffymo Aug 27 '12 at 01:12

4 Answers4

17

In your second example, although you are assigning the result to a variable of type float, the calculation itself is still performed exactly the same way as the first example. Java does not look at the destination variable type to determine how to calculate the right hand side. In particular, the subexpression 3 * (4 - 1) / 2 results in 4.

To fix this, you can use floating point literals instead of all integers:

float test = 5 + 3 * (4 - 1) / 2.0f;

Using 2.0f triggers floating point calculations for the arithmetic expression.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • That makes sense, but seems like it'll be a bit of a pain to keep track of. Thank you. – glcohen Aug 26 '12 at 22:47
  • @user1626448: Most of the time, you'll be doing calculations with one or more existing variables, that already have a type of `float` or `double` or whatever. In that case you don't have to worry about this. – Greg Hewgill Aug 26 '12 at 22:51
3

Although you represent the result of 5 + 3 * (4 - 1) / 2 in a float, the actual evaluation is done with the precision of an integer, meaning that the division of 9 / 2 returns 4 rather than the 4.5 you would receive if they were evaluated as floats.

FThompson
  • 28,352
  • 13
  • 60
  • 93
2

Expressions have their own type. So start with:

5 + 3 * (4 - 1) / 2

Each value has its own type. This type happens to be int, so this is the same as:

((int)5) + ((int)3) * (((int)4) - ((int)1)) / ((int)2)

Making it clearer that we're dealing with ints. Only after this is evaluated as 9 does it get assigned to a float.

Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
0

The short answer is that integer types operate on modular arithmetic, with modulus 1, and discard the remainder.

Since you cast test as an integer, modular arithmetic is employed with modulus 1 (e.g. 9.5 mod 1), int test = 5 + 3 * (4 - 1) / 2;

With a 32-or-64 bit float this would give 9.5; however, because you have cast test as an int, the remainder is discarded, and the value referenced by test is 9.