Reputation: 13
I have a function in java that returns an integer. I know what it is supposed to return so I know when it runs correctly or not. Anyway, there is this line of code at some point in a for loop:
If I write it like this
miuf = miuf_ant * nf_ant / nf - ((double) ((t - 1) * hist[t - 1]) / (double) nf);`
the result is fine.
If I write it like this
miuf = (miuf_ant * (nf_ant / nf) - ((double) ((t - 1) * hist[t - 1]) / (double) nf));
the result is way off.
nf_ant
, nf
and t
are int
s, the rest are double
s.
I have evaluated these 2 expressions in the debugger for a few iterations and the results differ by some 0.3 in general. Why does this happen and why is it that one works and the other doesn't?
Upvotes: 0
Views: 319
Reputation: 14165
If nf_ant
and nf
are int
s, your problem is that the second version if performing integer division and not floating point division. You need to cast one of them first.
Let's compare the following two expressions:
miuf_ant * nf_ant / nf
miuf_ant * (nf_ant / nf)
The first one is equivalent to the following by the rules of Java:
(miuf_ant * nf_ant) / nf
What happens here is that the product is evaluated first, and because miuf_ant
is double
, the result is also a double
. Afterwards, the same happends for the division.
In the "bad" (second) case though, because both division operators are int
s, the result is also an int
, losing precission on the operation by effectively truncating the result. This loss of precission is then carried to the product.
Upvotes: 1
Reputation: 234665
In the second case, nf_ant / nf
will be computed in integer arithmetic as the parentheses mean it's evaluated on its own. This loss of the remainder is the cause of the difference.
In the first case it is premultiplied by miuf_ant
which is a floating point type. Since *
and /
have the same precedence, all 3 arguments are promoted to floating point prior to computation.
Upvotes: 1