I've tried to convert 23 to binary and came up with the number 100111 by using the following process:
1) 23 = 22 + 1 // find out the least significant bit 1
2) 22/2 = 10 + 1 // next bit is 1
3) 10/2 = 4 + 1 // next bit is 1
4) 4/2 = 2 + 0 // next bit is 0
So I'm left with the 2 in decimal, which is 10 in binary. Now I'm writing down the number:
10 plus the the bits from the operations 4, 3, 2, 1 gives me
100111, however, the answer is 10111. Where is my mistake?
Provided with this method, the binary representation of the decimal number 23 is as follows:
ex: Convert 23 to a binary representation
23 / 2 = 11 R 1
11 / 2 = 5 R 1
5 / 2 = 2 R 1
2 / 2 = 1 R 0
1 / 2 = 0 R 1
answer = 10111
As you currently have it,
1) 23 = 22 + 1 // find out the least significant bit 1
This step is unnecessary. You don't need to shave off the odd number first. Simply follow the procedure outlined in the link to generate the output. What this means is that the only operation you perform on your decimal number output is repeated divisions by 2, with the remainders spelling out your binary representation of your number.
If this isn't a programming question, it should be migrated to the correct forum.
If you do want a JavaScript solution as well, since you have marked this question with the JavaScript tag, then the easiest way is to simply do (N).toString(2), where (N) is your decimal number and .toString(2) converts your number to a binary representation of your number in string form. The 2 represents the radix/base.
In the end, what you want to get is
23 = 16 + 4 + 2 + 1
= 1*16 + 0*8 + 1*4 + 1*2 + 1*1
= 1*2^4 + 0*2^3 + 1*2^2 + 1*2^1 + 1*2^0
The calculations should look like this:
23 = 2*11 + 1 (1st least significant digit is 1)
11 = 2*5 + 1 (2nd least significant digit is 1)
5 = 2*2 + 1 (3rd least significant digit is 1)
2 = 2*1 + 0 (4th least significant digit is 0)
1 = 2*0 + 1 (5th least significant digit is 1)
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I saw if condition like this if(c & 10) and This condition similar to this if(c==10). This is a correct way to write code in javascript?
It's correct (as in, it's not a syntax error), but & and == are different operators.
& is the bitwise AND operator. == is the abstract (loose) equality operator.
The reason c & 10 and c == 10 happen to work in an if when c is 10 is due to the fact that c & 10 returns a truthy value (indeed, 10); c == 10 returns true (which is by definition truthy).
However, c & 10 would also work for a large number of other integers, unlike c == 10.
c & 10 will produce a number.
c == 10 will produce a binary value.
var c = 10;
console.log("c & 10 = ",c & 10); // 10
console.log("c & 7 = ",c & 7); // 2
console.log("3 & c = ",3 & c); // 2
console.log("10 & 10 = ", 10 & 10); // 10
console.log("c==10 = ", c==10); // true
The Bitwise AND operator uses the binary representation of two integers and compares the binary digits (0 or 1) bit by bit and will produce a new integer with the responding bits set to 1 if and only if those corresponding bits in the first two numbers are both 1, otherwise that bit will be 0.
Ex. 1
compare 10 and 20
10 is binary 00001010 = 8 + 2 = 2**3 + 2**1
20 is binary 00010100 = 16 + 4 = 2**4 + 2**2
Comparison
00001010
& 00010100
--------
00000000
because at no bit position there are two 1s
Ex. 2
compare 10 and 200
10 is binary 00001010 = 8 + 2 = 2**3 + 2**1
20 is binary 11001000 = 128 + 64 + 8 = 2**7 + 2**6 + 2**3
Comparison
00001010
& 11001000
--------
00001000
^Here are two 1s
because at bit position 3 there are two 1s. So 200 & 10 are 8
So I am new to Javascript, in my first Intro to Javascript class. I just found what the & operator does and came across this definition:
The & operator returns a one in each bit position for which the corresponding bits of both operands are ones.
I was also able to find descriptions of == and === on this website on a question that has been previously answered. On this link here: Wikipedia Bitwise_operation#AND
It explains that 1 & 1 is the same as 1 x 1, simple multiplication. So my question is then why is 10 & 5 == 0 and 10 & 6 == 2
Wouldn't it be 10 & 5 == 50 and 10 & 6 == 60?
What am I failing to understand?
It's only the binary bits in each position (the 1s and 0s) that are multiplied.
For example, with 10 & 5:
10 = 1010 in binary
5 = 0101 in binary
Now multiply each digit against the other digit in the same position:
(1 x 0) (0 x 1) (1 x 0) (0 x 1)
= 0000
= 0 in decimal
console.log(10 & 5)
With 10 & 6:
10 = 1010 in binary
6 = 0110 in binary
Now multiply each digit against the other digit in the same position:
(1 x 0) (0 x 1) (1 x 1) (0 x 0)
= 0010
= 2 in decimal
console.log(10 & 6)
It’s equivalent to multiplication per bit.
0 & 0 === 0
0 & 1 === 0
1 & 1 === 1
So your example of 10 & 5 is:
1010
& 0101
= 0000
If you switch from base 10 to base 2, which is required when comparing numbers bitwise, then it is clearer :
10 & 5 becomes 1010 & 0101 which equals 0000 in base 2, 0 in base 10
10 & 6 becomes 1010 & 0110 which equals 0010 in base 2, 2 in base 10
Hope this helps!
So 10 should be something like this 1010
and 5 should be something like this 0101
Now, if you find & or And for both of them, You should get something like 0000 which is zero
Similarly for 6, it should be 0110
which should give & or And for both of them as 0010 which happens to be 2
Note: for And we have the following rule
0 & 0 === 0
0 & 1 === 0
1 & 1 === 1
Try going through w3c article: https://www.w3schools.com/jsref/jsref_operators.asp
In JavaScript, I tried executing the below statements
var x = 1+"2"-3; //Anser is 9.
var y = 1-"2"+4 //Anser is 3.
For such operations, what is converted to what?
I guess 1+"2" = 12(number) and then 12-3?
- converts the both operands to numbers. But if either operand to + is a string, the other is converted to string and it's a concatenation. Like "Hi, " + "how are you?" = "Hi, how are you?" So your answers are correct.
var x = 1+"2"-3;
// concats the string as 12 and then subtracts...
12 - 3 = 9
var y = 1-"2"+4
// converts to numbers and subtracts, making -1 and then adds 4 giving out 3
-1 + 4 = 3
This was the process.
Scenario I
Step 1:
1 + "2" => "12" //concatenation happened
Step 2
"12" - 3 => 9 //String widens to number since we are using - symbol here.
Scenario II
Step 1:
1 - "2" => -1 //String widens to number since we are using - symbol here.
Step 2:
-1 + 4 => 3 //Normal addition happens
It is said that
All numbers in javascript are 64bit floating point numbers.
I am wondering whether numbers are always use 64bit in memory?
I have a data structure like this (in C-style code)
{
int x; // [0-9]
int y; // [0-9]
int d; // [0-3]
}
x and y will be absolutely within the range of [0-9] and the only possible value of d is 0, 1, 2, 3.
If I store them as 3 separated number, will the structure use 64bit * 3 = 192 bits = 24 Bytes?
If so, I would like to store it in one number, x * 100 + y * 10 + d, and this should only use 64 bits(8 Bytes). Is this better without considering CPU usage.
And I also considered about string solution.
x.toString() + y.toString() + d.toString();
because all x, y and d are less than 10, they should be only 1 character, 16 bits.
So the structure become 16 bits * 3 = 48 bits = 6 Bytes.
Is this the most storage optimized solution?
And how about the storage in mongoDB? If I store the data structure into mongoDB, is it the same situation?
I wrote a snippets to test the storage in mongo.
The final structure includes 3 instances of structures above. And the total amount is 66816.
I stored them into 3 separated databases:
layout-full (I lost an 's'): an array includes 3 {x: valueX, y: valueY, d: valueD}
layouts-int: xydxydxyd (in decimal) ex. 233250750 means {x:2,y:3,d:3},{x:2,y:5,d:0},{x:7,y:5,d:0}
layouts-str: convert int above to 2-char string. String.fromCharCode(i >> 16) + String.fromCharCode(i & 0xFFFF)
And the result is...
> show dbs
layout-full 0.03125GB
layouts-int 0.03125GB
layouts-str 0.03125GB
But the details are...
collection in layout-full
"size" : 8017920,
"avgObjSize" : 120,
"storageSize" : 11182080,
collection in layouts-int
"size" : 2138112,
"avgObjSize" : 32,
"storageSize" : 5591040,
collection in layouts-str
"size" : 2405396,
"avgObjSize" : 36.000299329501914,
"storageSize" : 5591040,
From these results, I found the int storage is the most space saving method.
I also did this:
> db.tiny.save({})
> db.tiny.stats().avgObjSize
24
> db.tiny.remove()
> db.tiny.save({l:null})
> db.tiny.stats().avgObjSize
28
> db.tiny.remove()
> db.tiny.save({l:[{x:null,y:null,d:null},{x:null,y:null,d:null},{x:null,y:null,d:null}]})
> db.tiny.stats().avgObjSize
84
So the _id will use 24 bytes and the key part, {l:, will use 4 = 28 - 24 bytes.
And you can find that a integer uses 32 - 28 = 4 bytes, so integers less than 2^31 seems to be stored as 32-bit integer in mongo db.
Also the in string solution, a 2-char string uses 36 - 28 = 8 bytes, just equals the value I guessed.
And for the full-structure solution, from the last tiny db test, you can see that a structure without data uses 84 bytes, so data use 120 - 84 = 36 bytes = 9 * 4 bytes. And I have just 9 integer numbers in my final data structure (triple x,y,d). This also prove that integers are stored as 32-bit integer.
And why the empty structure uses 84 bytes?
Through some more experiments, I found that 1 array or empty json object uses 4 bytes, and a key uses * 4.
So, the empty structure actually is
{ // 1 object +4 bytes = 4
'_id': ObjectId('0123456789abcdef012345678'), // 3-char key + 12-byte id = 24
'l': [ // 1-char key + 1 array = 8
{'x': null, 'y': null, 'd': null}, // 1 object+ 3 keys = 16
{'x': null, 'y': null, 'd': null}, // 1 object+ 3 keys = 16
{'x': null, 'y': null, 'd': null} // 1 object+ 3 keys = 16
]
}
The result is 4 + 24 + 8 + 16 * 3 = 84 bytes.
I hope my experiments are useful for others.
This will store the three numbers in a single-character string. The only way to do better is to use typed arrays, but I'm not sure that's an option here.
function showMeSomeMagic(x, y, d) {
// we assume that:
// - x, y are integers in the range [0 9]
// - d is an integer in the range [0 3]
// if not add the appropriate checks/casting/coercing
var n = (d << 8) + (y << 4) + x;
// return a String made of a single Unicode code point in
// the range [0xE000 0xE399], i.e. inside the Unicode BMP PUA
return String.fromCharCode( n + 0xE000 );
}
function showMeSomeInverseMagic(s) {
// we assume that:
// s is a String created by showMeSomeMagic
var n = s.charCodeAt(0) - 0xE000;
var x = n & 15;
var y = (n >> 4) & 15;
var d = (n >> 8) & 15;
return { x:x, y:y, d:d };
}
edit: updated according to the OP comment
console.log(0.5 | 0); // 0
console.log(-1 | 0); // -1
console.log(1 | 0); // 1
Why does 0.5 | 0 return zero, but any integer (including negative) returns the input integer? What does the single pipe ("|") do?
This is a bitwise or.
Since bitwise operations only make sense on integers, 0.5 is truncated.
x | 0 is x, if x is an integer.
Bit comparison is so simple it's almost incomprehensible ;) Check out this "nybble"
8 4 2 1
-------
0 1 1 0 = 6 (4 + 2)
1 0 1 0 = 10 (8 + 2)
=======
1 1 1 0 = 14 (8 + 4 + 2)
Bitwise ORing 6 and 10 will give you 14:
alert(6 | 10); // should show 14
Terribly confusing!
A single pipe is a bit-wise OR.
Performs the OR operation on each pair
of bits. a OR b yields 1 if either a
or b is 1.
JavaScript truncates any non-integer numbers in bitwise operations, so its computed as 0|0, which is 0.
This example will help you.
var testPipe = function(input) {
console.log('input => ' + input);
console.log('single pipe | => ' + (input | 'fallback'));
console.log('double pipe || => ' + (input || 'fallback'));
console.log('-------------------------');
};
testPipe();
testPipe('something');
testPipe(50);
testPipe(0);
testPipe(-1);
testPipe(true);
testPipe(false);
This is a Bitwsie OR (|).
The operands are converted to 32-bit integers and expressed by a series of bits (zeroes and ones). Numbers with more than 32 bits get their most significant bits discarded.
So, in our case decimal number is converted to interger 0.5 to 0.
= 0.5 | 0
= 0 | 0
= 0