美文网首页
不积跬步之二进制的那些事儿

不积跬步之二进制的那些事儿

作者: 雨飞飞雨 | 来源:发表于2021-12-30 18:45 被阅读0次
易经八卦.jpeg

我们都知道二进制是0和1组成的,在二进制被 戈特弗里德·莱布尼茨设计出来的时候,据说他学习参考了中国的<易经>,<易经>中的太极生两仪,两仪生四象,思象生八卦,八卦生十六卦,十六生32卦,32卦生64卦.像不像我们的二进制计数呢 1 2 4 8 16 32 64,好了,我们进入正题

  • 二进制在IEEE 754 64 中的存储格式是什么?
  • 位操作都有哪些?
  • 二进制的加减乘除
  • 二进制和十进制,八进制,十六进制的互相转换

二进制在IEEE 754 64 中的存储格式是什么?

ECMAScript 中所有的值都以 IEEE 754 64 位格式存储,但是位操作并不直接应用到64位,而是先把值转换为32位再进行位操作,之后再把结果转换为64位.对于开发者而言,就好像只有32位,因为64位整数存储格式是不可见的.既然知道了这个,那么就只需要考虑32位整数的就可以了

那么32位的整数又是怎么使用的呢?

有符号整数使用32位的前31位表示整数值,第32位表示数值的符号,如0表示正,1表示负,这个位称为符号位,它的值决定了数值其余部分的格式.

正值的存储

正值以真正的二进制格式存储,即31位中的每一位都代表2的幂.第一位(成为0位)表示2**0 ,第二位表示2**1,第三位就是2**2以此类推.如果一个位是空的,则以0填充,相当于忽略不计.比如数值18的二进制格式为0000 0000 0000 0000 0000 0000 0001 0010 或者精简为10010.后者是用5个有效位,来决定实际的值.

image.png

负值的存储

负值以一种成为二补数(或补码)的二进制编码存储.一个数值的二补数通过以下三个步骤来完成.

  1. 确定绝对值的二进制表示,如对于-18就是先确定18的二进制表示
  2. 找到数值的反码(补数),就是把所有的0变成,所有的1变成0
  3. 最后,给结果加1

就完成了.

我们实际操作一下:

第一步:-18的绝对值18的二进制是

0000 0000 0000 0000 0000 0000 0001 0010

第二步:取反,把每个0变成1,每个1变成0

1111 1111 1111 1111 1111 1111 1110 1101

第三步:最后给这个值加个1

1111 1111 1111 1111 1111 1111 1110 1110

这个就是我们的-18

位操作都有哪些?

1.按位非 ~

按位非操作符用波浪符~表示,它的作用是返回数值的一补数,例如:

let num1 =25 ;    // 0000 0000 0000 0000 0000 0000 0001 1001
let num2 = ~num1; // 1111 1111 1111 1111 1111 1111 1110 0110
console.log(num2); // -26

通过上面的结果可以看出 按位非的最终结果是对数值取反并减-
相当于

let num1 = 25;
let num2 = -num1 - 1;

虽然效果一样,但是未运算要快的多.

2.按位与 &

按位与操作符使用&表示.

第一数值的位 第二个数值的位 结果
1 1 1
1 0 0
0 1 0
0 0 0

就是 两个1才返回1 任何一位是0 就返回0 这个不就是乘法吗? 1 * 1 = 1 ,1 * 0 = 0 ,0 * 0 = 0

例如:25 & 3

25  =  0000 0000 0000 0000 0000 0000 0001 1001
3   =  0000 0000 0000 0000 0000 0000 0000 0011
----------------------------------------------
AND =  0000 0000 0000 0000 0000 0000 0000 0001

最后得到的值就是1

3.按位或 |

用管道符表示 只要1 就返回1 两个是0 就返回0

第一数值的位 第二个数值的位 结果
1 1 1
1 0 1
0 1 1
0 0 0

还是 25 | 3 ,我们看看值是多少呢?

25  =  0000 0000 0000 0000 0000 0000 0001 1001
3   =  0000 0000 0000 0000 0000 0000 0000 0011
----------------------------------------------
OR  =  0000 0000 0000 0000 0000 0000 0001 1011

等于 27

4.按位异或 ^

按位异或和按位或的区别是 ,它只在一位上是1的时候才返回1 ,两个是1的时候反而是0 ,当然两个1的时候也是0

---|---|--
1 | 1 | 1
1 | 0 | 1
0 | 1 | 1
0 | 0 | 0

25 ^ 3 = ?

25  =  0000 0000 0000 0000 0000 0000 0001 1001
3   =  0000 0000 0000 0000 0000 0000 0000 0011
----------------------------------------------
XOR =  0000 0000 0000 0000 0000 0000 0001 1010

等于 26.

5.左移 <<

会按照指定的位数将数值的所有位向左移动.比如,如果数值2 (等于二进制是10),就会得到64(二进制2000000)

let oldValue = 2; // 10
let newValue = oldValue << 5; //1000000

注意:在移位后,数值右端会空出5位,左移会以0填充这些空位,让结果是完整的32位数值.

注意:左移会保留它所操作数值的符号.所以-2 << 5 就是 -64

6.有符号右移 >>

会将数值的所有32位都向右移..同时会保留符号位(整数还是负数),有符号右移其实就是左移的逆运算.
例如:64 >> 5 === 2

0000 0000 0000 0000 0000 0000 0010 0000
---------------------------------------
0000 0000 0000 0000 0000 0000 0000 0010

如果移位的值超过它自己的值会怎么样,例如2 >> 5 ,它的值是0

移位出现的空值会补0

7.无符号右移 >>>

正数

无符号右移和有符号右移相同

负数

对于负数,有时候差异会非常大,与有符号右移不同,无符号右移会给空位补零,而不管符号位是什么.
对于正数,当然没有没问题.但是对于负数,就差距很大了.无符号右移操作符将负数的二进制表示当成整数的二进制
表示处理.因为负数时其绝对值的二补数,所以右移之后结果边得非常大.

let oldValue = -64;// 1111 1111 1111 1111 1111 1111 1111 1100 0000
let newValue = oldValue >>> 5;//等于十进制134217726
-------------------------------------------------------------------
>>> 0000 1111 1111 1111 1111 1111 1111 1111 1110

就是 134217726

二进制的加减乘除

二进制的加法 逢 2 进 1

还记得小学的时候我们学过的10进制加减乘除法是怎么算的吗?就是他们两个数竖着放在一起,各位个位对着个位,十位对着十位.百位对着百位.
然后最重要的是,10进制它是逢10进1.而二进制它的区别是逢2进1,例如:我们 3 +1

   0 0 1 1
 + 0 0 0 1
 ---------
   0 1 0 0    

1 + 1 等于 2 逢2 进1 然后 第二位 已经有了一个1 我们两个1 相加又进1 而自己则是 0 ,所以 是 0 1 0 0

再看一个

   0 1 0 1  
 + 0 0 1 1 
----------
   1 0 0 0        

转换成10进制就是 5+3 = 8;

二进制的减法 不够借 2

和二进制的加法的算法一样,我们把他们竖排,在10进制里面进行减法运算的时候有一个概念是 不够10的则向上一位借10做减法.
在二进制中也一样,如果不够则从上一位借2 ,也就是 不够借2

   0 1 0 1  
 + 0 0 1 1 
----------
   0 0 1 0

在运算的时候,第一位 1 - 1 = 0 ,第二位 0 -1 不够 ,怎么办,向上一位借1 啊,就是 2 - 1 ,剩下 1
所以最后就是 0 0 1 0
转换为10进制就 5 - 3 = 2
结果也是相同

二进制的乘法 1 * 1 = 1 , 0 * 1 = 0

还记得10进制乘法是怎么算的吗?

          7   8
          5   6
----------------
         4    8
    4    2
    4    0
3   5
---------------
4   3    6    8

10进制的关键是 每一位和上一个数的每一位想乘,所有的都遍历完成以后,在相加,逢10进1

   0 1 0 1  
 + 0 0 1 1 
----------
   0 1 0 1
 0 1 0 1
----------
 0 1 1 1 1

5 * 3 = 15

二进制的乘法是1 * 1 = 1 1 * 0 = 0,计算完毕以后进行相加. 逢 2 进 1

二进制的除法

二进制的除法和十进制的很像,都需要不够借1

          0 0 0 1 1
        -----------
0 1 0 1 | 0 1 1 1 1
          0 1 0 1    
        -----------
              1 0 1
              1 0 1
              -----
                  0

最后是 0 1 1

是不是和10进制的除法一样.

二进制和十进制,八进制,十六进制的互相转换

二进制转换成十进制

二进制转换成十进制非常简单,我们知道二进制实际上是表示的2的幂
我们以八位为例,这里直接用幂计算符号 **来表示

0 0 0 0 0 0 0 0
2**7 2**6 2**5 2**4 2**3 2**2 2**1 2**0
128 64 32 16 8 4 2 1

比如我们上面的数 0 1 0 1

对应到上面的值 22 + 20 也就是 4 + 1 = 5

按照位数对应到它的值,我们就能求出来.

十进制转换成二进制

同样可以参考上面的表格来计算.

比如15 ,15这个值比16小,所以它应该是 8+4+2+1 = 15

所以它的值就是

16 8 4 2 1
 0 1 1 1 1

如果是16就直接用16数值那里的1

16 8 4 2 1
1  0 0 0 0

是不是很简单

二进制转八进制

以三位作为划分,我们按 倒排4 2 1 来标识,三排作为一个数字,因为8进制是逢8进1,所以它的值就是按照 最高位来排下来.

1 0 0   1 1 0
-----   -----
4 2 1   4 2 1
--------------
4       6
-------------
46

八进制数就是 46
我们在看一个例子

0 1 0   0 1 1
-----   -----
4 2 1   4 2 1
---------------
  2       3

最后得到的值是23(8)八进制数

那么带小数的是怎么算的呢?

0 1 1 . 0 1 1
----    -----
4 2 1   4 2 1
--------------
  3       3

最后得到的值就是 3.3(8)八进制数

八进制 转 二进制

实际上和10进制转二进制很像
我们知道一个八进制数需要三个二进制数来表示

例如 八进制数 46(8)

  4    6
---    ---
4 2 1  4 2 1
-----  -----
1 0 0  1 1 0

最后转换出来就是 100 110,带小数点也一样计算.

二进制 转 十六进制

十六进制的前9位是正常的1~9,从10 开始
A --> 10

B --> 11

C --> 12

D --> 13

E --> 14

F --> 15

我们上面的八进制是需要三个二进制数来表示,16进制,就需要4个二进制数来表示.
例如:

1 1 1 0  1 1 0 0
-------  -------
8 4 2 1  8 4 2 1
----------------
14       12
----------------
E C

最后就是 0xEC

parseInt(0xEC).toString(2)
//'11101100'

可以看到是正确的

同样我们也可以推理出十六进制转二进制的做法

十六进制 转 二进制

十六进制参考八进制数据转换

E        C

14       12
-------  -------
8 4 2 1  8 4 2 1 
-------  -------
8+4+2    8+4
-------  -------
1 1 1 0   1  1  0 0 

最后转换成 二进制就是 1110 1100

Over...

相关文章

  • 不积跬步之二进制的那些事儿

    我们都知道二进制是0和1组成的,在二进制被 戈特弗里德·莱布尼茨设计出来的时候,据说他学习参考了中国的<易经>,<...

  • 不积跬步

    2018/10/25 星期四 晴 没想到二姐的高价小收音机比手机的辐射要强,放在床边睡觉,...

  • 不积跬步

    “不积跬步无以至千里”常用来激励。 可在自己身上发掘这句名言,却只有垃圾、肥肉和慢。 一个上午,断断续续收拾了两个...

  • 不积跬步

    生活中看起不起眼的事情,对一些人来说就是财富机遇 朋友在我们单位上班,也属于从别的单位挖过来的,老板慧眼识珠,两人...

  • 劝学

    不积跬步无以至千里 不积小流无以成江海

  • 积累

    不积跬步无以至千里 不积小流无以成江海

  • 阿翔优视觉系列-视觉记录-Day8-第n课作业

    不积跬步,无以至千里;不积小流,无以成江海

  • 积攒自己

    不积细流,无以成江海,不积跬步,无以至千里。 题记 ...

  • 日积月累

    不积跬步,不以至千里;不积小流,无以成江海。 ------...

  • 不积跬步,无以至千里,不积小流,无以成江海。 ...

网友评论

      本文标题:不积跬步之二进制的那些事儿

      本文链接:https://www.haomeiwen.com/subject/bdfwqrtx.html