What does -1+ (int) mean? - java

I have a line of code in java, but I don't know how to explain how it works, someone knows what the -1+ (int) means
-1+ (int) ((Math.random () * (3)));

The (int) actually goes with the next portion of code: it casts the result of ((Math.random () * (3))) to an integer. (This will simply drop the decimal portion; it will not round).
Math.random() returns a number that is greater than or equal to 0.0 and less than 1.0.
((Math.random () * (3))) simply returns a double that is greater than or equal to 0.0 and less than 3.0, which will, as I just mentioned, subsequently be cast to an int. (This will result in a number between 0 and 2; 3 isn't possible).
Adding -1 to something is equivalent to subtracting 1.
So, this will result in a random integer between -1 and 1 (inclusive).

someone knows what the -1+ (int) means
This is the wrong way to look at it. Instead, you should break it down this way:
The + is adding two things together. On the left we have -1 a literal integer. On the right we have (int) ((Math.random () * (3))). Now we can break down what's in the parentheses. First we multiple two values, the result of Math.random() and the value (3). The result is a floating point number and the (int)` casts it to an integer.

What does -1+ (int) mean?
You are having problems understanding this is because you haven't grasped Java precedence rules and (apparently) what a type-cast looks like.
Lets start with this part:
((Math.random () * (3)))
That means:
call the Math.random() method
multiply the result by 3.
Note that there some extra parentheses here that aren't necessary. We could just write it as:
(Math.random() * 3)
Now lets look at the original expression:
-1 + (int) ((Math.random() * (3)));
In the above (int) means type-cast. Cast the type of the "following" to the type in the parentheses. In this case, it says
"cast the random number multiplied by 3 to an int". That will perform a primitive conversion of that value to int.
Next, the -1 means the number "minus one", and the + means addition. So the whole thing means
Add -1 to a random number multiplied by 3 and converted to an integer.
What is the conversion actually there for?
Well Math.random() actually produces a double value between 0.0 (inclusive) and 1.0 (exclusive). And multiplying that by 3 gives another double value. So the (int) cast is converting the double to an int.
Which tells us the complete meaning of that expression:
Generate a random integer in the range -1 to +1.
I mentioned the precedence rules. These are the rules that (in effect tell you what the subexpressions are. For example
a * b + c
means
(a * b) + c
because * has higher precedence than +.
So in our example we have the following operators:
The - in -1 is a unary minus (negation)
The + is binary plus (addition)
The (int) is a type cast
The Math.random() is a method call
The * is a binary multiplication
The ( ... ) are parentheses.
The order of precedence for these operators is
parentheses highest
method call
negation
type cast
multiplication
addition
So you can see that we needed the outside parentheses in (Math.random() * 3) so that the type cast applies to the product rather than (just) result of the method call.
Here is a table showing the precedence of all operators (and similar) in Java 11:
Operator precedence in Java

Related

Why does (int)(2/0.9) = 2?

I put this into java and I was given the result 2. Was wondering why it isn't an ArithmeticException, as shouldn't (int)(2/0.9) turn into 2/0. All help is appreciated.
Your code is
(int) (2 / 0.9)
So the int-cast is only applied to the result after computing 2 / 0.9. Now 2 / 0.9 divides an int by a double value. In such a case the int will also be interpreted as double (2.0 in this case). The result is thus like
2.0 / 0.9 = 2.22...
This process is known as numeric promotion (it uses widening primitive conversion here JLS§5.1.2). From JLS§5.6:
A numeric promotion is a process by which, given an arithmetic operator and its argument expressions, the arguments are converted to an inferred target type T. T is chosen during promotion such that each argument expression can be converted to T and the arithmetic operation is defined for values of type T.
After that you cast to int which will round the value to the next lower integer, 2 in this case. Thus the result is 2.
What you expected would be the result of an expression like
2 / (int) 0.9
// or more explicit:
2 / ((int) 0.9)
which first casts the 0.9 to an int before dividing. In this case you would correctly get
2 / 0
yielding the expected ArithmeticException.

Division value casted to double with tricks in parentheses

The following code with presence and absence of parentheses produce different output. Why?
System.out.println((double) 3/6); // output 0.5
System.out.println((double) (3/6)); // output 0.0
Because in the first example you are actually doing ((double) 3)/6, and therefore the result is a double too.
In the second one, you are performing an integer division, and then you are casting the result. 3/6 = 0, and (double) 0 = 0.0.
In the first example, you are casting 3 to a double before dividing by an int. According the Java type conversion rules, the output is a double(0.5 in this case).
In the second example, you are dividing an int by an int. Since the number you are dividing is smaller than the number you are dividing with, the answer is zero. Then you are simply casting int 0 to double 0.

Parentheses and order of operations

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 ints, the rest are doubles.
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?
If nf_ant and nf are ints, 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 ints, 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.
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.

Java int cast returns 0

I have the following code:
int i = (int) 0.72;
System.out.println(i);
Which yields the following output:
0
I would of imagined that the variable i should have the value of 1 (since 0.72 > 0.5 => 1), why is this not the case?
(I imagine that when casting to int, it simply cuts of the decimal digits after the comma, not taking into account of rounding up; so I'll probably have to take care of that myself?)
Correct, casting to an int will just truncate the number. You can do something like this to get the result you are after:
int i = (int)Math.round(0.72);
System.out.println(i);
This will print 1 for 0.72 and 0 for 0.28 for example.
Because when you cast a double to int, decimal part is truncated
UPDATE Math.round will give your desired output instead of Math.ceil:
System.out.println(Math.round(0.72));
// will output 1
System.out.println(Math.round(0.20));
// will output 0
You can use Math.ceil :
System.out.println(Math.ceil(0.72));
// will output 1
System.out.println(Math.ceil(0.20));
// will output 1
Casting to an int implicity drops the decimal part. That's why you get 0 because anything after the 0 is removed (in your case the 72). If you want to round then look at Math.round(...)
Explicit cast does a conversion a float/double value to an int variable (which discards the fractional part)
Java does not round-off the number like we do.It simply truncates the decimal part.
If you want to round-off the number use java.lang.Math
Casting double to int truncates the non-integer portion of the number.
To round numbers as you describe, use Math.round()
As a complete Java beginner, and just in case my experience is useful to someone, I was just making the following mistake:
int x = (int) Math.random() * 10;
... which will always set x to 0. Instead, I should've done int x = (int) (Math.random() * 10);.
Not much of a Java-know-how specific mistake, but I'll just throw this in case anyone puzzled by this stumbles upon this question.

How to calculate integer expression in Java

Suppose, I need to calculate 3 * (2 / 3) = 2 but 3 * (2 / 3) = 0 in integer arithmetic. So, it looks like I should use floating-point arithmetic 3 * (2.0 / 3) = 2.0 and cast the floating point result to int.
Does it make sense? How would you avoid casting here?
In this particular example, you may be better off rearranging the expression as 3 * 2 / 3, or as 3 / 3 * 2. This way you'll get the exact result using integer math alone.
Using floating-point math is the more general solution, but you need to be aware of rounding issues. In general, you shouldn't expect that x * (y / x) would give you exactly y when x and y are floating-point numbers.
If you know that the result is an integer, or simply want to round it to the nearest integer, you could use Math.round():
Math.round(3 * (2f / 3))
Simply casting the result to int is not a good idea since floating-point numbers are inexact, and such a cast would simply truncate the number.
You can't avoid casting. You can either use integer division or you can use full division but then arguments and result will be in floating point.
You can try moving around the expression parts to bring out the integer division to the top level. In your case you could transform 3 * (2 / 3) to (3 * 2) / 3 which will result in 2 without any floating point operations.
* and / have the same precedence, so omitting the parentheses will provide you with a correct result of the example.
Casting (or truncating) is unavoidable otherwise.
Personally I would re-arrange the equation to be:
3 / 3 * 2 = 2
But not sure if thats what you need. You could try doing the calculation on float's and then use round() to round it up or down to the nearest integar.
This is because of the integer division. In these kinds of expressions you are better off using float, yes.
You can avoid the explicit casting only if you are using the compound operator. The compound operator does an automatic cast for you.
int a = 3;
a *= (2.0/3);
System.out.println(a);
What exactly is it you want to achieve? Using integer arithmetic the result depends on where you set you parentheses. (a/b) * (c/d) * (e/f) will, as you noticed yourself, in general result in something different than (a*c*d) / (b*d*f), even though mathematically both expressions are equal. Nontheless both expressions may be correct depending on the task you want to solve. I do miss a clear statement of this.
If you are looking for the integer closest to the mathematically correct value just calculate nominator and denominator seperately and then perform the division. This way intermediate errors do not occur. If not you need to reformulate your question.

Categories

Resources