# basic-theory

#### 按位取反操作符

[引用链接](https://blog.csdn.net/xiexievv/article/details/8124108)

**首先搞懂 “反码”，“取反”，“按位取反（\~）”，这3个概念是不一样的。**

* **取反：0 变 1,1 变 0**
* **反码：正数的反码是其本身，对于负数其符号位不变其它各位取反(0变1,1变0)**
* **按位取反(\~)： 这将是下面要讨论的。**

“\~”运算符在c、c++、java、c#中都有，之前一直没有遇到这个运算符。

要弄懂这个运算符的计算方法，首先必须明白二进制数在内存中的存放形式，**二进制数在内存中是以补码的形式存放的。**

另外正数和负数的补码不一样，**正数的补码、反码都是其本身**，既：

```
正数9：

原码为：0000 1001

补码为：0000 1001

反码为：0000 1001

再例如： -2 

求原码：1111 0010 （前面4个1表示符号位）

求反码：1111 1101 （符号位不变，其余各位求反）

求补码：1111 1110 （符号位不变，末位+1）

所以-2在内存中存放为: 1111 1110

```

***

弄懂了上述情况后，如何计算就好办了

假设要对正数9按位取反——> (\~9)，计算步骤如下，

```
原码为0000 1001，

反码为0000 1001，

补码为 0000 1001，

对其取反 1111 0110（符号位一起进行取反,这不是反码更加不是最终结果,只是补码的取反仅此而已）

我们还需要把他转换成原码，因为是负数所以进行负数补码到原码的逆运算

先减1得反码： 1111 0101

取反得原码：1111 1010，（**反码和原码是一个相对的概念，对反码取反就是原码。**取反过程符号位是不变的哦）

前面4个1是符号位，1是负数，既得十进制：-10
```

不知道说的明不明白，这里步骤就是：

1. 先对正数求补码
2. 然后对补码取反，包括符号位
3. 最后进行一个补码求原码的过程，一定要搞清概念啊。

***

下面我们再反推计算 （\~ -10）

```
-10的原码：1111 1010 

-10的反码：1111 0101 （符号位不变）

-10的补码：1111 0110 （符号位不变，末位+1）

补码取反：**0000 1001** （符号位一起取反）
```

这是一个正数，那么我们对其求原码就可得到最终结果？

因为正数的补码，反码，原码都是一样的 那我们的最终结果是 0000 1001 ，十进制是 9，这与我们前面推算出的结果吻合。

***

最后一个有趣的事实是：

1. 所有正整数的按位取反是其本身+1的负数
2. 所有负整数的按位取反是其本身+1的绝对值
3. 零的按位取反是 -1（0在数学界既不是正数也不是负数）

#### 内网网段

[参考链接](http://blog.kankanan.com/article/51857f51-ip-6bb5670954ea4e9b.html)

在IPv4地址协议中预留了3个IP地址段，作为私有地址，供组织机构内部使用。\
这三个地址段分别位于A、B、C三类地址内：

* A类地址：10.0.0.0--10.255.255.255
* B类地址：172.16.0.0--172.31.255.255&#x20;
* C类地址：192.168.0.0--192.168.255.255
