> 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)
- 步入JavaScript的世界
- 二进制运算
- JavaScript 的版本是怎么回事?
- JavaScript和DOM的产生与发展
- DOM事件处理
- js的并行加载与顺序执行
- 正则表达式
- 当遇上this时
- Javascript中apply、call、bind
- JavaScript的编译过程与运行机制
- 执行上下文(Execution Context)
- javascript 作用域
- 分组中的函数表达式
- JS之constructor属性
- Javascript 按位取反运算符 (~)
- EvenLoop 事件循环
- 异步编程
- JavaScript的九个思维导图
- JavaScript奇淫技巧
- JavaScript:shim和polyfill
- ===值得关注的库===
- ==文章==
- JavaScript框架
- Angular 1.x
- 启动引导过程
- $scope作用域
- $q与promise
- ngRoute 和 ui-router
- 双向数据绑定
- 规范和性能优化
- 自定义指令
- Angular 事件
- lodash
- Test