Why does the statement `0 < 0.5 < 1` reduce to false? - javascript

I recently discovered the ECMAScript Spec, which I was able to use to answer a question I've had about Math.random() for a while; namely whether or not it would ever generate 0 without the help of Math.floor().
The ECMAScript Spec specifies that 0 <= Math.random() < 1, unlike literally anyone else for some reason. I hopped over to the console and ran a test before saving it in my notes but noticed that statement reduces to false.
Below is a function that tests everything about comparison statements that I thought might be causing this lie. I call the function twice to generate two arrays of Boolean values, and the results seem to imply that literally this statement: 0 <= Math.random() < 1 - and this statement alone, returns FALSE where it should return TRUE. Especially when you consider bonus round where I test the exact same statement but with an additional comparison tacked onto the end, and it also returns true
function getTruths( a, b, c ) {
return [
a + 1 < b + 1,
a + 1 < c + 1,
b + 1 < c + 1,
a + 1 < b + 1 < c + 1,
a + 0 < b + 0,
a + 0 < c + 0,
b + 0 < c + 0,
a + 0 < b + 0 < c + 0
];
}
function demonstrate() {
// array of truth
console.log( getTruths( 0, 1, 2 ) );
// array of lies
console.log( getTruths( 0, 0.5, 1 ) );
// bonus round
return [ 0 < 0.5 < 1 < 1.5 ];
}
demonstrate();
So I did some more plucking around and learned that it isn't just that. it seems that a and b can actually be any value lower that one and equal to or greater than zero, just as long as b is still bigger than a, and c is still equal to 1 of course... and given those parameters, no matter what, the return is still FALSE. If you add 1 to everything though suddenly you're in good shape again, just as in the function provided above.
Anyway can someone explain this to me? Thanks.

a < b < c
is interpreted as
(a < b) < c
The result value from a relational operator like < is a boolean, either true or false. If c is a number, then, that boolean will be converted to a number, either 1 (true) or 0 (false). Thus c is compared to either 0 or 1, not the values of either a or b.
The proper way to write "is b strictly between a and c" is
a < b && b < c

Related

What does >>>= mean? [duplicate]

This question already has answers here:
JavaScript triple greater than
(4 answers)
Closed 2 years ago.
While I was checking the lodash code, I came up with a question I was curious about.
// slice.js
function slice(array, start, end) {
let length = array == null ? 0 : array.length
if (!length) {
return []
}
start = start == null ? 0 : start
end = end === undefined ? length : end
if (start < 0) {
start = -start > length ? 0 : (length + start)
}
end = end > length ? length : end
if (end < 0) {
end += length
}
length = start > end ? 0 : ((end - start) >>> 0)
start >>>= 0
let index = -1
const result = new Array(length)
while (++index < length) {
result[index] = array[index + start]
}
return result
}
export default slice
Specifically, I am curious about why this code exists in this part.
((end - start) >>> 0)
As far as I know, the bit operator shifts the position of a binary number, but I am curious why it shifts 0 times.
>>>=
And >>>= This operator is the first time I saw it.
Does anyone know what it means?
>>> is called unsigned right shift (or zero fill right shift). You may have known of left/right shift.
Basically it shifts the specified number of bits to the right. You can find it here
So >>>= is basically the right shift assignment.
a >>>= b
is equivalent to:
a = a >>> b
The unsigned right shift operator (a >>> b) does shift the bits of the variable a by b bits as you said.
It always returns a positive integer, so a >>> 0 would be used to make sure that the input isn't say, negative, or a string, or otherwise not a positive integer.
a >>>= b is similar to a += b, that is, it applies the right shift b to a and then assigns the output to a, similar to how a += b adds b to a and then assigns the result to a. So a >>>= b is equivalent to a = a >>> b like a += b is equivalent to a = a + b.

Reverse Bits JavaScript

The problem is standard but the solution in JavaScript takes a lot more effort to code.
I got the solution but my answer is coming half of what is desired.
Problem Description
Reverse the bits of a 32-bit unsigned integer A.
Problem Constraints
0 <= A <= 2^32
Input Format
The first and only argument of input contains an integer A.
Output Format
Return a single unsigned integer denoting minimum xor value.
Example Input
Input 1:
0
Input 2:
3
Example Output
Output 1:
0
Output 2:
3221225472
My solution
function modulo(a, b) {
return a - Math.floor(a/b)*b;
}
function ToUint32(x) {
return modulo(parseInt(x), Math.pow(2, 32));
}
function revereBits(A){
A = A.toString(2);
while (A.length < 31){
A = "0"+A;
}
var reverse = 0;
var NO_OF_BITS = A.length;
for(var i = NO_OF_BITS; i >= 1; i--){
var temp = (parseInt(A, 2) & (1 << i - 1));
if(temp){
reverse |= 1 << (NO_OF_BITS - i);
}
}
if( reverse << 1 < 0 ) reverse = ToUint32(reverse << 1);
return reverse;
}
Now, in the line
if( reverse << 1 < 0 ) reverse = ToUint32(reverse << 1);
You see that I have to double the answer. I cannot, however, get the part of why is this required.
I took the approach from https://www.geeksforgeeks.org/write-an-efficient-c-program-to-reverse-bits-of-a-number/
Had to make few adjustments to it. For example, run the loop from 31 to 1 rather than 0 to 31. The latter gives negative values in first left shift operation for i = 0 itself.
Can someone please help in fixing this solution and point to the problem in this?
UPDATE - Problem is related to Bit manipulation. So guys, please don't answer or comment for anything consisting of in-built string functions of Javascript. Cheers!
You should be able to do it using just bitwise operators, and a typed array to solve the sign issue:
Update
Changing slightly approach of the rev function after #bryc comment. Since having multiple function for "history" purpose makes the answer difficult to read, I'm putting first the latest code.
However, I'm keeping the comments about the different steps – the rest can be found in the edit history.
function rev(x) {
x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
x = ((x >> 4) & 0x0F0F0F0F) | ((x & 0x0F0F0F0F) << 4);
x = ((x >> 8) & 0x00FF00FF) | ((x & 0x00FF00FF) << 8);
x = (x >>> 16) | (x << 16);
return x >>> 0;
}
This is the same code you would write in other languages as well to reverse bits, the only difference here is the addition of the typed array.
As #harold pointed out in the comment, the zero-fill right shift returns an unsigned (it's the only bitwise operator to do so) therefore we can omit the typed array and just add >>> 0 before the return.
In fact, doing >>> 0 is commonly used to simulate the ToUint32 in JS polyfilll; e.g.:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every
// 2. Let lenValue be the result of calling the Get internal method
// of O with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = O.length >>> 0;
function reverseBits(integer, bitLength) {
if (bitLength > 32) {
throw Error(
"Bit manipulation is limited to <= 32 bit numbers in JavaScript."
);
}
let result = 0;
for (let i = 0; i < bitLength; i++) {
result |= ((integer >> i) & 1) << (bitLength - 1 - i);
}
return result >>> 0; // >>> 0 makes it unsigned even if bit 32 (the sign bit) was set
}
Try this:
function reverseBits(num) {
let reversed = num.toString(2);
const padding = "0";
reversed = padding.repeat(32 - reversed.length) + reversed;
return parseInt(reversed.split('').reverse().join(''), 2);
}
console.log(reverseBits(0)); // 0
console.log(reverseBits(3)); // 3221225472

Why is [1,2,3] <= [1,2,3] true in javascript? [duplicate]

I'm trying to compare two arrays in javascript.
What I'd like is:
a < b &iff; ∃ i ≥ 0 s.t. a[i] < b[i] and ∀ 0 ≤ j < i, a[j] = b[j]
So arrays of non-negative numbers work as desired:
firebug> [0,1,2,3,4] < [1,0,0]
true
And comparing negative numbers with zero works as expected:
firebug> [-1, 1] < [0, 0]
true
But comparing negative numbers with negative numbers is... suprising:
firebug> [-2] < [-1]
false
firebug> -2 < -1
true
What's going on here, so I can correct my intuition for what array comparison means in javascript?
The array is converted to a string, which comes down to .join(), which in turn joins the elements with a comma (,) as delimiter.
"-1,1" < "0,0" === true
because the character code of - (45) is smaller than the character code of 0 (48).
On the other hand,
"-2" < "-1" === false
because the second character codes are compared (the first are both -, so that doesn't give a result yet), and the character code for 2 (50) is bigger than the character code of 1 (49), so this yields false.
It comes down to a lexographical sorting (i.e. by character codes) and not a numerical one, even if the elements are numbers (because of the string coercion).
Basically comparing arrays is not recommended. It is implicitly defined as string comparison, but this can yield surprising results.
There's no such thing as JavaScript array comparison in any form similar to what you describe.
What's happening in all cases is that your arrays are being converted first to strings by joining their contents together. Thus, the string "-2" is not less than the string "-1", because the character "2" comes after "1" in the character set. Similarly, "-1,1" is less than "0,0" because the "-" character comes before the digits.
You can see for yourself that in all cases your comparisons:
array1 < array2
get exactly the same results as:
("" + array1) < ("" + array2)
or:
array1.join(",") < array2.join(",")
I couldn't find an answer about how to actually compare arrays in Javascript and get "expected" results, so here is the code
compareArrays = function(a, b) {
var elA, elB, i, len;
for (i = 0, len = Math.min(a.length, b.length); i < len; i++) {
elA = a[i], elB = b[i];
if (elA > elB) return 1;
if (elA < elB) return -1;
}
return b.length - a.length;
};
console.log(compareArrays([-2], [-1])) # -1
console.log(compareArrays([], [])) # 0
console.log(compareArrays([null], [undefined])) # 0
console.log(compareArrays([1, 2, 3], [1, 2, 3, 4])) # 1
console.log(compareArrays([0, 2], [0, 1])) # 1
console.log(compareArrays([1], [NaN])) # 0
console.log(compareArrays([NaN], [1])) # 0

How "Math.random() * arr.length | 0" works for return a random index for an array

I've been working in a legacy code that have a certain functionality that should return a random item for array and I see the following expression:
array[Math.random() * arr.length | 0]
My first impression was try to undestand the | operator but i can't figure out how does work.
I test the expression in the chrome console and I see that always returns a valid index with this:
let array = [1,2,3,4]
for(let i = 0; i < 5000; i++){
console.log(array[Math.random() * arr.length | 0]);
}
How "Math.random() * arr.length | 0" works for return a random index for an array?
Math.random() returns a number >= 0 and < 1.
* arr.length returns a number >= 0 and < arr.length, yet this can't be used as an index, because it would have a fractional part
| 0 coerces the left expression to a integral number then applies the bitwise or with the number zero, which is always the other number
This said, what makes this work is the implicit conversion (called coersion) in the operator |.
In this context, | 0 is being used to round down to the nearest integer. So Math.random generates a number in the range 0 <= number < 1, then this gets multiplied by arr.length giving a number between 0 <= number < arr.length, which is then rounded down giving an integer between 0 and arr.length -1, inclusive
let array = [1, 2, 3, 4]
function randomIndex() {
let random = Math.floor(Math.random () * array.length)
return array [random]
}
console.log(randomIndex())

What is the best way to determine if a given number is a power of two?

Is there a more effective way to return true if n is a power of two or false if not?
function isPowerOfTwo(n) {
return Math.pow(2, Math.round(Math.log(n) / Math.log(2)));
}
You can actually use ECMAScript5 Math.log:
function powerOfTwo(x) {
return (Math.log(x)/Math.log(2)) % 1 === 0;
}
Remember, in math, to get a logarithm with an arbitrary base, you can just divide log10 of the operand (x in this case) by log10 of the base. And then to see if the number is a regular integer (and not a floating point), just check if the remainder is 0 by using the modulus % operator.
In ECMAScript6 you can do something like this:
function powerOfTwo(x) {
return Math.log2(x) % 1 === 0;
}
See the MDN docs for Math.log2.
Source: Bit twiddling Hacks,
function powerOf2(v) {
return v && !(v & (v - 1));
}
You just bitwise AND the previous number with the current number. If the result is falsy, then it is a power of 2.
The explanation is in this answer.
Note:
This will not be 100% true for programming, mathematical, [also read 'interviewing']. Some edge cases not handled by this are decimals (0.1, 0.2, 0.8…) or zero values (0, 0.0, …)
Using bitwise operators, this is by far the best way in terms of efficiency and cleanliness of your code:
function PowerofTwo(n){
return ((x != 0) && !(x & (x - 1)));
}
what it does is checks the bits that make up the number, i.e. 8 looks like this:
1 0 0 0
x-1 or 7 in this case looks like this
0 1 1 1
when the bitwise operator & is used it invokes an && on each bit of the number (thus 1 & 1 = 1, 1 & 0 = 0, 0 & 1 = 0, 0 & 0 = 1):
1 0 0 0
-0 1 1 1
=========
0 0 0 0
since the number turns into an exact 0 (or false when evaluted as a boolean) using the ! flag will return the correct answer
if you were to do this with a number like 7 it would look like this:
0 1 1 1
-0 1 1 0
=========
1 1 1 0
returning a number greater than zero causing the ! flag to take over and give the correct answer.
A number is a power of 2 if and only if log base 2 of that number is whole. The function below computes whether or not that is true:
function powerOfTwo(n){
// Compute log base 2 of n using a quotient of natural logs
var log_n = Math.log(n)/Math.log(2);
// Round off any decimal component
var log_n_floor = Math.floor(log_n);
// The function returns true if and only if log_n is a whole number
return log_n - log_n_floor == 0;
}
Making use of ES6's Math.clz32(n) to count leading zeros of a 32-bit integer from 1 to 2³² - 1:
function isPowerOf2(n) {
return Math.clz32(n) < Math.clz32(n - 1);
}
/**
* #param {number} n
* #return {boolean}
*/
const isPowerOfTwo = function(n) {
if(n == 0) return false;
while(n % 2 == 0){
n = n/2
}
return n === 1
};
function PowerOfTwo(n){
// Exercise for reader: confirm that n is an integer
return (n !== 0) && (n & (n - 1)) === 0;
}
console.log(PowerOfTwo(3))
console.log(PowerOfTwo(4))
This is for a specific online course that requires an answer in a specific way.
Without using libraries and other methods just loops and .push.
you need to create an inner loop using while
it should start with 1
keep multiplying it with 2 until i,j,k or whatever is greater than the current number(array) so it will have to do 2 4 6 8 10 12 14 16 18 until it is greater than the number
then it will go to the outer loop then repeat again until
const numbers = [5, 3, 9, 30];
const smallestPowerOfTwo = arr => {
let results = new Array;
// The 'outer' for loop -
for (let i = 0; i < arr.length; i++) {
number = arr[i];
// The 'inner' while loop
j = 1;
while (j < number) { //starting from 1 then multiplied by 2 then by 2 again untill it is more than the number
j = j * 2;
}
results.push(j);
}
return results
}
console.log(smallestPowerOfTwo(numbers))

Categories

Resources