🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
> Javascript 按位取反运算符 (~) ,对一个表达式执行位非(求非)运算。如 ~1 = -2 ; ~2 = -3 ; ~99 = -100 `result = ~ 【数字】` 所有一元运算符(如 ~ 运算符)都按照下面的规则来计算表达式的值: 代码如下: ```js 1、 如果应用于未定义的表达式或 null 表达式,则会引发一个运行时错误。 2、 将对象转换为字符串。 3、 如果可能,将字符串转换为数字。 否则,将引发运行时错误。 4、 布尔值被视为数字(如果为 false,则为 0;如果为 true,则为 1)。 ``` 运算符将应用于结果数字。 `~` 运算符查看表达式的二进制表示形式的值,并执行位非运算。 表达式中的任何一位为 1,则结果中的该位变为 0。 表达式中的任何一位为 0,则结果中的该位变为 1。 下面的示例阐释了位非 (~) 运算符的用法,其中包含二进制表示十进制负数的,如果不熟悉这个请先看懂*《十进制负数转换为二进制、八进制、十六进制》*。 ```javascript 代码如下: var temp = ~5; /* 5 二进制 101,补满 32位 00000000000000000000000000000101 按位取反 11111111111111111111111111111010 由于32位开头第一个是1,所以这是一个负数,将二进制转换成负数,需要先反码 00000000000000000000000000000101 之后,再+1 00000000000000000000000000000110 转换成十进制为6,加上符号变成负数 -6 */ alert(temp); // 弹出【-6】 ``` ## 十进制负数转换为二进制、八进制、十六进制 程序猿们或许对二进制都不陌生,二进制是计算技术中广泛采用的一种数制。二进制数据是用0和1两个数码来表示的数。但是很多人都会将二进制转换成整数,但是如何用二进制表示负数呢?有的人会说,在二进制前面加个负数符合。而计算机只能认识0 和 1,又怎么去加个额外的负数符号呢?于是我们就需要用0和1来表示负数。如果想要弄懂这个,我们需要先了解什么是二进制原码。 ### 原码是什么 原码(true form)是一种计算机中对数字的二进制定点表示方法。原码表示法在数值前面增加了一位符号位(即最高位为符号位):正数该位为0,负数该位为1(0有两种表示:+0和-0),其余位表示数值的大小。 简单直观;例如,我们用8位二进制表示一个数,+11的原码为`00001011`,-11的原码就是10001011 原码不能直接参加运算,可能会出错。例如数学上,`1+(-1)=0`,而在二进制中`00000001 + 10000001 = 10000010`,换算成十进制为-2。显然出错了。 ![](https://box.kancloud.cn/6ecfb8d35f486172c672f12319a1c862_241x377.png) ### 二进制原码、补码和反码 十进制如何转换成二进制 我们如何把十进制的-3,转换成二进制表示呢?首先我们将 -3 的绝对值 +3 转换成二进制,假设是为int类型(32位)的,那么二进制表示为: `0000 0000 0000 0000 0000 0000 0000 0011` #### 负数转换成二进制分为3步: **1、** 首先将负数转换为对应的原码 -3 的原码为(也就是+3转换成二进制后的字符串): `0000 0000 0000 0000 0000 0000 0000 0011` **2、** 再将原码的每一位做取反操作得到反码。 取反操作:0变为1 、 1变为0;取反后的结果即为: `1111 1111 1111 1111 1111 1111 1111 1100` **3、** 将反码+1得到补码 `1111 1111 1111 1111 1111 1111 1111 1101` 现在用Windows自带的计算器来验证一下,Win+R 输入calc,将计算器改为程序员,选择双字(4字节,32位) ![](https://box.kancloud.cn/60aaf4f1c2ab09080d7f410c1d5364de_427x386.png) 打开Windows自带的计算器科学计算功能 **在计算器中选择十进制,之后输入 -3** : ![](https://box.kancloud.cn/d590d90a5d6d9fdf58fb8fcdc639ab36_427x386.png) 再点击二进制转换,将十进制下的-3转换成二进制: ![](https://box.kancloud.cn/9638247e9526b422a917627749bab909_427x386.png) ### 二进制转十进制负数问题 正常情况下,转换二进制到十进制都是没有任何问题的。而在类似 Javascript / PHP 等整数类型中,一般 int /integer 都有位数限制,一般都是32位长度。也就预示着,这些语言中,整数是有最大值的,而32位最大整数极限为:2147483647,也就是二进制: `01111111111111111111111111111111` 那么就很容易理解,32位二进制,第一位数为0的时候,就表示这个是一个正数,而如果是1,那么就表示这个是负数。 32位二进制 `11111111111111111111111111111001` 十进制值是什么? `11111111111111111111111111111001` 如上,二进制长度为32位,也就是这个整数是一个负数,先取反,得到反码: `00000000000000000000000000000110` 反码+1,得到: `00000000000000000000000000000111` 转换成十进制:7 由于是负数,所以加个负号,转换成 -7 **趣味:32位二进制 1111111111111111111111111111001 十进制值是什么?** 这个是个比较有趣的,千万不要误导为上面这是一个负数,其实这个是个整数,因为这里只有31位,需要在前面加0,补足32位,变成: `01111111111111111111111111111001` ### 十进制负数转八进制、十六进制 负数转换成八进制、十六进制,只需在补码(二进制)的基础上,3位合成一位计算,或者4位合成一位计算 -3的转换成二进制为: `1111 1111 1111 1111 1111 1111 1111 1101` 八进制则将-3的二进制从右至左每3位为一个单元,不够三位用0补 即: `011 111 111 111 111 111 111 111 111 111 101` 计算每一个单元,结果为:`37777777775` 十六进制则将-3的二进制从右至左每4位合并为一个单元,即: `1111 1111 1111 1111 1111 1111 1111 1101` 计算后为: `FFFFFFFD` ![](https://box.kancloud.cn/666265b432c4e678aca273144434598f_427x386.png)