What will you learn from this passage?


Functions of ArrayBuffer Use of left and right displacement operations use of bitwise and operations


This article will use JavaScript to develop a visual tool for automatic conversion between decimal and binary.



Of course, it’s not the wine that matters. Familiarity with binary bit operations during development will be the focus of this article.



1 Introduction to conversion tools

Let’s take a look at the visualization tool.




Enter a decimal positive integer (32-bit unsigned integer), and we display the binary of that number in a table.
The table consists of 32 cells, divided into groups of eight because 1 byte =8 bits.


For example, if you enter the number 7, the binary number would be 111, and the table would look like this:



The binary number on each cell can be toggled between 0 and 1, and the corresponding decimal number will be computed.


For example, if we change the selected cell from 0 to 1, the decimal number will also change to 263:



2 ArrayBuffer

Let’s use the number 263 as an example to show how to implement code that manipulates byte streams using bit operations.


First, when we initialize, we put the number 263 into an array, which is then converted to a stream of bytes into an ArrayBuffer.

The rectangular ArrayBuffer below represents a chunk of memory, but we cannot manipulate it directly.


In this case, we use the JS TypedArray to access the memory. MDN calls TypedArray Multiple views on the same data.


We can use Uint32Array, Uint8Array and other “views” to read and write to ArrayBuffer memory.


This way, both our decimal and binary displays can read data from the same block of memory, instead of wasting extra array space holding a bunch of zeros and ones.


In addition, when changing the values of the “binary display area” cells, we can write directly to the data in the ArrayBuffer memory, saving a lot of trouble.


Looking at the code below, we use the Uint32Array to represent the “decimal display area”.

let target = new Uint32Array([263])Copy the code
Turning the array [263] into a byte stream and reading it as an array of 32-bit unsigned bytes, the array assigned to target is [263]. Target [0] is 263 in the decimal area.


We use the Uint8Array to represent the “binary display area”.


let bytes = new Uint8Array(target.buffer)Copy the code

Target. buffer reads the byte stream stored in memory as an array of 8-bit unsigned bytes. The resulting bytes array is [7,1,0,0], and the corresponding binary array is [0000111,00000001, 00000000, 00000000].

Next we display the bytes array in the Binary display area.

Since there are 32 cells, we iterate from cell 0 to cell 31, each of which uses the getBit method to get the corresponding binary value from the Bytes array.

function writeBits() {    
    for (var i = 0; i < 32; I ++) {cell [I].textContent = getBit(I); }}Copy the code


Here is the code for getBit.
function getBit(bit) {    
    return bytes[bit >> 3] & (0x1 << (bit & 0x7))?1 : 0; 
}Copy the code


Let’s explain it piece by piece.



“Bit > > 3” group

“>>” is the right shift operator. If n is an integer, then n>>3 has the same effect as n divided by 8, which can be used for grouping.


“Yu bit & 7”

If n is an integer, n&7 has the same effect as the remainder of n divided by 8, which can be used to determine the position of n in the group to which it belongs.


The ampersand and << operations

We know the rules for bitwise and are as follows:

1 and 1 = 1

0 and 1 = 0

1 & 0 = 0

0, 0 = 0


That is, if we want to know whether n in the binary number “0100 0n01” is 0 or 1, we can do this:

0x01000n01 & 0x00000100Copy the code
If this is 0, then n is 0; If the answer is greater than 0, then the value of n is 1.




Under bitwise and operations, 0x00000100 is a “valuer.” We can get a “valuer” by using the left shift operator.


0x1<< n positionCopy the code
Move the 1 in 0x0000 0001 to position N, which is 0x0000 0100.




example

Now that we’re done with the key bitwise techniques, let’s use an example to get a feel for it.


For example, if we want to get the value of the second cell (from cell 0) in the bytes array [0000111,00000001, 00000000, 00000000], we would do something like this:


The first stepWith 2>>3=0, we calculate that the second cell belongs to group 0, which is the element with subscript 0 in the Bytes array.



The second stepWith 2&7=0, it can be calculated that the second cell belongs to the second cell in the first group (from the 0th cell).


The third step, make “valuer”, 0x1<<2, get 00000100.


Finally, the bytes[0]& evaluator determines whether the result is greater than or equal to 0, and the value of the second cell is obtained.

let res = 0x00000111 & 0x00000100 ? 1 : 0Copy the code


Res has a value of 1, which means the second cell has a value of 1. Isn’t it fun?



To be continued……



Review past

Binary, octal, decimal, hexadecimal data conversion


Binary to decimal mental arithmetic