Bitwise AND operations in Javascript - javascript

I make a project that reads value from a remote JSON. In this project the remote JSON can give me with one variable 16 different types of alarm. The implementation is by a bynary 16bit value expressed in int. So if there is the third alarm it should return me 8 (bynary 1000) and if the second,eigth and tenth alarm is up it return me 1284 (binary 10100000100). Well when there is no alarm it returns me 0.
So, I create a function in JS (accordly to here) that passing the value returned (8/1284/0 in the example) returns me a simple true or false if there is an alarm. The function is pretty simple:
function IsOnAlarm(passedVal) {
if (passedVal & 0) {
return false;
} else {
return true;
}
}
but it does not function :-(
I create a JSFiddle that shows the problem. How can I solve it? Thanks in advance.

Well as far as I understand you just need to check whether the value is 0. There's no need for any bitwise operation.
function IsOnAlarm(passedVal) {
return passedVal != 0;
}
Side note: passedVal & 0 is always 0 no matter what passedVal is (that's why it always goes to else).

You can do it like
function IsOnAlarm(passedVal) {
if (passedVal != 0) {
return false;
} else {
return true;
}
}
Check this http://jsfiddle.net/KQH43/3/

The AND operator always return false if one of the operands is zero, see below:
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
The easiest way to rewrite your function is as follows:
function IsOnAlarm(passedVal) {
return !!passedVal;
}
Explanation: the double negation operation (!!) allows you to cast the input to boolean. Any non-zero value will evaluate to true, zero evaluates to false.

Check this jsfiddle, it is using bitwise AND comparison.
I've modified your function to make it easier to understand:
function AreAlarmsOn(alarmsToCheck, alarmState) {
return and(alarmsToCheck, alarmState)!=0;
}
It takes alarmsToCheck and checks its bits against alarmState bits, alarmsToCheck can have bits for several alarms if you need to check multiple alarms.

Is this what you're looking for?
var getFlags = function(val) {
var results = [];
for (var i = 0; i < 16; i++) {
results.push(!!((val >> i) & 1));
}
return results;
};
var flags = getFlags(1284);
flags[2] //=> true
flags[8] //=> true
flags[10] //=> true
// all other values ==> false / undefined

Related

Check if number is divisible by another number in JS

I am pretty new at this stuff, and I am solving a series of questions, but I've got lost in this one.
I have to verify if a number can be divided by other, and the answer must be true or false.
I got his
function solucao(numero, x) {
solucao(numero % x);
if (solucao === 0) {
resultado = true;
}else{
resultado = false;
}
}
But I'm getting runtime error and can't see whats is missing.
So you want to check if a number numero is divisible by x. The modulo operator can help. Try this:
function solucao(numero, x){
if (numero % x == 0){
return true
}
else {
return false
}
}
function solucao(numero, x) {
let resultado;
if (numero % x === 0) {
resultado = true;
}else{
resultado = false;
}
return resultado;
}
I think you get confused at some point. You are calling the function, inside of itself. You should do like this, and also, declare the result variable.
I am sure this will help:
function checkIfDivided(){
// in this section the variables come from an html document
var number=parseInt(document.getElementById("number").value);
var divisor=parseInt(document.getElementById("divisor").value);
if(number%divisor==0)
return true;
else return false;
}
or
function checkIfDivided(number,divisor){
//in the function the variable are given as parameters
if(number%divisor==0)
return true;
else return false;
}
Looks like two things to me:
You haven't declared your 'resultado' variable ( this can be as simple as just typing 'let resultado;' without the single quotes
You haven't returned your 'resultado' variable after the if/else statement
Right now, your function is using an undeclared variable and not returning anything, so that is why you are getting an error. Fix the two above steps and you should be good! :)
You clearly understand that the modulus operator is the way to go. Using it we discover that 12 is divisible by 3 because 12 % 3 return zero. Zero is considered a "falsy" value while any other number is considered "truthy".
Given this then if 12 % 3 returns a "falsey" value (zero) we can't use the result directly. But what if we can "flip" false to true? We can, using the not operator (!).
Using the ! operator on the result of a math problem requires the use of parentheses around the math problem itself.
So the problem in code becomes (12 % 3) and to 'flip' it with the ! operator it becomes
!(12 % 3).
This is proven below with:
console.log(!(12 % 3)) --> logs true
console.log(!(12 % 5)) --> logs false
The function implementation of that is simple and also proven:
console.log(isDivisible(12,3)); --> logs true
console.log(isDivisible(12,5)); --> logs false
console.log(!(12 % 3))
console.log(!(12 % 5))
function isDivisible(number, x){
return !(number % x);
}
console.log(isDivisible(12,3));
console.log(isDivisible(12,5));
There is one other way to do so and i think its much cleaner.
console.log(Number.isInteger(10/2)) //true
console.log(Number.isInteger(4/2)) // false
//a must be greater than b
function check(a,b) {
console.log(Number.isInteger(a/b))
return Number.isInteger(a/b)
}
check(10,5)//true
check(8,3)//false

Can (a== 1 && a ==2 && a==3) ever evaluate to true?

Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
Moderator note: Please resist the urge to edit the code or remove this notice. The pattern of whitespace may be part of the question and therefore should not be tampered with unnecessarily. If you are in the "whitespace is insignificant" camp, you should be able to accept the code as is.
Is it ever possible that (a== 1 && a ==2 && a==3) could evaluate to true in JavaScript?
This is an interview question asked by a major tech company. It happened two weeks back, but I'm still trying to find the answer. I know we never write such code in our day-to-day job, but I'm curious.
If you take advantage of how == works, you could simply create an object with a custom toString (or valueOf) function that changes what it returns each time it is used such that it satisfies all three conditions.
const a = {
i: 1,
toString: function () {
return a.i++;
}
}
if(a == 1 && a == 2 && a == 3) {
console.log('Hello World!');
}
The reason this works is due to the use of the loose equality operator. When using loose equality, if one of the operands is of a different type than the other, the engine will attempt to convert one to the other. In the case of an object on the left and a number on the right, it will attempt to convert the object to a number by first calling valueOf if it is callable, and failing that, it will call toString. I used toString in this case simply because it's what came to mind, valueOf would make more sense. If I instead returned a string from toString, the engine would have then attempted to convert the string to a number giving us the same end result, though with a slightly longer path.
I couldn't resist - the other answers are undoubtedly true, but you really can't walk past the following code:
var aᅠ = 1;
var a = 2;
var ᅠa = 3;
if(aᅠ==1 && a== 2 &&ᅠa==3) {
console.log("Why hello there!")
}
Note the weird spacing in the if statement (that I copied from your question). It is the half-width Hangul (that's Korean for those not familiar) which is an Unicode space character that is not interpreted by ECMA script as a space character - this means that it is a valid character for an identifier. Therefore there are three completely different variables, one with the Hangul after the a, one with it before and the last one with just a. Replacing the space with _ for readability, the same code would look like this:
var a_ = 1;
var a = 2;
var _a = 3;
if(a_==1 && a== 2 &&_a==3) {
console.log("Why hello there!")
}
Check out the validation on Mathias' variable name validator. If that weird spacing was actually included in their question, I feel sure that it's a hint for this kind of answer.
Don't do this. Seriously.
Edit: It has come to my attention that (although not allowed to start a variable) the Zero-width joiner and Zero-width non-joiner characters are also permitted in variable names - see Obfuscating JavaScript with zero-width characters - pros and cons?.
This would look like the following:
var a= 1;
var a‍= 2; //one zero-width character
var a‍‍= 3; //two zero-width characters (or you can use the other one)
if(a==1&&a‍==2&&a‍‍==3) {
console.log("Why hello there!")
}
IT IS POSSIBLE!
var i = 0;
with({
get a() {
return ++i;
}
}) {
if (a == 1 && a == 2 && a == 3)
console.log("wohoo");
}
This uses a getter inside of a with statement to let a evaluate to three different values.
... this still does not mean this should be used in real code...
Even worse, this trick will also work with the use of ===.
var i = 0;
with({
get a() {
return ++i;
}
}) {
if (a !== a)
console.log("yep, this is printed.");
}
Example without getters or valueOf:
a = [1,2,3];
a.join = a.shift;
console.log(a == 1 && a == 2 && a == 3);
This works because == invokes toString which calls .join for Arrays.
Another solution, using Symbol.toPrimitive which is an ES6 equivalent of toString/valueOf:
let i = 0;
let a = { [Symbol.toPrimitive]: () => ++i };
console.log(a == 1 && a == 2 && a == 3);
If it is asked if it is possible (not MUST), it can ask "a" to return a random number. It would be true if it generates 1, 2, and 3 sequentially.
with({
get a() {
return Math.floor(Math.random()*4);
}
}){
for(var i=0;i<1000;i++){
if (a == 1 && a == 2 && a == 3){
console.log("after " + (i+1) + " trials, it becomes true finally!!!");
break;
}
}
}
When you can't do anything without regular expressions:
var a = {
r: /\d/g,
valueOf: function(){
return this.r.exec(123)[0]
}
}
if (a == 1 && a == 2 && a == 3) {
console.log("!")
}
It works because of custom valueOf method that is called when Object compared with primitive (such as Number). Main trick is that a.valueOf returns new value every time because it's calling exec on regular expression with g flag, which causing updating lastIndex of that regular expression every time match is found. So first time this.r.lastIndex == 0, it matches 1 and updates lastIndex: this.r.lastIndex == 1, so next time regex will match 2 and so on.
This is possible in case of variable a being accessed by, say 2 web workers through a SharedArrayBuffer as well as some main script. The possibility is low, but it is possible that when the code is compiled to machine code, the web workers update the variable a just in time so the conditions a==1, a==2 and a==3 are satisfied.
This can be an example of race condition in multi-threaded environment provided by web workers and SharedArrayBuffer in JavaScript.
Here is the basic implementation of above:
main.js
// Main Thread
const worker = new Worker('worker.js')
const modifiers = [new Worker('modifier.js'), new Worker('modifier.js')] // Let's use 2 workers
const sab = new SharedArrayBuffer(1)
modifiers.forEach(m => m.postMessage(sab))
worker.postMessage(sab)
worker.js
let array
Object.defineProperty(self, 'a', {
get() {
return array[0]
}
});
addEventListener('message', ({data}) => {
array = new Uint8Array(data)
let count = 0
do {
var res = a == 1 && a == 2 && a == 3
++count
} while(res == false) // just for clarity. !res is fine
console.log(`It happened after ${count} iterations`)
console.log('You should\'ve never seen this')
})
modifier.js
addEventListener('message' , ({data}) => {
setInterval( () => {
new Uint8Array(data)[0] = Math.floor(Math.random()*3) + 1
})
})
On my MacBook Air, it happens after around 10 billion iterations on the first attempt:
Second attempt:
As I said, the chances will be low, but given enough time, it'll hit the condition.
Tip: If it takes too long on your system. Try only a == 1 && a == 2 and change Math.random()*3 to Math.random()*2. Adding more and more to list drops the chance of hitting.
It can be accomplished using the following in the global scope. For nodejs use global instead of window in the code below.
var val = 0;
Object.defineProperty(window, 'a', {
get: function() {
return ++val;
}
});
if (a == 1 && a == 2 && a == 3) {
console.log('yay');
}
This answer abuses the implicit variables provided by the global scope in the execution context by defining a getter to retrieve the variable.
This is also possible using a series of self-overwriting getters:
(This is similar to jontro's solution, but doesn't require a counter variable.)
(() => {
"use strict";
Object.defineProperty(this, "a", {
"get": () => {
Object.defineProperty(this, "a", {
"get": () => {
Object.defineProperty(this, "a", {
"get": () => {
return 3;
}
});
return 2;
},
configurable: true
});
return 1;
},
configurable: true
});
if (a == 1 && a == 2 && a == 3) {
document.body.append("Yes, it’s possible.");
}
})();
Alternatively, you could use a class for it and an instance for the check.
function A() {
var value = 0;
this.valueOf = function () { return ++value; };
}
var a = new A;
if (a == 1 && a == 2 && a == 3) {
console.log('bingo!');
}
EDIT
Using ES6 classes it would look like this
class A {
constructor() {
this.value = 0;
this.valueOf();
}
valueOf() {
return this.value++;
};
}
let a = new A;
if (a == 1 && a == 2 && a == 3) {
console.log('bingo!');
}
I don't see this answer already posted, so I'll throw this one into the mix too. This is similar to Jeff's answer with the half-width Hangul space.
var a = 1;
var a = 2;
var а = 3;
if(a == 1 && a == 2 && а == 3) {
console.log("Why hello there!")
}
You might notice a slight discrepancy with the second one, but the first and third are identical to the naked eye. All 3 are distinct characters:
a - Latin lower case A
a - Full Width Latin lower case A
а - Cyrillic lower case A
The generic term for this is "homoglyphs": different unicode characters that look the same. Typically hard to get three that are utterly indistinguishable, but in some cases you can get lucky. A, Α, А, and Ꭺ would work better (Latin-A, Greek Alpha, Cyrillic-A, and Cherokee-A respectively; unfortunately the Greek and Cherokee lower-case letters are too different from the Latin a: α,ꭺ, and so doesn't help with the above snippet).
There's an entire class of Homoglyph Attacks out there, most commonly in fake domain names (eg. wikipediа.org (Cyrillic) vs wikipedia.org (Latin)), but it can show up in code as well; typically referred to as being underhanded (as mentioned in a comment, [underhanded] questions are now off-topic on PPCG, but used to be a type of challenge where these sorts of things would show up). I used this website to find the homoglyphs used for this answer.
Yes, it is possible! 😎
» JavaScript
if‌=()=>!0;
var a = 9;
if‌(a==1 && a== 2 && a==3)
{
document.write("<h1>Yes, it is possible!😎</h1>")
}
The above code is a short version (thanks to #Forivin for its note in comments) and the following code is original:
var a = 9;
if‌(a==1 && a== 2 && a==3)
{
//console.log("Yes, it is possible!😎")
document.write("<h1>Yes, it is possible!😎</h1>")
}
//--------------------------------------------
function if‌(){return true;}
If you just see top side of my code and run it you say WOW, how?
So I think it is enough to say Yes, it is possible to someone that said to
you: Nothing is impossible
Trick: I used a hidden character after if to make a function that its name is similar to if. In JavaScript we can not override keywords so I forced to use this way. It is a fake if, but it works for you in this case!
» C#
Also I wrote a C# version (with increase property value technic):
static int _a;
public static int a => ++_a;
public static void Main()
{
if(a==1 && a==2 && a==3)
{
Console.WriteLine("Yes, it is possible!😎");
}
}
Live Demo
JavaScript
a == a +1
In JavaScript, there are no integers but only Numbers, which are implemented as double precision floating point numbers.
It means that if a Number a is large enough, it can be considered equal to four consecutive integers:
a = 100000000000000000
if (a == a+1 && a == a+2 && a == a+3){
console.log("Precision loss!");
}
True, it's not exactly what the interviewer asked (it doesn't work with a=0), but it doesn't involve any trick with hidden functions or operator overloading.
Other languages
For reference, there are a==1 && a==2 && a==3 solutions in Ruby and Python. With a slight modification, it's also possible in Java.
Ruby
With a custom ==:
class A
def ==(o)
true
end
end
a = A.new
if a == 1 && a == 2 && a == 3
puts "Don't do this!"
end
Or an increasing a:
def a
#a ||= 0
#a += 1
end
if a == 1 && a == 2 && a == 3
puts "Don't do this!"
end
Python
You can either define == for a new class:
class A:
def __eq__(self, who_cares):
return True
a = A()
if a == 1 and a == 2 and a == 3:
print("Don't do that!")
or, if you're feeling adventurous, redefine the values of integers:
import ctypes
def deref(addr, typ):
return ctypes.cast(addr, ctypes.POINTER(typ))
deref(id(2), ctypes.c_int)[6] = 1
deref(id(3), ctypes.c_int)[6] = 1
deref(id(4), ctypes.c_int)[6] = 1
print(1 == 2 == 3 == 4)
# True
It might segfault, depending on your system/interpreter.
The python console crashes with the above code, because 2 or 3 are probably used in the background. It works fine if you use less-common integers:
>>> import ctypes
>>>
>>> def deref(addr, typ):
... return ctypes.cast(addr, ctypes.POINTER(typ))
...
>>> deref(id(12), ctypes.c_int)[6] = 11
>>> deref(id(13), ctypes.c_int)[6] = 11
>>> deref(id(14), ctypes.c_int)[6] = 11
>>>
>>> print(11 == 12 == 13 == 14)
True
Java
It's possible to modify Java Integer cache:
package stackoverflow;
import java.lang.reflect.Field;
public class IntegerMess
{
public static void main(String[] args) throws Exception {
Field valueField = Integer.class.getDeclaredField("value");
valueField.setAccessible(true);
valueField.setInt(1, valueField.getInt(42));
valueField.setInt(2, valueField.getInt(42));
valueField.setInt(3, valueField.getInt(42));
valueField.setAccessible(false);
Integer a = 42;
if (a.equals(1) && a.equals(2) && a.equals(3)) {
System.out.println("Bad idea.");
}
}
}
This is an inverted version of #Jeff's answer* where a hidden character (U+115F, U+1160 or U+3164) is used to create variables that look like 1, 2 and 3.
var a = 1;
var ᅠ1 = a;
var ᅠ2 = a;
var ᅠ3 = a;
console.log( a ==ᅠ1 && a ==ᅠ2 && a ==ᅠ3 );
* That answer can be simplified by using zero width non-joiner (U+200C) and zero width joiner (U+200D). Both of these characters are allowed inside identifiers but not at the beginning:
var a = 1;
var a‌ = 2;
var a‍ = 3;
console.log(a == 1 && a‌ == 2 && a‍ == 3);
/****
var a = 1;
var a\u200c = 2;
var a\u200d = 3;
console.log(a == 1 && a\u200c == 2 && a\u200d == 3);
****/
Other tricks are possible using the same idea e.g. by using Unicode variation selectors to create variables that look exactly alike (a︀ = 1; a︁ = 2; a︀ == 1 && a︁ == 2; // true).
Rule number one of interviews; never say impossible.
No need for hidden character trickery.
window.__defineGetter__( 'a', function(){
if( typeof i !== 'number' ){
// define i in the global namespace so that it's not lost after this function runs
i = 0;
}
return ++i;
});
if( a == 1 && a == 2 && a == 3 ){
console.log( 'Oh dear, what have we done?' );
}
Honestly though, whether there is a way for it to evaluate to true or not (and as others have shown, there are multiple ways), the answer I'd be looking for, speaking as someone who has conducted hundreds of interviews, would be something along the lines of:
"Well, maybe yes under some weird set of circumstances that aren't immediately obvious to me... but if I encountered this in real code then I would use common debugging techniques to figure out how and why it was doing what it was doing and then immediately refactor the code to avoid that situation... but more importantly: I would absolutely NEVER write that code in the first place because that is the very definition of convoluted code, and I strive to never write convoluted code".
I guess some interviewers would take offense to having what is obviously meant to be a very tricky question called out, but I don't mind developers who have an opinion, especially when they can back it up with reasoned thought and can dovetail my question into a meaningful statement about themselves.
If you ever get such an interview question (or notice some equally unexpected behavior in your code) think about what kind of things could possibly cause a behavior that looks impossible at first glance:
Encoding: In this case the variable you are looking at is not the one you think it is. This can happen if you intentionally mess around with Unicode using homoglyphs or space characters to make the name of a variable look like another one, but encoding issues can also be introduced accidentally, e.g. when copying & pasting code from the Web that contains unexpected Unicode code points (e.g. because a content management system did some "auto-formatting" such as replacing fl with Unicode 'LATIN SMALL LIGATURE FL' (U+FB02)).
Race conditions: A race-condition might occur, i.e. a situation where code is not executing in the sequence expected by the developer. Race conditions often happen in multi-threaded code, but multiple threads are not a requirement for race conditions to be possible – asynchronicity is sufficient (and don't get confused, async does not mean multiple threads are used under the hood).
Note that therefore JavaScript is also not free from race conditions just because it is single-threaded. See here for a simple single-threaded – but async – example. In the context of an single statement the race condition however would be rather hard to hit in JavaScript.
JavaScript with web workers is a bit different, as you can have multiple threads. #mehulmpt has shown us a great proof-of-concept using web workers.
Side-effects: A side-effect of the equality comparison operation (which doesn't have to be as obvious as in the examples here, often side-effects are very subtle).
These kind of issues can appear in many programming languages, not only JavaScript, so we aren't seeing one of the classical JavaScript WTFs here1.
Of course, the interview question and the samples here all look very contrived. But they are a good reminder that:
Side-effects can get really nasty and that a well-designed program should be free from unwanted side-effects.
Multi-threading and mutable state can be problematic.
Not doing character encoding and string processing right can lead to nasty bugs.
1 For example, you can find an example in a totally different programming language (C#) exhibiting a side-effect (an obvious one) here.
Here's another variation, using an array to pop off whatever values you want.
const a = {
n: [3,2,1],
toString: function () {
return a.n.pop();
}
}
if(a == 1 && a == 2 && a == 3) {
console.log('Yes');
}
Okay, another hack with generators:
const value = function* () {
let i = 0;
while(true) yield ++i;
}();
Object.defineProperty(this, 'a', {
get() {
return value.next().value;
}
});
if (a === 1 && a === 2 && a === 3) {
console.log('yo!');
}
Using Proxies:
var a = new Proxy({ i: 0 }, {
get: (target, name) => name === Symbol.toPrimitive ? () => ++target.i : target[name],
});
console.log(a == 1 && a == 2 && a == 3);
Proxies basically pretend to be a target object (the first parameter), but intercept operations on the target object (in this case the "get property" operation) so that there is an opportunity to do something other than the default object behavior. In this case the "get property" action is called on a when == coerces its type in order to compare it to each number. This happens:
We create a target object, { i: 0 }, where the i property is our counter
We create a Proxy for the target object and assign it to a
For each a == comparison, a's type is coerced to a primitive value
This type coercion results in calling a[Symbol.toPrimitive]() internally
The Proxy intercepts getting the a[Symbol.toPrimitive] function using the "get handler"
The Proxy's "get handler" checks that the property being gotten is Symbol.toPrimitive, in which case it increments and then returns the counter from the target object: ++target.i. If a different property is being retrieved, we just fall back to returning the default property value, target[name]
So:
var a = ...; // a.valueOf == target.i == 0
a == 1 && // a == ++target.i == 1
a == 2 && // a == ++target.i == 2
a == 3 // a == ++target.i == 3
As with most of the other answers, this only works with a loose equality check (==), because strict equality checks (===) do not do type coercion that the Proxy can intercept.
Actually the answer to the first part of the question is "Yes" in every programming language. For example, this is in the case of C/C++:
#define a (b++)
int b = 1;
if (a ==1 && a== 2 && a==3) {
std::cout << "Yes, it's possible!" << std::endl;
} else {
std::cout << "it's impossible!" << std::endl;
}
Same, but different, but still same (can be "tested" multiple times):
const a = { valueOf: () => this.n = (this.n || 0) % 3 + 1}
if(a == 1 && a == 2 && a == 3) {
console.log('Hello World!');
}
if(a == 1 && a == 2 && a == 3) {
console.log('Hello World!');
}
My idea started from how Number object type equation works.
An ECMAScript 6 answer that makes use of Symbols:
const a = {value: 1};
a[Symbol.toPrimitive] = function() { return this.value++ };
console.log((a == 1 && a == 2 && a == 3));
Due to == usage, JavaScript is supposed to coerce a into something close to the second operand (1, 2, 3 in this case). But before JavaScript tries to figure coercing on its own, it tries to call Symbol.toPrimitive. If you provide Symbol.toPrimitive JavaScript would use the value your function returns. If not, JavaScript would call valueOf.
I think this is the minimal code to implement it:
i=0,a={valueOf:()=>++i}
if (a == 1 && a == 2 && a == 3) {
console.log('Mind === Blown');
}
Creating a dummy object with a custom valueOf that increments a global variable i on each call. 23 characters!
This one uses the defineProperty with a nice side-effect causing global variable!
var _a = 1
Object.defineProperty(this, "a", {
"get": () => {
return _a++;
},
configurable: true
});
console.log(a)
console.log(a)
console.log(a)
By overriding valueOf in a class declaration, it can be done:
class Thing {
constructor() {
this.value = 1;
}
valueOf() {
return this.value++;
}
}
const a = new Thing();
if(a == 1 && a == 2 && a == 3) {
console.log(a);
}
What happens is that valueOf is called in each comparison operator. On the first one, a will equal 1, on the second, a will equal 2, and so on and so forth, because each time valueOf is called, the value of a is incremented.
Therefore the console.log will fire and output (in my terminal anyways) Thing: { value: 4}, indicating the conditional was true.
As we already know that the secret of loose equality operator (==) will try to convert both values to a common type. As a result, some functions will be invoked.
ToPrimitive(A) attempts to convert its object argument to a primitive
value, by invoking varying sequences of A.toString and A.valueOf
methods on A.
So as other answers using Symbol.toPrimitive, .toString, .valueOf from integer. I would suggest the solution using an array with Array.pop like this.
let a = { array: [3, 2, 1], toString: () => a.array.pop() };
if(a == 1 && a == 2 && a == 3) {
console.log('Hello World!');
}
In this way, we can work with text like this
let a = { array: ["World", "Hello"], toString: () => a.array.pop() };
if(a == "Hello" && a == "World") {
console.log('Hello World!');
}
Surprisingly, yes. The == loose equality operator in JS calls the valueOf() method of the object that's being compared. Therefore, you can create a class that returns an internal value, then increments that interval value every time it's called. Like this:
class AClass {
constructor(initalVal) {
this.val = initalVal;
}
valueOf() {
return this.val++;
}
}
const a = new AClass(1);
console.log(a==1 && a==2 && a==3)
I know that there are a lot of other answers to this question, but this is how you'd do it with ES6 syntax.
Note: If you don't want this to happen, then you should use the === operator to check for strict instead. Like this:
class AClass {
constructor(initalVal) {
this.val = initalVal;
}
valueOf() {
return this.val++;
}
}
const a = new AClass(1);
console.log(a===1 && a===2 && a===3)
Yes, you can Do that, see the following JavaScript code:
let a = 0 // Create a variable and give it a value
if( a !== 1 && a !== 2 && a !== 3 )
{
console.log("true")
}
Explanation of the solution:
Simply , we add the not equal sign
before the == sign so that we tell the language that these values are
not equal to the value in the variable

Eloquent JavaScript 2nd Edition recursion exercise solution

I attempted to solve the recursion exercise of the online book eloquentjavascript 2nd edition:
Here is what the question states:
We’ve seen that % (the remainder operator) can be used to test whether
a number is even or odd by using % 2 to check if it’s divisible by
two. Here’s another way to define whether a (positive, whole) number
is even or odd:
Zero is even.
One is odd.
For any other number N, its evenness is the same as N - 2.
Define a recursive function isEven corresponding to this description.
The function should accept a number parameter and return a boolean.
Test it out on 50 and 75. See how it behaves on -1. Why? Can you think
of a way to fix this?
Here is what I have attempted and it works:
function isEven(number) {
if (number == 0) {
return true;
} else {
return (-number % 2 == 0) ? true : false;
}
return isEven(number - 2);
}
console.log(isEven(-1));
But, it seems to be a wrong answer because as I understood the author wants me to use - 2 method. I am wondering if this is indeed the correct answer or if it is wrong could someone point me in the right direction.
I think the reason you are getting confused is because you're not understanding how recursion works. The reason it is n-2 is, it is taking the number and subtracting 2 until it is either a zero or one. Therefore giving us a true or false.
Hope that helps. Read over how the process of recursion works.
The alternative solution that doesn't use the modulos operator % or any other built in functions in JavaScript is provided below. This solution instead relies on using another recursion to change negative value of the number.
function isEven(number) {
if (number < 0) {
return isEven(-number);
} else if (number == 1) {
return false;
} else if (number == 0) {
return true;
} else {
return isEven(number - 2);
}
}
console.log(isEven(50)); // true
console.log(isEven(75)); // false
console.log(isEven(-1)); // false
We call isEven(number -2) to go back to the top of the function with the number that was inputed intially but 2 less than before and it will keep doing that until the number is 1 or 0 and then it will be able to return the boolean true or false (even or odd).
I think the problem is to create an isEven function without using a mod/%/remainder operation
function isEven(number) {
if (number < 0) {
number = Math.abs(number);
}
if (number===0) {
return true;
}
if (number===1) {
return false;
}
else {
number = number - 2;
return isEven(number);
}
}
I guess it is important to add to this
it doesn't handle strings
it doesn't handle floats
don't put this into a production application
function isEven(n) {
n = Math.abs(n);
if (n==0)
return true;
else if (n==1)
return false;
else
return isEven(n-2);
}
console.log(isEven(-50)); // → true
console.log(isEven(75)); // → false
console.log(isEven(-75)); // → false
console.log(isEven(-1)); // → false
var isEven = function(n) {
// Get the absolute value of the number
// so we don't have to bother with negatives
n = Math.abs(n);
// We know that if we subtract 2 from our number
// until it is equal to zero, our number was even
// If our number isn't zero, this statement will be skipped
if(n === 0) return true;
// We know that if we subtract 2 from our number
// and it reaches a value of 1, it isn't even
// If our number isn't 1, this statement will be skipped
if(n === 1) return false;
// We subtract 2 from our original number and pass it
// back in to this function to check it over and over again
// until one of the conditions is met and the function can
// return a result
return isEven(n - 2);
}
// We test our function here
console.log(isEven(-21));
This is the leanest method I could come up with. Notice we call our isEven function from within itself and pass in the value of n - 2. This will constantly subtract 2 from our number and check to see if it is equal to 0 or 1 until we get a proper result and return the corresponding boolean.
I hope this clears things up a little.
How about the below code? Seems to work for me.
/*if > 1 keep looking, otherwise return reverse boolean value.
If negative value, inverse, to answer the last part of the question...
Also needed to use parseInt as the text value I used,
was considered a string value!
This being a recursive function which really isn't necessary,
means that in javascript we will get a
stack size exceeded error when the number becomes too large.*/
function isEven(x) {
return (x>1)?isEven(x-2):(x>=0)?!x:isEven(-x);
}
The book wants the following console.log outputs for such values
console.log(isEven(50));
// → true
console.log(isEven(75));
// → false
console.log(isEven(-2));
// → ??
The hint says "When given a negative number, the function will recurse again and again, passing itself an ever more negative number, thus getting further and further away from returning a result. It will eventually run out of stack space and abort." So I'm not sure if what I got represents that but my code and console.log outputs is shown below:
let isEven = function(num) {
if (num ===0) {
return true
} else if (num===1){
return false
} else {
return isEven(num-2)
}
}
console.log(isEven(50));
// → true
console.log(isEven(75));
// → false
console.log(isEven(-2));
// → RangeError: Maximum call stack size exceeded (line 3 in function isEven)```
The question requires that you don't' not to use the modulus operator (%).
// Your code here.
var isEven = function(a){
if (a == 0){ //case 1 : zero is even
return true;
}
else if(a == 1){ //case 2: one is odd
return false;
}
else {
return isEven(Math.abs(a-2)); //solves case 3 (negative numbers)
}
}
console.log(isEven(50));
// → true
console.log(isEven(75));
// → false
console.log(isEven(-1));
// → ?? ....false
This is the "correct" answer from the website. I say "correct" in quotes because I don't understand the 2nd 'else if' statement's return isEven(-n). Why did the author include the option to turn n into a positive number?
function isEven(n) {
if (n == 0)
return true;
else if (n == 1)
return false;
else if (n < 0)
return isEven(-n);
else
return isEven(n - 2);
}
Anyways, thought I'd share since I didn't see anybody post THIS answer.
//define recursive function isEven takes a positive whole number
//returns true if even
function isEven(x) {
//define innner function to loop over value
function find(current) {
//check if value == 0, return true
if (current == 0) {
return true
//check if value == 1 return false
} else if (current == 1) {
return false
//loop over value, subtracting 2 each time until either 0 or 1
//which returns the approriate true/false value based on evenness
} else {
console.log(current)
return find(current -2)
}
}
return find(x)
}
If the number is 1 or -1 so ODD, the function returns false,
If the number is 0 so EVEN, it returns true,
If then number nor 1,-1 nor 0 we have to first check if the number is positive or negative,
If the number is negative and less than -1 we call the function again but increase the number by 2 until we get -1 or 0;
If the number is positive and greater than 1 we call the function again but decrease the number by 2 until we get 1 or 0;
So for example, the number is 5 ->it`s positive and greater than 1 so call the function over and over again and decrease the number by 2 until the result will be 0 or 1:
5->3->1 //->false
function isEven(num) {
if (num == 1 || num == -1) {
return false;
} else if (num == 0) {
return true;
} else {
if (num < -1) {
return isEven(num + 2);
} else {
return isEven(num - 2);
}
}
}
Test result:
console.log(`-35 is even: ${isEven(-35)}`); //-> false
console.log(`-1 is even: ${isEven(-1)}`); //-> false
console.log(`0 is even: ${isEven(0)}`); //-> true
console.log(`32 is even: ${isEven(32)}`); //-> true
I see quite a few examples above using math functions and modulo operator. But I guess the author expects a simple recursive function to make the reader understand the functioning of the same and how if not properly defined it can lead to repetitive function calls and eventually lead to overflow of stack. I believe this code below can help you understand:
function isEven(n){
if(n==0){
return true;
} else if(n==1){
return false;
} else {
return isEven(n-2);
}
}
console.log(isEven(50));
console.log(isEven(75));
console.log(isEven(-1));
function isEven(num){
if(num %2 == 0) {
return true;
} else {
return false;
}
}
console.log(isEven(50));
// → true
console.log(isEven(75));
// → false
console.log(isEven(-1));
// → ??
function isEven(number) {
while(number>= -1)
{
return isEven(number-2) == 0 && number>-1 ? true : false;
}
}
console.log(isEven(-1));
I hope this helps:
const evenOrOdd = (N) => {
if (Math.abs(N) === 0) {
return console.log('Even');
} else if (Math.abs(N) === 1) {
return console.log('Odd');
}
evenOrOdd(Math.abs(N) - 2);
};
Google Chrome Console code results:
It utilizes all three given arguments on the problem. It can handle negative integers. It does not use the modulo operator. Lastly, I wasn't able to see any code snippet similar to what I provided thus I am enticed to share what I can.

Comparison operators !== against 0

I think that it is obvious what my code does.
Why does my code return a whole string if I use the !== operator? I know that arrays in Javascript start from at index 0, and here I'm entering the whole filename as the argument, so indexOf(".") will always be greater then 0. No, I'm not passing an .htaccess file here.
function getFileExtension(i) {
// return the file extension (with no period) if it has one, otherwise false
if(i.indexOf(".") !== 0) { //
return i.slice(i.indexOf(".") + 1, i.length);
} else {
return false;
}
}
// here we go! Given a filename in a string (like 'test.jpg'),
getFileExtension('pictureofmepdf'); return given string
// both operand are same type and value
But if I change comparasion to
(i.indexOf(".") > 0) // logs false
P.S. I case that you are asking, this is form usvsth3m.
indexOf() returns the index of the substring, so it can return 0, which would mean that the substring appears at position 0. If the substring is not found, it returns -1 instead, so change your if statement to reflect this logic:
if(i.indexOf(".") >= 0)
Additionally, you should use substring() to extract a substring from a string - slice() is for arrays.
return i.substring(i.indexOf(".") + 1, i.length);
Still, I think a better way to do this is with split():
var fileNameArray = i.split("."); // "foo.txt" --> ["foo" "txt"]
if(fileNameArray.length >= 2) {
return fileNameArray[1];
} else {
return false; //maybe you want to return "" instead?
}
The String method indexOf returns (if it is founded) the first index of the string you search, and remember, index can be zero, that why you have to do a strict comparision to check if indexOf it is not returning a boolean false.
I will suggest you to use lastIndexOf for this case because a file named as something.min.js will return min.js as an valid extension, and nope.
Well, to simplify, I omit that indexOf returns index which is typeof number, or -1, not returning boolean value FALSE in case when given value not found. So in case of comparing -1 to 0, result is true, and that's why I actually geting outputed given string, instead false. Well, MDN is in my bookmark bar now
var z = -1;
console.log(z >= 0); // evaluates false because -1 < 0
console.log(z !== 0); // evaluates true because -1 !== 0
// also if z > 0 it is !== 0, but could be < 0
So next code works like a charm.
function getFileExtension(i) {
// i will be a string, but it may not have a file extension.
// return the file extension (with no period) if it has one, otherwise false
if(i.indexOf(".") >= 0) {
return i.substring(i.indexOf(".") + 1, i.length);
} else {
return false;
}
}
getFileExtension('pictureofmepdf');

How to make 0 return true?

I have a situation where I am searching for something in an array, and if a value is found, I do something. I am doing this by setting a variable to undefined, and then when the value is found, setting to the index of the element found. This would work if the value returned is anything but 0, but if it is 0, then it returns as false. How can I work around this?
var index = undefined;
for(var i=0; i<ARRAY; i++)
{
if(CONDITION)
index = i;
}
if(index)
{
DO SOMETHING
}
So my problem occurred when the index turned out to be zero, because this returned false. The reason I want to do it this way is because I am not sure if it exists in the array or not.
How about testing the result to see whether it's >= 0 instead of relying on its truthyness?
if (index >= 0) { ... }
The undefined value is not >= 0 so that should work.
Why not be 100% explicit? This is, after all, what you're actually intending to check:
if (typeof index === 'number')
{
// DO SOMETHING
}
I prefer this even to checking >= 0 since that operator gives some weird results for non-numeric values:
Input | >= 0
------------
"1" | true
false | true
null | true
[] | true
"" | true
(See this jsFiddle for evidence.)
You mean you have a variable that may be undefined or some number, and you want undefined to be distinguishable from 0?
Then:
if (index) // wrong
if (index >= 0) // right
Or you can use type-aware comparisons:
if (index !== undefined) { .. }
You can use -1 to indicate the index was not found in the array. As you mentioned, 0 will be implicitly cast to a "false" if you use it like a boolean. You can use === to avoid an implicit cast.
You could... not do it like that, because you need to work within JS's definition of truthiness, or check explicitly for undefined.
0 is falsey in javascript; use === to test whether a value is actually false:
foo = 0;
foo == false //true
foo === false //false
As you're setting the value to undefined one way of testing is to see whether the value is Not a Number:
if (!isNaN(foo))
{
//foo is numeric
}
I wrote these simple utility functions to help with more math-oriented tasks:
function isFalsy(val) {
return (((!val)&&(val!==0))||(val === null)||(val === NaN)||(val === ""))
}
function isTruthy(val) {
return !isFalsy(val)
}

Categories