JavaScript operators precedence algorithm - javascript

I have an example:
let x = 4
console.log(x++ + ++x + x--)
it's returns 16 but I don't understand how.
If we will look in MDN there is an operators precedence table.
So there is a precedence like this:
Postfix increment
Postfix decrement
Prefix increment
Addition
With this logic it should return 14
x++ = 4 - (5) -> remembers for next call
x-- = 5 - (4) -> remembers for next call
++x = 5
+
4 + 5 + 5 = 14
Can some one explain, how operators parser algorithm works with unary and binary operators?

Once operator precedence is applied, the grouping looks like:
((x++) + (++x)) + (x--)
The interpreter will evaluate the two +s left-to-right, and resolve the inner expressions as it comes across them. The increments/decrements don't run immediately and before the +s - they only run once the interpreter has determined that their expression needs to be evaluated. This is what happens, in order:
x is 4
((x++) + (++x)) + (x--)
evaluate postfix increment: insert 4, x increases to 5
(4 + (++x)) + (x--)
evaluate prefix increment: x increases to 6, insert 6
(4 + 6) + (x--)
simplify:
10 + (x--)
evaluate postfix decrement: insert 6, x decreases to 5
10 + 6
Resulting in a final value of 16.

The order is completely consistent. You are evaluating left-to-right and apply the precedence. I'll break it down in steps:
1. Post-increment x++
//x = 4
x++ + ++x + x--
^^^
|
--> expression = 4
--> x = 5
First off we evaluate x++. Postfix increment has higher precedence than the addition, so we have to solve it first. This expression produces 4 (value of x at the time) however, the value of x is also incremented for future reads.
2. Pre-increment ++x
//x = 5
4 + ++x + x--
^^^
|
--> x = 6
--> expression = 5
Next ++x is evaluated, as prefix increment also has higher precedence than the addition, so we have to resolve it before the expression a + b. We aren't concerned with x-- yet, since we've not gotten to it.
Thus, the prefix increment will increase the value of x from 5 to 6 and then return that new value.
3. Addition (x++) + (++x)
//x = 6
4 + 6 + x--
^^^^^
|
--> expression = 10
We've resolved the higher priority expressions, so it's time for the addition. Which is simple 4 + 6 = 10.
4. Post-decrement x--
//x = 6
10 + x--
^^^
|
--> expression = 6
--> x = 5
We're reached another a + b construct but the postfix decrement x-- is higher priority, so we solve that first. Current value of x is 6 and we return that, then do the decrement of x to 5.
5. Addition ((x++) + (++x)) + (x--)
//x = 5
10 + 6
^^^^^^
|
--> expression = 16
Finally, another simple addition after everything with higher precedence is resolved: 10 + 6 = 16

You could take a table for the values, one for x with values for the actual/post or pre and actual value.
Then take according to the order of opperends the value and add this values.
let x = 4
console.log(x++ + ++x + x--); // 16
post pre post increment
x 4 5 5 6 6 5 different values
value 4 6 6 values for addition
let x = 4
console.log(x++ + ++x + x--); // 16

Related

Deciding key-value pairs for Roman Numeral Converter

Every solution I've found uses the following object.
function converter(num) {
var romanKeys =
{M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1}
When attempting the problem myself, I wasn't too sure which roman numerals were redundant when constructing the object. Procedurally, how do we arrive to this object? e.g How do I know that
"VI: 6" is unnecessary but "IV: 4" is?
When a symbol appears after a larger (or equal) symbol it is added
Example: VI = V + I = 5 + 1 = 6
Example: LXX = L + X + X = 50 + 10 + 10 = 70
But if the symbol appears before a larger symbol it is subtracted
Example: IV = V − I = 5 − 1 = 4
Example: IX = X − I = 10 − 1 = 9
I can be placed before V (5) and X (10) to make 4 and 9.
X can be placed before L (50) and C (100) to make 40 and 90.
C can be placed before D (500) and M (1000) to make 400 and 900.
When you are scanning a roman number you are looking from left to right at each symbol and if it appears before a larger symbol, you take them together, do the substraction and add it to the result, then move to the symbol after them. Otherwise you take a single symbol and add its value to the result and move to the next symbol.
For example for XIV:
1) result = 0
2) X < I => result += 10 (result = 10)
3) I < V => result += (5-1) (result = 14)
Note that if you are using that mapping, you only need the combinations where the second symbol is greater than the first one for which the substraction rule applies, as noted above (CM, CD, XC, XL, IX, IV).
Having something like XI in that mapping would give you a wrong result. For XIV you will have XI (11) + V (5) = 16, not X (10) + IV (4) = 14.

Unexpected result of increments sum

Good afternoon, please explain why, when waiting for 3, 4 is output to the console.
let x = 1;
console.log (x++ + ++x) // 4
At first, I thought that the priority of operations, but then why in such an example outputs 8, and not 6 for example?
let x = 1;
console.log (x++ + ++x + ++x) // 8
Sorry, if this question is duplicated, but I can't find any about this question.
For the first example:
let x = 1;
console.log (x++ + ++x) // 4
x++ returns the value of x (1) and increments it afterward. x is now 2. (This is postfix increment.)
++x increments the value of x and returns it, which is 3 (2 + 1). (This is prefix increment.)
1 + 3 = 4
See Increment Operator.
x++ or x-- is first use then update.
++x or --x is first update then use.
update means update the value of the variable x.

What is JavaScript Operator precedence -right to left meaning

I tried this JavaScript expression.
I got the answer.
But I need the logic behind that.
var x=8 ,y=5;
document.write(x++ + ++x - y++ - y-- );
How to evaluate this?
inside a statement
++x // <-- increments x, then performs the statement
x++ // <-- performs the statement, then increments x
var x=8 ,y=5;
document.write(x++ + ++x - y++ - y-- );
Means
var x=8 ,y=5;
document.write(8 + 9 - 5 - 5 );
Whose result is 7
After that statement x = 10 and y = 5

What is the logic behind JavaScript In-/ Decrement? Could someone clearify this?

++ Increment
x = ++y // When y = 6 x = 6
x = y++ // And y = 6 x = 5
-- Decrement
x = --y // When y = 4 x = 4
x = y-- // When y = 4 x = 5
Could someone clearify this?
Thank you.
The only slightly tricky case there is:
x = --y // When y = 4 x = 4
You must be looking at y afterward. If you looked at y before, you'd see a 5.
The basic rules for prefix decrement (--y) and postfix decrement (y--) are:
Either way, the operand (y in this case) is decremented by 1. The only difference is what the result of that expression (--y or y--) is.
If the operator comes before the operand (--y) it's a "prefix" decrement: The decrement happens before the result of the expression is taken. So the result is the value of y after it was decremented.
If the operator comes after the operand (y--) it's a "postfix" decrement: The decrement happens after the result of the expression is taken. So the result is the value before it was decremented.
Examples:
var x, y;
y = 5;
snippet.log("Before prefix decrement: y = " + y);
x = --y; // Result is the value **after** the decrement
snippet.log("After prefix decrement: x = " + x + ", y = " + y);
y = 5;
snippet.log("Before postfix decrement: y = " + y);
x = y--; // Result is the value **before** the decrement
snippet.log("After postfix decrement: x = " + x + ", y = " + y);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
In both cases y will have the same final value. The only difference will be in the return value of the expression itself.
++y will return the value after incrementing.
y++ will return the value before incrementing.
When the operator precedes the variable, it changes its value before any processing. When the variable precedes the operator, the value is changed after processing.
y = ++x is identical to:
x = x + 1;
y = x;
and y = x++ is identical to:
y = x;
x = x + 1;
Since your main question is:
The logic behind ...
The answer to that part specifically are processors. Many have had the INC and DEC instructions for a very long time and since C was created to match the processor instructions, it was thought that having operators such as ++ and -- would help in optimizing some code.
INC WORD [BP+4] ; increment value at address BP+4 by one
DEC WORD [SP+16] ; decrement value at address SP+16 by one
RISC processors generally require you to use ADD and SUB instead. The result is pretty much the same in modern processor because speed of execution of such instructions was greatly enhanced, especially with large instruction caches.
Java and JavaScript are spawned of C and thus inherited these.
Specifically, there is the 68000 processor that has instructions such as:
MOV.W D1, (A1)+ ; copy D1 at address A1, then increment A1 by size of D1
MOV.W D2, -(SP) ; decrement stack by size of D2, then copy D2 at address SP
which include hidden increment (the +) and hidden decrement (the -) in the instruction.
In these cases, C matched the processor behavior perfectly. You could write something like:
*a1++ = d1;
*--sp = d2;
And each line becomes just one instruction in assembly language. Notice that the ++ and -- used with the stack work like a charm:
*--sp = d1; // move the stack pointer, then save value on the stack
... // do some work
d1 = *sp++; // restore from the stack, then move the stack pointer back
Here we want to use register d1, so we save it on the stack, the automatic pre-decrement works exactly as required. Then before leaving the function, we restore from the stack, again, the automatic post-increment works exactly as expected. The INTEL processors have specialized instructions instead: PUSH and POP. But that's the same concept.
Of course, with C++ and other object oriented languages (including Java and JavScript), that has evolved quite a bit now and it is easy to lose the reason why we have had these ++ and -- operators.

Surprising simple operation results

In JavaScript, I tried executing the below statements
var x = 1+"2"-3; //Anser is 9.
var y = 1-"2"+4 //Anser is 3.
For such operations, what is converted to what?
I guess 1+"2" = 12(number) and then 12-3?
- converts the both operands to numbers. But if either operand to + is a string, the other is converted to string and it's a concatenation. Like "Hi, " + "how are you?" = "Hi, how are you?" So your answers are correct.
var x = 1+"2"-3;
// concats the string as 12 and then subtracts...
12 - 3 = 9
var y = 1-"2"+4
// converts to numbers and subtracts, making -1 and then adds 4 giving out 3
-1 + 4 = 3
This was the process.
Scenario I
Step 1:
1 + "2" => "12" //concatenation happened
Step 2
"12" - 3 => 9 //String widens to number since we are using - symbol here.
Scenario II
Step 1:
1 - "2" => -1 //String widens to number since we are using - symbol here.
Step 2:
-1 + 4 => 3 //Normal addition happens

Categories