I have a java class as follows:
class A{
public static void main(String[] args){
int a=10;
a*=a++ +a;
System.out.println(a);
}
}
Output:210
In my opinion the output should be 231 calculated as follows:
a*=10+11;
a*=21;
a=a*21;
a=11*21;
a= 231;
Can anyone please explain me where am I wrong and why?
In any statement of the type:
x *= y;
The initial value of the LHS is evaluated before the RHS. So your statement:
a *= a++ + a;
Is equivalent to:
a = a * (a++ + a);
Which sets a to the value 10 * (10 + 11) => 210.
If you're particularly interested in the formal specification related to this point you can find it here which contains the rule "If the operator is a compound-assignment operator (§15.26.2), then evaluation of the left-hand operand includes both remembering the variable that the left-hand operand denotes and fetching and saving that variable's value for use in the implied binary operation."
Consider 15.7.1. Evaluate Left-Hand Operand section of java specs where it says - First, the left-hand operand is evaluated to produce a variable then the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator
In your case it is a = 10 * ((11)+10) = 201
Related
class Output
{
public static void main (String[] args)
{
int a = 5;
a += 5+ (++a) + (a++);
System.out.print(a);
}
}
Evaluation:
a += 5 + (++a) + (a++)
=> a+= 5 + 6 + (a++) [++a :increment value of a and then use it. So:increment a = 6, then use a=6]
=> a+= 5 + 6 + 6 [a++ :use and then increment value of a. So: use a=6, then increment a=7]
=> a+= 11 + 6
=> a+= 17
=> a = a+17
=> a = 7 + 17
=> a = 24
The += operator, like all compound operators, evaluates the variable on the left first, before evaluating all other operands, and before any operations are actually performed. This is specified by the JLS, Section 15.26.2:
If the left-hand operand expression is not an array access expression, then:
First, the left-hand operand is evaluated to produce a variable. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason; the right-hand operand is not evaluated and no assignment occurs.
Otherwise, the value of the left-hand operand is saved and then the right-hand operand is evaluated. If this evaluation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
Otherwise, the saved value of the left-hand variable and the value of the right-hand operand are used to perform the binary operation indicated by the compound assignment operator. If this operation completes abruptly, then the assignment expression completes abruptly for the same reason and no assignment occurs.
Otherwise, the result of the binary operation is converted to the type of the left-hand variable, subjected to value set conversion (§5.1.13) to the appropriate standard value set (not an extended-exponent value set), and the result of the conversion is stored into the variable.
(bold emphasis mine)
That means that a is evaluated (and saved) to 5 on the left side before the a++ and ++a are evaluated on the right side. The right side does evaluate to 17, but because the left side is still 5, the sum is 22, not 24.
The expression
a += 5 + (++a) + (a++);
is equivalent to
a = a + 5 + (++a) + (a++);
Meaning that the new assigned value of a is the sum of the operands from right to left (because of left-to-right associativity) evaluated in the following way:
take the variable a: evaluated as 5
add the constant 5
increment the variable a and then evaluate the result: 6
evaluate the variable a and then increment it. The value used in the sum will be the evaluated value: 6
The sum is 22.
This question already has an answer here:
What is the type of a ternary expression with int and char operands? [duplicate]
(1 answer)
Closed 2 years ago.
This subject is already asked but I didn't understand it.
You'll find my program below. When I run this program it prints X and 88. When I remove do the declaration of int i = 0 it returns X and X. I found some explanations here : Unexpected output when using a ternary operator and final variable but i didn't understand it so much. I don't understand why this program returns X and 88 instead of X and X.
public class Ternary {
public static void main(String[] args) {
char x = 'X';
int i = 0;
System.out.println(true ? x : 0);
System.out.println(false ? i : x);
}
}
please read the rules of ternary operator here
https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25
1st one is result of If one of the operands is of type T where T is byte, short, or char, and the other operand is a constant expression of type int whose value is representable in type T, then the type of the conditional expression is T. T being type char in this case and constant expression being 0
so the output is of type char which is x
2nd one is case for Otherwise, binary numeric promotion is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands.
read about binary numeric promotion here https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2
last case of point 2 applies here Otherwise, both operands are converted to type int. and converting char to int gives its ascii value which is 88
and hence the output is 88
We are asked to use for int variables to make the answer equal 20. We are only supposed to change the placement of the plus's and minuses. They have a minus in front of int a. Does that make int a negative?
I've googled the answer but my Googlefu isn't up to par.
public static int a = 1;
public static int b = 3;
public static int c = 9;
public static int d = 27;
public static void main(String[] args) {
int result = - a + b - c + d;
}
In the expression:
- a + b - c + d
there are 3 different operators, going left to right:
Unary minus operator
Binary plus operator
Binary minus operator
(Binary plus operator again)
In general, unary operators have higher precedence than binary operators, so this expression is equivalent to:
(( (- a) + b) - c) + d
So, the unary - applies to the a. From the linked specification above:
At run time, the value of the unary minus expression is the arithmetic negation of the promoted value of the operand.
So, it doesn't make a negative, it results in an expression whose value is the negation of a. This happens to be negative, because a has a positive value. However, it doesn't make a anything, a is left unchanged.
The only way to actually make a negative would be to reassign it:
a = -Math.abs(a);
For a more elaborate answer please have a look at the java language specification, where you can find detailed information on how operators and expressions are evaluated in java (in your case: https://docs.oracle.com/javase/specs/jls/se12/html/jls-15.html#jls-15.15.4)
This question already has answers here:
Why don't Java's +=, -=, *=, /= compound assignment operators require casting?
(11 answers)
Adding int to short [duplicate]
(3 answers)
short plus short is an int [duplicate]
(2 answers)
Closed 4 years ago.
I just can't understand the difference between this:
short d = 0;
//some code
node.accessible = d + 1;
and this
short d = 0
//same code here
node.accessible = d;
node.accessible += 1;
the second thing is working, but the 1st one is't inteliji showes "incompatiable types" error.
p.s. node class:
public class Node {
int n;
short accessible;
Node(int n){
this.n = n;
this.accessible = -1;
}
}
In the first version :
node.accessible = d + 1;
d + 1 produces a int as summing an int and a short produces an int.
The JLS states indeed that (look at the last case, emphasis is mine) :
5.6.2. Binary Numeric Promotion
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:
If any operand is of a reference type, it is subjected to unboxing
conversion (§5.1.8).
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.
Otherwise, if either operand is of type long, the other is converted
to long.
Otherwise, both operands are converted to type int.
But you cannot assign a int to the accessible field that is a short without explicit cast as int has a broader range than short.
While in the second version, a Compound Assignment Operators is used (+=):
node.accessible += 1;
As a consequence, in your case the result of the operation is converted to short : the type of the left-hand variable as the JLS states :
15.26.2. Compound Assignment Operators
A compound assignment expression of the form E1 op= E2 is equivalent
to E1 = (T) ((E1) op (E2)), where T is the type of E1, except that E1
is Evaluations only once.
And more specifically in your case :
Otherwise, the result of the binary operation is converted to the type
of the left-hand variable, subjected to value set conversion (§5.1.13)
to the appropriate standard value set (not an extended-exponent value
set), and the result of the conversion is stored into the variable.
That's because 1 in your + 1 expression is of type int. Adding short to int results in int which can't be assigned without a narrowing cast back to node.accessible.
In the second sample,
node.accessible += 1;
is actually
node.accessible = (short)(node.accessible + 1);
so it works without problem.
But in the first one
node.accessible = d + 1; is actually node.accessible = d + 1; and it doesn't automatically cast as short and thus gives error as (d + 1) is of type int
class Tester {
public static void main(String[] arg) {
byte b=10;
b +=(b<127)?b>-128? b+=10 :0 :5;
System.out.println(b);
}
}
i know that the conditions are evaluated true and took the control to b+=10
so now logically b+=b+=10; is adding the value of b and 10 which evaluates 20, assigning to b. Now i'm unable to evaluate it further.
JLS 15.7.1. Evaluate Left-Hand Operand First has a similar example :
If the operator is a compound-assignment operator (§15.26.2), then evaluation of the left-hand operand includes both remembering the variable that the left-hand operand denotes and fetching and saving that variable's value for use in the implied binary operation.
Example 15.7.1-2. Implicit Left-Hand Operand In Operator Of Compound Assigment
In the following program, the two assignment statements both fetch and remember the value of the left-hand operand, which is 9, before the right-hand operand of the addition operator is evaluated, at which point the variable is set to 3.
class Test2 {
public static void main(String[] args) {
int a = 9;
a += (a = 3); // first example
System.out.println(a);
int b = 9;
b = b + (b = 3); // second example
System.out.println(b);
}
}
This program produces the output:
12
12
Therefore, in your case, the original value of b (10) is remembered and added to the result of the ternary conditional operator (which is 20, since the value of b+=10 is the result of that expression), giving you 30.
First (b<127) is evaluated which is true so it moves to part b>-128? b+=10
In this b>-128 is evaluated which is also true so it moves to b+=10 which makes b=20 and adds to the left side of expression in which value of 10 is stored in b.So b+=(b=20) makes b=30