Flag bit computation and detection - javascript

In some code I'm working on I should take care of ten independent parameters which can take one of two values (0 or 1). This creates 2^10 distinct conditions. Some of the conditions never occur and can be left out, but those which do occur are still A LOT and making a switch to handle all cases is insane.
I want to use 10 if statements instead of a huge switch. For this I know I should use flag bits, or rather flag bytes as the language is javascript and its easier to work with a 10 byte string with to represent a 10-bit binary.
Now, my problem is, I don't know how to implement this. I have seen this used in APIs where multiple-selectable options are exposed with numbers 1, 2, 4, 8, ... , n^(n-1) which are decimal equivalents of 1, 10, 100, 1000, etc. in binary. So if we make call like bar = foo(7), bar will be an object with whatever options the three rightmost flags enable.
I can convert the decimal number into binary and in each if statement check to see if the corresponding digit is set or not. But I wonder, is there a way to determine the n-th digit of a decimal number is zero or one in binary form, without actually doing the conversion?

Just use a bitwise-and. In C/C++, this would be:
if (flags & 1) {
// Bit zero is set.
}
if (flags & 2) {
// Bit one is set.
}
if (flags & 4) {
// Bit two is set.
}
...
For production goodness, use symbolic names for the flag masks instead of the magic numbers, 1, 2, 4, 8, etc.
If the flags are homogeneous in some way (e.g., they represent ten spatial dimensions in some geometry problem) and the code to handle each case is the same, you can use a loop:
for (int f = 0; f < 10; ++f) {
if (flags & (1 << f)) {
// Bit f is set.
}
}

You can use a bitwise and:
10 & 2^1 is true because 10 = 1010b
^ 1
8 & 2^1 is false because 8 = 1000b
^ 0
10 & 2^3 is true because 10 = 1010b
^ 1

You could get a number that has the n-th bit set and AND it with your number. If the result is zero your number didn't have the bit set. Otherwise, it did. Look here, also.

Related

Write a function that returns the square of a number without using *,+ or pow

The task is to write a function that takes n as an input where n is a number (from -32768 to 32768) and returns the square of that number. Simple task except for the fact that we cannot use any operators such as *,+ or even use any Math. functions such as pow. eval is not allowed as well.
Even more challenging is that we must keep the character code count less than 39 characters.
I absolutely cannot think of a way to get the square of a number without using the + or *. And even worse, to keep the character count less, it's impossible for me.
Codes like this won't work because: I used the plus sign and the character count is more than 60.
function sq(n){
var res=n;
for(i=1;i<n;i++)
res+=n;
return res;
}
If n is a decimal, we are expected to return the nearest whole number as the result.
Thank you for reading all of this!
Edit: My problem has been solved. Thank you to everyone who has tried to help me with their codes as it helped me gain a new aspect of solving each problems.
Thank you very much again!
You can try this as well
function multiply(a) {
return a / (1 / a);
}
console.log(multiply(6))
console.log(multiply(4))
The repeat() method returns a new string with a specified number of copies of the string it was called on. See here
This approach is limited to positive and integer numbers only.
// Another method
function multiplytwo(a) {
return ("i").repeat(a).repeat(a).length
}
console.log(multiplytwo(4))
console.log(multiplytwo(25))
//creating a string “i” and repeating it “a” times, then repeats that “a” times, and then returning the length.
You could divide n by 1 / n
For rounding off without using Math.round, I have used this:
s=n=>(r=>(r-~~r<.5?0:1)- -~~r)(n/(1/n))
console.log(s(5));
console.log(s(4.4));
console.log(s(-4.44));
This has 39 characters.
** is not in your list, so you might be able to use it:
sq = n => n ** 2
console.log(sq(5));
You could also use - twice, instead of +:
sq=n=>{s=0;for(let i=n;i>0;i--)s=s-(-n);return s}
console.log(sq(5));
(function definition is 49 characters)
If anyone still needs a solution that passes tests.
#adiga's solution works nicely. But if you need to be under 39 characters you can exploit JS implicit type coercion: substitute r-~~r<.5?0:1 by r-~~r<.5. It will give you a boolean which will be coerced to either 1 or 0. So, final solution is following:
s=n=>(r=>(r-~~r<.5)- -~~r)(n/(1/n))
As this just got brought back up, here is a 22-character solution:
sq=n=>~~-(-.5-n/(1/n))
;[[0, 0], [1, 1], [2, 4], [3, 9], [4.4, 19], [-4.44, 20], [32768, 1073741824]]
.forEach (([n, s]) => console .log (`sq(${n}) == ${s} //=> ${sq(n) == s}`))
Explanation
Like other answers here it takes advantage of the fact that n / (1/n) is mathematically equivalent to squaring n. This is also helped by the fact that although 1 / 0 is Infinity, 0 / Infinity gives back 0. Mathematically this is iffy, but for the problem it's perfect. The trick is then to round this to the nearest integer. We could do so like this:
let sq = (n) => Math .round(n / (1 /n) + 0.5)
But we have two issues here. First we take the fact that Math.round is disallowed by the rules. Here we can use a common substitution for Math.round, namely ~~. This is simply two consecutive applications of the bitwise NOT operator, which first removes any fractional part to convert the result to a 32-bit integer, then inverts all the bits. Doing it a second time acts much like integer truncation, giving something more like:
let sq = (n) => ~~ (n / (1 /n) + 0.5)
But we still have a + in the definition, also disallowed. But that can be replaced by subtracting the negation of the value, with a version like this:
let sq = (n) => ~~ (n / (1 /n) - -0.5)
Now, minifying this would give us
sq=(n)=>~~(n/(1/n)- -.5)
and this is an equivalent 22-character solution. But for some reason I really didn't like the space in that version, and since (a - b) is equivalent to - (b - a), we can create this alternative:
let sq=n=>~~-(-.5-n/(1/n))
I'm not generally much of a code-golfer. I simply don't see the point. But this was a fun little challenge.

Can anyone explain this process with converting decimal numbers to Binary

I have looked around the internet for a way to convert decimal numbers into binary numbers. and i found this piece of code in some forum.
var number = prompt("Type a number!") //Asks user to input a number
var converted = []; // creates an array with nothing in it
while(number>=1) { //While the number the user typed is over or equal to 1 its shoud loop
converted.unshift(number%2); // takes the "number" and see if you can divid it by 2 and if theres any rest it puts a "1" otherwise "0"
number = Math.floor(number/2); // Divides the number by 2, then starts over again
}
console.log(converted)
I'm not understanding everything completely, so i made some comments of what i think the pieces of code do. But anyone that can explain in more detail? or is the way i think the code does correct?
This code is based on a technique for converting decimal numbers to binary.
If I take a decimal number. I divide it by two and get the remainder which will either be 0 or 1. Once you divide 57 all the way down to 0. You get the binary number for example:
57 / 2 = 28 r 1; 28 / 2 = 14 r 0; 14 / 2 = 7 r 0; 7 / 2 = 3 r 1; 3 / 2 = 1 r 1; 1 / 2 = 0 r 1;
The remainders are the binary number. Sorry if it's a bit hard to read. I definitely recommend writing it out on paper. Read from the last remainder to the first, the remainders look like this: 111001
Reverse it to make it correct. array.unshift() can do this or you could use array.push() then array.reverse() after the while loop. Unshift() is probably a better approach.
57 in decimal is equal to 111001, which you can check.
BTW, this algorithm works for other bases, as long you are converting from decimal. Or at least as far as I know.
I hope this helped.
It seems like you've got the gist of it down.
Let's start with a random number:
6 === 110b
Now let's see what the above method does:
The number is geq than 1, hence, let's add the last bit of the number to the output
6%2 === 0 //output [0]
the number we're working with after dividing the number by two, which is essentially just bit-shifting the whole thing to the right is now 11b (from the original 110b). 11b === 3, as you'd expect.
You can alternatively think of number % 2 as a bit-wise AND operation (number & 1):
110
& 1
-----
0
The rest of the loop simply carries the same operation out as long as needed: find the last bit of the current state, add it to the output, shift the current state.

Using bitwise operators in javascript

I am creating a bitmask in javascript. It works fine for bit 0 through 14. When I set only bit fifteen to 1. It yields the integer value of "-2147483648" instead of "2147483648". I can do a special case hack here by returning hardcoded "2147483648" for bit fifteen but I would like to know the correct way of doing it.
Sample code:
function join_bitmap(hex_lower_word, hex_upper_word)
{
var lower_word = parseInt(hex_lower_word, 16);
var upper_word = parseInt(hex_upper_word, 16);
return (0x00000000ffffffff & ((upper_word<<16) | lower_word));
}
Above code returns -2147483648 when hex_lower_word is "0x0" and hex_upper_word is "0x8000" instead of 2147483648
The reason for this is because Javascript's bit shift operations use signed 32-bit integers. So if you do this:
0x1 << 31 // sets the 15th bit of the high word
It will set the sign bit to 1, which means negative.
On the other hand instead of bit shifting you multiply by powers of two, you'll get the result you want:
1 * Math.pow(2, 31)
The reason is, you are setting the sign bit...
2147483648 is 1 followed by 31 zeros in binary...
As you are doing a bitwise operation, the output is always a signed 32 bit number, which makes the 32nd bit the sign bit, so you get a negative number...
Update
(upper_word * Math.pow(2, 16))
will give positive 2147483648.
But, you still have the OR operation, which puts us back to square one...
As previous answers explained, the bitwise operators are 32 bit signed. Thus, if at any point along the way you set bit 31, things will go badly wrong.
In your code, the expression
(upper_word<<16) | lower_word)
is evaluated first because of the parentheses, and since upper_word has the top bit set, you will now have a negative number (0x80000000 = -2147483648)
The solution is to make sure that you do not shift a 1into bit 31 - so you have to set bit 15 of the upper word to zero before shifting:
mask15 = 0x7fff;
((upper_word&mask15)<<16|lower_word)
This will take care of "numbers that are too big become negative", but it won't solve the problem completely - it will just give the wrong answer! To get back to the right answer, you need to set bit 31 in the answer, iff bit 15 was set in upper_word:
bit15 = 0x8000;
bit31 = 0x80000000;
answer = answer + (upper_word & bit15)?bit31:0;
The rewritten function then becomes:
function join_bitmap(hex_lower_word, hex_upper_word)
{
var lower_word = parseInt(hex_lower_word, 16);
var upper_word = parseInt(hex_upper_word, 16);
var mask15 = 0x7fff;
var bit15 = 0x8000;
var bit31 = 0x80000000;
return 0xffffffff & (((upper_word&mask15)<<16) | lower_word) + ((upper_word & bit15)?bit31:0);
}
There isn't just a single "hard coded special case" - there are 2 billion or so. This takes care of all of them.

numbers and toFixed , toPrecision in Javascript?

Regarding the famous issue of 1.01+1.02 which is 2.0300000000000002
one of the workarounds is to use toFixed : e.g.
(1.01+1.02).toFixed(2) --->"2.03"
But I saw a solution with toPrecision
parseFloat((1.01+1.02).toPrecision(10))-->"2.03"
But lets have a look at n in
toFixed(n)
toPrecision(n)
How would I know what is n ?
0.xxxxxxxxxxx
+
0.yyyyyyyyyyyyy
---------------------
0.zzzzzzzzzzzzzzzzzzzzzzzzz
^
|
-----??????------
each number being added can have a different decimal digits...
for example :
1.0002+1.01+1.03333--> 3.0435300000000005
how would I calculate the n here ? what is the best practice for this (specific) issue ?
For addition as in this situation I would check the number of decimal places in each operand.
In the simplest of situations the number of decimal places in the operand with the greatest number of decimal places is the value of n.
Once you have this, use which ever method you like to truncate your value. Then get rid of trailing zeros.
You may encounter trailing zeros in situations such as 1.06 + 1.04, the first step would take you to 1.10 then truncating the zero would give 1.1
In your last example 1.0002+1.01+1.03333 greatest number of decimal places is 5 so you are left with 3.04353 and there are no trailing zeros to truncate.
This returns the expected output:
function add(){
// Initialize output and "length" properties
var length = 0;
var output = 0;
// Loop through all arguments supplied to this function (So: 1,4,6 in case of add(1,4,6);)
for(var i = 0; i < arguments.length; i++){
// If the current argument's length as string is longer than the previous one (or greater than 0 in case of the first argument))
if(arguments[0].toString().length > length){
// Set the current length to the argument's length (+1 is to account for the decimal point taking 1 character.)
length = arguments[0].toString().length +1;
}
// Add the current character to the output with a precision specified by the longest argument.
output = parseFloat((output+arguments[i]).toPrecision(length));
}
// Do whatever you with with the result, here. Usually, you'd 'return output;'
console.log(output);
}
add(); // Returns 0
add(1,2,3); // Returns 6
add(1.01,2.01,3.03); // Returns 6.05
add(1.01,2.0213,3.3333); // Returns 6.3646
add(11.01,2.0213,31.3333); // Returns 44.3646
parseFloat even gets rid of trailing zero's for you.
This function accepts as many numbers as parameters as you wish, then adds these together taking the numbers' string length into account, when adding them. The precision used in the addition is dynamically modified to fit the "currently added" argument's length.
Fiddle
If you're doing calculations, you have a couple of choices:
multiply the numbers by eg 100, to convert to integers, then do the calculations, then convert back again
do the calculations, dont worry about the rounding errors, then round the result at display time
If you're dealing with money/currencies, the first option is probably not a bad option. If you're just doing scientific maths, I would personally not worry about it, and just round the results at display time, eg to 6 significant figures which is the default for my c++ compiler (gcc; not sure if it is in the c++ standards or not, but if you print 1.234567890 in gcc c++, the output is 1.23457, and the problem is avoided)
var a = 216.57421;
a.toPrecision(1); // => '200' because 216 with 1 < 5;
a.toPrecision(2); // => '220' because 216 with 6 >= 5;
a.toFixed(1); // => 216.6 because 7 >= 5;
a.toFixed(2); // => 216.57 because 4 < 5;

how does radix in parseInt really work?

I'm wondering how radix calculation really works in parseInt.
I want to build a own formula/function to do exactly the same as parseInt, so that I can put it into another programming language or tell my students in my math class so that they can learn it (not that I would never do it).
I just want to know how it works.
I put together a little fiddle: http://jsfiddle.net/Cy6Bx/
EDIT just figure it out by myself here is the result: https://tinker.io/3ca4c
It dose not have all the validation and such that parseInt has, but it dose the basic things to understand whats going on
"I'm wondering how radix calculation really works in parseInt."
In fact, is not rocket science, the most simple parseInt implementation (agnostic to the language) would iterate the string (in reverse order) and multiply the radix factor by the character numeric value ('0' -> 0, '1' -> 1, ..., 'A' -> 10, ..., 'F' -> 15) raising the radix in every iteration
Something like:
value = 0
base = 1
for every character c in numeric_string (iterate in backwards)
var d = digitValueOf(c)
value = value + d * base
base = base * radix
end for

Categories