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.
Related
I was writing an algorithm to compare how many bits are different between 2 numbers using this function
var hammingDistance = function(x, y) {
let result = 0;
while (x !== 0 || y !== 0) {
// This line is incorrect
if (x & 1 !== y & 1) result++;
x = x >> 1;
y = y >> 1;
}
return result;
};
But my result is always 1 less than the correct answer, and it turns our my function is wrong when comparing the left most digit, such as 0011 and 0100. It returns 2 instead of 3.
https://i.imgur.com/P46RyZr.png
I can use XOR instead of !== to get the correct answer. But I'm wondering why?
Your problem is that !== has a higher precedence than &. So your condition is actually (x & (1 !== y)) & 1. Use explicit grouping instead:
if ((x & 1) !== (y & 1)) result++;
It works with ^ because that has a lower precedence than &.
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
I am fairly new to programming, just knowing the basics in Javascript and Swift. I am trying to write a simple program which creates, from any entered number, a two digit number by summing up the first and last digit until only two digits are finally left.
Here is an example:
num = 1234567:
1+7 = 8
2+6 = 8
3+5 = 8
4 remains
So the first result is: 8884. Now everything is added again:
8+8 = 16
8+4 = 12
The result is 1612. Again everything is summed up:
1+2 = 3
6+1 = 7
The result is 37 - which is also the final result.
I am struggling with two things. First the while loop. I was thinking about casting num.toString() and then do a while loop like this in which I change the string to an int again:
num.toString()
while (num.length > 2) {
num = num.parseInt(num, 10);
...
}
But this doesn't work properly, plus it gets crazy complicated I guess because I would have to switch between string and int each new round, right?
I know how to add all digits together until I get a two digit number (it took me a while to figure this one out) and I am not even sure if this is a good way to do it:
var sum = num
.toString()
.split('')
.map(Number)
.reduce(function (a, b) {
return a + b;
}, 0);
But obviously I cannot use this here and I have no idea how to change the code so that the first and last digit are added together.
Slightly different approach:
function sum(num) {
var numString = num.toString();
var newString = "";
while (numString.length > 1) { // (1)
newString += (parseInt(numString[0]) + parseInt(numString[numString.length - 1])).toString(); // (2)
numString = numString.substring(1, numString.length - 1); // (3)
}
newString += numString; // (4)
if (newString.length > 2) { // (5)
console.log(newString)
return sum(newString);
} else {
return newString;
}
}
console.log(sum(1234567));
Outputs:
8884
1216
73
Brief explanation of what's going on:
(1) Your while loop will process the string until there's either 1 or
0 characters left
(2) Add the sum of your first and last character to
your newString
(3) Remove the first and last characters from your
numString now that they've been saved to the newString. Because
you're overwriting the value in numString and shrinking it, this
will eventually satisfy the while condition of a numString with
less than 2 characters
(4) Add the remaining characters to
newString, which will either be 1 or 0 characters depending on the
length of the original number
(5) if your newString is more than 2
characters, run this method again. Otherwise return your result
Try this buddy. Its just using simple for loop. Its loops upto half of number and add corresponding. The final result according to ur logic should be 73 not 37
function sum(num){
//if num is greater than or equal to 2 end the function and return final value
if(num.length <= 2) return num;
//converting the num to string beacuse first time input will be number
num = String(num);
let result = '';
//creating a loop upto half of length of the num
for(let i = 0;i<num.length/2;i++){
//if the number is not middle one
if(i !== num.length - 1 - i)
{
//adding the sum of corresponding numbers to result
result += parseInt(num[i]) + parseInt(num[num.length - 1 - i]);
}
//if the number is middle number just add it to result
else result += num[i]
}
return sum(result);
}
console.log(sum(1234567))
You could take a nested while loop and check the string length for the outer loop and the left and right indices for the inner loop
function add(n) {
var s = n.toString(),
l, r,
sum;
while (s.length > 2) {
l = 0;
r = s.length - 1;
sum = [];
while (l < r) {
sum.push(+s[l++] + +s[r--]);
}
if (l === r) sum.push(s[l]);
s = sum.join('');
}
return +s;
}
console.log(add(1234567));
The same but with a recursive function.
function add(n) {
var s = n.toString(),
l = 0, r = s.length - 1,
sum = [];
if (s.length <= 2) return n;
while (l < r) sum.push(+s[l++] + +s[r--]);
if (l === r) sum.push(s[l]);
return add(+sum.join(''));
}
console.log(add(1234567));
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))
This question already has answers here:
What is the JavaScript >>> operator used for? [duplicate]
(2 answers)
Closed 9 years ago.
I just saw this code:
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (elt /*, from*/) {
var len = this.length >>> 0; // 3rd line
var from = Number(arguments[1]) || 0;
from = (from < 0) ? Math.ceil(from) : Math.floor(from);
if (from < 0) from += len;
for (; from < len; from++) {
if (from in this && this[from] === elt) return from;
}
return -1;
};
}
What does the >>> do on the 3rd line?
That's an unsigned right shift operator. Interestingly, it is the only bitwise operator that is unsigned in javascript.
Lets have a practical application of it..
suppose you want to divide a number by 4
yes 8/4 = 2
right !
what if you can do that using bitwise operations:
that will be much faster right ?
do this in your console now..
20 >>> 2
gives 5
how ??
when we convert 20 to binary we get 10100
now shift 2 bits to right , you will get 101 which is equivalent to 5
Cheers!
From MDN docs on JavaScript operators:
Zero-fill right shift
a >>> b
Shifts a in binary representation b bits to the right, discarding bits shifted off, and shifting in zeros from the left.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
It's a bitwise operator.
a >>> b
Shifts a in binary representation b (< 32) bits to the right,
discarding bits shifted off, and shifting in zeros from the left.