public static void main(String[] args) {
int x = 1 + + + + + + + + + 2;
System.out.println(x);
}
I can compile above method. Is there any explanation about the allowed multiple "+" operator?
It's addition, then the unary plus operator repeated. It's equivalent to the following:
int x = 1 + (+ (+ (+ (+ (+ (+ (+ (+ 2))))))));
The reason is that + can act as a unary operator, similar to how - can be the negation operator. You are just chaining a bunch of unary operators together (with one final binary addition).
it evaluates to 1 + (+ ... (+(+(+2))) ... ) = 1 + 2 = 3
I think they treated all those plus as the same one +. Because the output is 3, so there is no magic here at all
you do not get any exceptions, it works fine. You will get output 3.
Its because though syntactically it may seem wrong use of '+' but there is this unary operation is repeating itself.
Related
Why compiler thinks that the expression 1 + m=6 + 2 is evaluated to boolean? Compiler (Eclipse) says that the result of this expression is boolean. Why? Priority of = is lowest, so first + is done and 1+m shall fail with "unitialized local variable" compile error. If I declare int m = 1; then expression above shall fail as (1+1) = (6+2) => 2=8 is not allowed.
class Driver {
static void f(int arg) {
System.out.println(arg);
}
public static void main(String[] args) {
int m;
f( 1 + m=6 + 2); // c.ERR
f( 1 + (m=6) + 2); // prints 9
}
}
The specific error doesn't make sense, but without those parentheses, you're trying to assign the right-hand side to the result of 1 + m, which obviously you can't do. The parentheses change the order of operations so the m=6 happens first, and then the two additions.
Quoting :
The evaluation of an arithmetical expression is controlled by three
sets of rules: precedence rules, associativity rules, and order rules.
Precedence rules describe how an underparenthesized expression should
be parenthesized when the expression mixes different kinds of
operators.
Associativity rules describe how an underparenthesized expression
should be parenthesized when the expression has a bunch of the same
kind of operator.
Order of evaluation rules describe the order in which each operand in
an expression is evaluated.
//Evluation order
f( 1 + m=6 + 2);
- 1+ m =>ERR
- 6+2 = 8 => ok
- 1+m = 8 => ERR
f( 1 + (m=6) + 2);
- m=6 => ok
- 1+6 = 7 => ok
- 7+2 = 9 => ok
Last day while programming, I mistakenly wrote something like this-
int i = 2;
int j = 3;
int a = i+++j;
And it did not shoot any error and I got-
a = 5
After detecting this coding error I was curious. So, I started playing with it. When I changed it a little-
int a = i+ ++j;
I got-
a = 6
With this-
int a = i+ + +j;
and this-
int a = i++ +j;
I again got-
a = 5
Similar situation was experienced here.
But here comes the weird part. There is no difference between a = i+--j & a = i+ --j. Both gives-
a = 4
Why is that? I completely understand what exactly is happening here. The thing I do not understand is- 'WHY?'. + and - are both operators, then why there is a difference?
For clarity, I wish to share another odd experience. This code works perfectly-
int i=0;
System.out.println("value: "+--i);
And outputs-
value: -1
But this-
System.out.println("value: "+++i);
Gives following error-
error: unexpected type
As #Bunti pointed out, your answer is in the Operator Precedence.
When you do,
int a = i+++j;
It's evaluated as int a = (i++) + j since Postfix has the highest precedence.
Now you know why you get a = 5 there. Print i along with a and you will see it's incremented.
Similarly, when you do System.out.println("value: "+++i);, it's evaluated to System.out.println(("value: "++) + i);
But postfix operations are not applicable to String. Hence the syntax error.
But when you do, System.out.println("value: "+--i);, this is evaluated to System.out.println("value: "+ (--i));. Hence it works just fine.
Operator precedence is only half of the answer, since the first thing to clarify is what the operators in your code are.
Basically i+++j could be interpreted as i ++ + j, as i + ++ j or as i + + + j.
However according to the lexical rules of Java (https://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.2) the interpretation is the same as if the expression was written as i ++ + j.
According to the operator precedence this is evaluated is (i++) + j, so that in int a = i++ + j; a is 5 (and i is 3!).
For i+--j the tokens are i + -- j (since the is no operator +-), which is according to operator precedence i + (--j), so that in int a = i + --j; a is 4 (and j is now 2).
Now comes the fun part:
What is int a = i + + + j;? This is the same as int a = i + (+(+j)); (+j being the unary plus operation on j), so this gives again 5 (but i is still 2 and j is still 3, which is different from the case i++ + j!)
And what is int a = i + - - j;? This is the same as int a = i + (-(-j)); (-j being the unary minus operation on j) which also gives 5 (and also does not modify i or j).
What is int a = i++++j;? This is not a valid Java expression (it will not compile), since this is equivalent to (i++) ++ j and since i++ cannot be converted to a variable this is illegal (https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.14.2) and then there is this dangling j too.
Adding more + without adding spaces does not make it legal, while i++ + ++j is perfectly legal...
Similarly, "SomeString"+++i is illegal, since this is read as ("SomeString"++)+i and you can't increment a String literal (and also not a String variable).
"SomeString"+--i is valid, since this is read as "SomeString"+(--i), which appends the result of --i to "SomeString".
Many of them have written answers for this. I would like to put it in different words.
i++ is post fix.
In post fix operation, value is incremented after the value is extracted.
Thus in case of i+++j, we have original value of i when expression is evaluated, and i is incremented after the evaluation is completed.
In case of ++j since its prefix value is incremented before evaluation.
This i+++j is equal to (i++)+j and i+ ++j is equivalent to i + (++j).
Hope this adds this helps adding to your understanding.
Hope this answers the behavior of arithmetic operation-
int i = 2;
int j = 3;
int a = i+++j;
a=5 as there is no space between the + symbol. Even if you put any more + symbols in between, the answer will remain the same. To explain its working, it is similar to any basic calculator we use, if i input a number and type + for any number of times, the second input when received will still give the sum of the 2 input-ed numbers. This is because the compiler is initializing the addition operation between the 2 numbers.
int a = i+ ++j;
Here in this case, you are adding the i to the incremented value of j. So it is like u are looking for an operation of 2+ ++3, which is 2+4 and hence the answer 6. the ++ operator is defined as an increment in the JRE.
int a = i+ + +j;
Here it behaves same as the 1st case as +j or i+ are not increment operators defined by JRE.
int a = i+--j;
In this interesting case, we are using 2 diff arithmetic operators i.e. + and --. As -- is defined, the decrement of j value happens and the change value of j is added to i.
int a = i+ --j;
As in above, since + and - are diff operations. the space between them or not doesn't matter.
int i=0;
System.out.println("value: "+--i);
In this case, we are printing a string and using +--i; so JRE treats it as printing out Value: decrement of i. As known in print statement, + is used to make system print multiple value at a time.
System.out.println("value: "+++i);
coming to this, the + in print function is defined to provide a way to print several variable that are separated by a + symbol and hence the conjunction of +++ is not defined for print function and hence gives an error.
May be the i+++j just is i+j, but the i+ ++j is i + ++j, there ++j change's , 'j=4'. So i[2] + j[4] = 6.
Java May not recognize three +++.
The precedence for the plus operator is listed only once in the java tutorial precedence table. However the following Java expressions:
String unexpected = "1 + 1 = " + 1 + 1;
String expected = "1 + 1 = " + (1 + 1);
System.out.println(unexpected);
System.out.println(expected);
result in this output:
1 + 1 = 11
1 + 1 = 2
Does this mean the plus operator has a higher precedence when used to concatenate Strings, or does it mean the plus operator's precedence is no different for Strings and Numbers, but that it is simply evaluated left to right?
It means it is evaluated left to right.
From jls SE8 15.18.1. String Concatenation Operator +: The + operator is syntactically left-associative, no matter whether it is determined by
type analysis to represent string concatenation or numeric addition. In some cases care is
required to get the desired result. For example, the expression:
a + b + c
is always regarded as meaning: (a + b) + c
Therefore the result of the expression: 1 + 2 + " fiddlers"
is: "3 fiddlers"
but the result of: "fiddlers " + 1 + 2
is: "fiddlers 12"
Another example: 1 + 1 + "" + 1 + 1
will result in : 211
That is why, for your context "1 + 1 = " + 1 + 1;
will result in string 1 + 1 = 11
But, "1 + 1 = " + (1 + 1); will result in 1 + 1 = 2
+ always flow from left to right
in your first example String unexpected = "1 + 1 = " + 1 + 1; , string comes first and then the int value so 1 is treated as string.
in your second example String expected = "1 + 1 = " + (1 + 1); , you are using () which is having higher precedence over + operator.(BODMAS)
consider another example:
String unexpected1 =1+1+ "1 + 1 = " ;
System.out.println(unexpected1);
output will be 21 + 1 =
here int value comes first so 1+1 =2 and then the string literal so 2 is concatenated with 1+1=
Using + in strings will trigger a concatenation rather than summation.
But when you use (1+1) and sum it to "1+1=" using a +, the expression inside the parentheses will be evaluated first then concatenated to the rest of the string. Evaluating the inside of the parentheses works independently from the String, thus 1 and 1 will be considered two integers being added to each other.
And when using same operators, everything is evaluated from left to right.
There is an order of evaluation for operators that you can find here
Alright, so I'm trying to make an expression-as-a-string solver, so that the user can input a string, such as 2+4*5/10, and it will print out the answer, 4. I have some code written, but it doesn't apply the order of operations; it simply solves the equation in order of the operators - e.g. 2+4*5/10 would produce 3, which is incorrect. How do I make it so that multiplication and division are performed first, then addition and subtraction?
Here's the code I have right now:
class Expressions
{
String E;
void SetE(String e)
{
E = e;
}
int EvalE()
{
int res = 0;
int temp = 0;
char op = '+';
for(int i=0;i<E.length();i++)
{
if(E.charAt(i)=='*'||E.charAt(i)=='/'||E.charAt(i)=='+'||E.charAt(i)=='-')
{
if(op=='*')res*=temp;
else if(op=='/')res/=temp;
else if(op=='+')res+=temp;
else res-=temp;
temp=0;
op=E.charAt(i);
}
else
{
temp = temp*10+E.charAt(i)-'0';
}
}
if(op=='*')res*=temp;
else if(op=='/')res/=temp;
else if(op=='+')res+=temp;
else res-=temp;
return res;
}
}
Split the expression into two simpler expressions, then use recursion.
You have to do the following steps in precisely this order, or you will mess up the order of operations.
Look for the rightmost + sign. If there is such a +, then use recursion to evaluate the sub-expression to the left of it, then the sub-expression to the right of it, then add them and return the result.
If there's no + sign, then look for the rightmost - sign that's preceded by a number (that is, it's subtraction, not negation). If there is such a -, then use recursion to evaluate the sub-expression to the left of it, then the sub-expression to the right of it, then subtract them and return the result.
If there's no + or - sign, then look for the rightmost * sign. If there is such a *, then use recursion to evaluate the sub-expression to the left of it, then the sub-expression to the right of it, then multiply them and return the result.
If there's no +, - or * sign, then look for the rightmost * sign. If there is such a *, then use recursion to evaluate the sub-expression to the left of it, then the sub-expression to the right of it, then divide them and return the result. If you're using integers, you'll have to think about whether you want integer division or floating point. You might also want to do some kind of check around dividing by zero.
If there's no +, -, * or /, then all you've got is numbers and whitespace. Maybe a negative sign. Strip out the whitespace, parse it and return it.
Example: "6 - 5 - 4 + 3 * -2"
First, split at the +, and use recursion to evaluate "6 - 5 - 4 " and
" 3 * -2".
For "6 - 5 - 4 ", split at the second - , and use
recursion to evaluate "6 - 5 " and " 4 ".
For "6 - 5 ", split at the -, and use recursion to evaluate "6 " and " 5 ".
For " 3 * -2", split at the *, because the - is not preceded by a number. Use recursion to evaluate " 3 " and " -2 ".
For each of "6 ", " 5 ", " 4 ", " 3 " and " -2 ", there are no operators, so we just strip out the white space and parse.
The result of our calculation will be "((6-5)-4)+(3*-2)", so the order of operations worked out correctly.
Use two for loops.
In your first loop, search for * and / operators. Evaluate that part and replace that part of the string with the result of the evaluation.
In your second loop, do all the + and - as you're already doing.
So for the example you use, 2+4*5/10, your first loop would look for * or /. Upon finding the *, it evaluates 4*5. That's 20, so the string is modified into 2+20/10. Check again, and it finds the /, and modifies the string into 2+2.
Now you go through your second loop, and get 4.
You need to do two steps instead of one. In first step you parse equation into the reverse polish notation, then in second step you run through that and calculate results. Nice bonus is you get brackets support for (almost) free :-)
I have a doubt which follows.
public static void main(String[] args) throws IOException{
int number=1;
System.out.println("M"+number+1);
}
Output: M11
But I want to get it printed M2 instead of M11. I couldn't number++ as the variable is involved with a for loop, which gives me different result if I do so and couldn't print it using another print statement, as the output format changes.
Requesting you to help me how to print it properly.
Try this:
System.out.printf("M%d%n", number+1);
Where %n is a newline
Add a bracket around your sum, to enforce the sum to happen first. That way, your bracket having the highest precedence will be evaluated first, and then the concatenation will take place.
System.out.println("M"+(number+1));
It has to do with the precedence order in which java concatenates the String,
Basically Java is saying
"M"+number = "M1"
"M1"+1 = "M11"
You can overload the precedence just like you do with maths
"M"+(number+1)
This now reads
"M"+(number+1) = "M"+(1+1) = "M"+2 = "M2"
Try
System.out.println("M"+(number+1));
Try this:
System.out.println("M"+(number+1));
A cleaner way to separate data from invariants:
int number=1;
System.out.printf("M%d%n",number+1);
System.out.println("M"+number+1);
Here You are using + as a concatanation Operator as Its in the println() method.
To use + to do sum, You need to Give it high Precedence which You can do with covering it with brackets as Shown Below:
System.out.println("M"+(number+1));
System.out.println("M"+number+1);
String concatination in java works this way:
if the first operand is of type String and you use + operator, it concatinates the next operand and the result would be a String.
try
System.out.println("M"+(number+1));
In this case as the () paranthesis have the highest precedence the things inside the brackets would be evaluated first. then the resulting int value would be concatenated with the String literal resultingin a string "M2"
If you perform + operation after a string, it takes it as concatenation:
"d" + 1 + 1 // = d11
Whereas if you do the vice versa + is taken as addition:
1 + 1 + "d" // = 2d