I'm working on rewriting some Javascript-code to work in Excel VBA. I've manage to translate almost all of the Javascript-code thanks to searching on this website! However, there is some code I can't understand what it's doing precisely. This is the bit of Javascript-code:
var k = x % y;
return (k != 0 && (k > 0 ^ y > 0) && isFinite(y)) ? k + y : k;
The first line is clear to me. k is the remainder of x/y. In the second line, modulo gets the value of either k+y or k. This is decided by (k!=0 && (k > 0 ^ y > 0) && isFinite(y))
Could somebody explain to me step by step how I should be reading this code? Especially the &&(k>0^y>0)&& is puzzling me.
This is how far I seem to be getting till now:
Example 1: x=9 and y=4
k = 9%4 = 9/4=2 with remainder 1 So: k=1
(1!=0&&(1>0^4>0)&&isFinite(4)) (True AND (True^True) AND True) = True?
Example 1: x=9 and y=1
k = 9%1 = 9/1=9 with remainder 0 So: k=0
(0!=0&&(0>0^1>0)&&isFinite(1)) (False AND (False^True) AND True) = False?
If I would think purely mathematically, then I would guess that the part (False^True) should be read like (0^1) = 0 = False.
Step by step explanation of the critical part as evaluated by the language:
(k != 0 && (k > 0 ^ y > 0) && isFinite(y)) ? k + y : k;
(k != 0 && (k > 0 ^ y > 0)
: true
if and only if 1. and 2. below is true
k != 0
: true
if k
is not in 0, '0', 0.0, '0.0'
(k > 0 ^ y > 0)
: true
if and only if one of 1. and 2. is true
true
if and only if k
is a Number
or numeric String
above 0
true
if and only if y
is a Number
or numeric String
above 0
isFinite(y))
: true
if y
is not one of undefined, Object, Array, Infinity, -Infinity, ...
(further native objects) or a non-numeric String
(k != 0 && (k > 0 ^ y > 0) && isFinite(y))
: true
if and only if both parts above were true
. The ternary ?
operator will return the 1st post-expression k + y
if the pre-expression is true
and the 2nd post-expression k
otherwise.
In more general terms the take-away lessons are:
comparisons in JS are complex: String
is often cast to Number
and different functions have different behavior on native objects (isFinite(null) === true
but isFinite(undefined) === false
). Therefore generally always prefer using ===
and !==
.
JS uses short-circuiting on boolean operators
^
is the exclusive OR
aka XOR
operator
?
is the ternary if
operator which equals if ... do ... else do ...