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.
Related
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
This question already has answers here:
Integer division: How do you produce a double?
(11 answers)
Closed 6 years ago.
I am trying to do simple math. a=5, b=a/2 &(round up), which has to be 5/2 = 3 when I round up , c=b-a, 3-5=2. my question when I divide 5/2 and round up I got 2 instead of 3 for b. can some one help me how I can round up and get 3? Thanks
int a=5;
int b=(int)Math.ceil(a/2);
int c=b-a;
System.out.println(b);
System.out.println(c);
you should use floating-point value of 2 instead of integer in this line:
int b = (int) Math.ceil(a / 2f);//also you can use "2.0" or "2d" instead of "2f"
your version uses int division (which produces int value of 2) and 2f constant forces to use floating-point division and promote a value to float (after it division produces float value of 2.5)
It is possible because of JLS spec for Multiplicative Operators:
Binary numeric promotion is performed on the operands (§5.6.2)
And that is how numeric promotion works for int and float division operands in our case:
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
You can use a little trick to get things faster:
int b =(a + 1) / 2;
Since you are dividing with 2, in case the number is odd with + 1, you'll get exact value for upper rounding. And if number is even with + 1 rounding will give the half of it as expected.
EDIT
Or in general, if you want to calculate Math.ceil(a / b) you can do it with following formula : (a + b - 1) / b, assuming a and b being positive.
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.
int m = 10;
int f = 3;
float r = (float)m/f; // gives 3.333333 as output
float r = (float)(m/f); // gives 3.0 as output
Can anyone tell me how the parentheses are changing the answer because I am basically typecasting the integer value of m/f into float. What I don't understand is how the addition of brackets around m/f is changing the answer.
In the second case:
(float)(m/f)
you are doing integer division first and then casting to float and therefore you lose the fraction. In the first case you cast m to float and therefore end up performing floating point division.
The cast operator has higher precedence in both C++ and Java but using parenthesis around the division forces it to be evaluated first.
In C++ his behavior is due to the usual arithmetic conversions which is covered in the draft C++ standard section 5 Expressions paragraph 10 which says:
Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield
result types in a similar way. The purpose is to yield a common type, which is also the type of the result.
This pattern is called the usual arithmetic conversions, which are defined as follows:
and includes the following bullet:
— Otherwise, if either operand is float, the other shall be converted to float.
In Java this behavior is covered in the JLS section 5.6.2. Binary Numeric Promotion which says:
When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:
and includes:
Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:
and includes:
Otherwise, if either operand is of type float, the other is converted to float.
and includes the following example:
int i = 0;
float f = 1.0f;
// First int*float is promoted to float*float, then
The difference is what gets converted to float. In the first case m gets converted to float, so the entire expression becomes floating point. In the second, you perform the expression (integer division) and then convert to float, at which point it's too late to save those precious significant digits.
(float)m/f divides (float)m by f. Since one of the operands is a float, the operator is floating-point division, and the answer is 3.333 etc.
(float)(m/f) calculates (m/f) and casts it to float. Since both operands are integer, the operation is integer division, and m/f is 3. Then 3 is casted to float to become 3.0.
On the first example, m gets casted to float first then divided which gives you a floating-point number. The second example, the division is an int division so it will give you an int number that then gets transformed to a floating-point number.
Adding parentheses, change precedence of operators. Type casting is applied before division normally but using parentheses you tell compiler to divide before casting to float.
Order of operations: Casting applies before division, and division between two integers always rounds (down) to the nearest integer in Java.
float r = (float)m/f; // Is the same as ((float)m)/f, and because there's a
// float in the division, we keep everything a float.
float r = (float)(m/f); // Is division between two integers, so we round down
// to the nearest integer before casting to a float.
I'm a beginner and there's something that's not making much sense to me. Please could be so kind as to explain where I'm going wrong. I'm sorry if this has been asked before.
Here the presence of the decimal point mean these get evaluated using floating point division.
System.out.println(1/3.0); // this prints: 0.3333333333333333
System.out.println(1.0/3); // this prints: 0.3333333333333333
System.out.println(1.0/3.0); // this prints: 0.3333333333333333
Apparently, this below is an example of "truncating-integer division." It seems a bit weird to me but ok.
System.out.println(1/3); // this prints: 0
Is it ok to say: "in the line below, the (double) cast is evaluated 1st. It effectively says: "treat 1/3 as a double - don't use truncating integer division. instead use floating point division.""
System.out.println((double)1/3); // this prints: 0.3333333333333333
Below, however we get 0.0 - how did that happen?
System.out.println((double)(1/3)); // this prints: 0.0
ok so maybe the extra parentheses mean the (1/3) gets evaluated 1st. It is evaluated using truncating integer division yielding 0. And then the double is applied giving us 0.0 Ok that makes sense
Ok so we maybe can propose a couple of general rules here:
Rule 1: (double) expression means apply the (double) cast first then evaluate the expression.
Rule 2: (double) (expression) means evaluate the expression then apply the cast.
Great!
So in the next line below we have: (int) expression, so I guess we can apply rule 1). The (int) cast is evaluated 1st. It effectively says: "treat 1.0/3 as a int - don't use as much memory as you would with a double. Don't use floating point division, instead apply truncating integer division."" So we have 0 right? No.
System.out.println((int)1/3.0); // this prints: 0.3333333333333333
Ok so we have 0.33333 so the (int) cast is not evaluated 1st. It is as if it wasn't there. Let's propose a 3rd rule:
Rule 3: (int) expression means ignore the (int) cast altogether just evaluate the expression like the (int) isn't even there.
Ok applying rule 3 to the line below, we have (int) but we are just going to ignore it. 1.0/3.0 is evaluated with floating point division and we get 0.3333333. Success!
System.out.println((int)1.0/3.0); // this prints: 0.3333333333333333
And in the last line below, again we have (int) but we are just going to ignore it. (1.0/3) is evaluated using floating point division yielding 0.3333333333 right? No.
System.out.println((int)(1.0/3)); // this prints: 0
Ok now I'm confused. Please could you help me get my head round this?
Java's language parsing rules are basically implying a lot of parentheses everywhere in your code based on its rules of order of operations. Understanding where Java thinks the parentheses are will help you understand this behavior. When you say:
(double) 1 / 3.0
... this is equivalent to saying:
((double) 1) / 3.0
This means that 1 gets converted to a double, and 3.0 is automatically a double, so you'll end up doing a floating point division rather than integer division. The same thing would happen with (double) 1 / 3, because the divisor is a double, so even though the dividend is an int, the system realizes that you want to do floating-point division. The compiler doesn't want you to lose precision unless you specifically ask to, so any time either the dividend or the divisor is a double, it will do double division.
On the other hand:
(int) 1 / 3.0
... is the same as saying:
((int) 1) / 3.0
In this case, you're telling the compiler what it already knew: that the divisor (1) is an int. Then you're asking it to divide by a double value (3.0). Since the dividend is a double, it will perform double division.
As you noted, 1/3 will produce zero, because that's how integer division works and both numbers are integers. The same will happen with 1/(int)3.0 because you're telling the compiler to make the 3.0 into an int before the division will occur (as in 1/((int)3.0)).
The final point to keep in mind is that (int) 0.33 will also get converted to 0, because an integer can't hold decimal values in it. So when you say (int)(1.0/3), you're doing double division, but then you're converting the double into an int afterwards, producing 0.
This is specified in the Java Language Specification - Numeric Promotions
If any of the operands is of a reference type, unboxing conversion (§5.1.8) is performed.
Then:
If either operand is of type double, the other is converted to double.
Otherwise, if either operand is of type float, the other is converted to float.
Otherwise, if either operand is of type long, the other is converted to long.
Otherwise, both operands are converted to type int.
The concept is called widening conversion:
5.1.2 Widening Primitive Conversion
The following 19 specific conversions on primitive types are called the widening primitive conversions:
byte to short, int, long, float, or double
short to int, long, float, or double
char to int, long, float, or double
int to long, float, or double
long to float or double
float to double
The reason why
(int) (1.0/3) == 0
is because you cast the result of 1.0/3 (0.33333... by the above rules) explicitly to an integer, which is equivalent to "floor(result)" (rounding down), so the result is 0.
Cast has a higher precedence than /, that's why the other operations were misleading to your understanding:
(double) 1 / 3
will explicitly cast 1 to a double value 1.0 first, so again the result by the above rules is equal to 0.3333....
The cast is only applied to the expression immediately after it.
Examples:
(int)1/3
applies the cast to the 1. equivalent to ((int)1)/3
(int)(1/3)
the cast is applied to the result of the expression.
(int)((double)1.333*(float)3.167)
getting a little more complicated. 1.333 casted to double,
multiplied by 3.167 casted to a float, with the result casted to an int
Hope that helps!
There are two factors in all those cases:
Operator precedence
When one of the arguments of the division is a floating point number, the result is a floating point number.
I'll give three examples from your question:
(double) (1/3) - first evaluate the expression in parenthesis - (1/3) is an integer division so the result is 0, then cast it to double, you get 0.0
(int) (1.0/3) - first evaluate the expression in parenthesis - (1.0/3) is a floating point division, so the result is 0.3333, then cast it to int, and you get 0
(double) 1/3 - first perform casting so (double)1 becomes 1.0, then evaluate the division 1.0/3 - this is a floating point division, so the result is 0.3333