博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript位运算符 2
阅读量:5290 次
发布时间:2019-06-14

本文共 4579 字,大约阅读时间需要 15 分钟。

按位运算符是把操作数看作一系列单独的位,而不是一个数字值。所以在这之前,不得不提到什么是“位”:
数值或字符在内存内都是被存储为0和 1的序列,每个0和1被称之为1个位,比如说10进制数据2在计算机内被存储为 0 0 0 0 0 0 1 0,当我们将内存内的位值改变之后,这个值代表的意义也就变了,比如把2前移动一位, 现在存储单元里面变成了0 0 0 0 0 1 0 0,这个值表示的是十进制的4,这也就是按位操作符的运算原理。
按位运算符有6个:
& 按位与
|按位或
^按位异或
~取反
>>右移
<<左移
>>>少了无符向右位移

1 & 运算符

&是二元运算符,它以特定的方式的方式组合操作数中对应的位 如果对应的位都为1,那么结果就是1, 如果任意一个位是0 则结果就是0
                    0001
                 &  0011
                ---------
                    0001
判断一个数是奇数还是偶数,我们会用求余数来判断:
function assert(n) {          if (n % 2 === 1) {    console.log("n是奇数");     } else {    console.log("n是偶数");    }}assert(3); // "n是奇数"
我们也可以用一个数和1进行按位&操作来判断,而且速度更快:
function assert(n) {if (n & 1) {    console.log("n是奇数");} else {    console.log("n是偶数");}}assert(3); // "n是奇数"
下面是位运算过程:
                 1 = 0001
                 3 = 0011
                 --------
                 & = 0001
 
奇数的二进制码的最后一位数肯定是1,而1只有最后一位为1,按位&操作之后,结果肯定只有最后一位数为1。而偶数的二进制表示的最后一位数是0,和1进行按位&操作,结果所有位数都为0。
只要任何一位是0 &运算的结果就是 0,所以可以用&把某个变量不必要的位设为0, 比如某个变量的二进制表示为 0 1 0 0 1 0 0 1, 我想保留低4位,消除高4位, 用 & 0x0F就可以了(注:0x为16进制表示法,0x0F 对应的二进制为 0 0 0 0 1 1 1 1)
 

2 | 运算符

|与||操作符的道理也是一样的,只要两个数中有一个数为1,结果就为1,其他则为0。
                    0001
                 |  0011
                ---------
                    0011
 
对浮点数向下求整,我们会用下面的方法:
var num = Math.floor(1.1); // 1
 
我们也可以用位运算来求整:
var num = 1.1 | 0; // 1
其实浮点数是不支持位运算的,所以会先把1.1转成整数1再进行位运算,就好像是对浮点数向下求整。所以1|0的结果就是1。

3 ^ 运算符

按位异或是两个数中只有一个1时返回1,其他情况返回0。
                    0001
                 ^  0011
                ---------
                    0010
 
数字与数字本身按位异或操作得到的是0,因为每两个对应的数字都相同,所以最后返回的都是0。
数字与0按位异或操作得到的是数字本身
 
异或满足交换律和结合律,类似小学的乘法运算
num1^num2 === num2^num1
num1^num2^num3 === num1^(num2^num3)
证明1:个人联想, 在二进制中符号位 用0表示正号 用1表示负号 ,十进制用 + - 表示。
用正负号+ -来模拟异或操作, 1:- ,0:+ 。
1^1结果为0, 0^0 结果为^0  , 1^0结果为1, 0^1 结果为1
负负得正          正正的正               负正得负          正负得负
完全十进制符号的运算 故:num1^num2^num3 === num1^(num2^num3)
 
证明2:数字逻辑法或者说逻辑代数法: 将两式分别转化为同一种形式,比如:卡诺图、真值表、标准与或式等.
(a♁b)♁c
= (a'b + ab')♁c
= (a'b + ab')'c + (a'b + ab')c'
= (a'b)' (ab')' c + a'bc' + ab'c'
= (a + b')(a' + b) c + a'bc' + ab'c'
= abc + a'b'c + a'bc' + ab'c'
a♁(b♁c)
= a'(b♁c) + a(b♁c)'
= a'(b'c + bc') + a(b'c + bc')'
= a'b'c + a'bc' + a(b'c)'(bc')'
= a'b'c + a'bc' + a(b + c')(b' + c)
= a'b'c + a'bc' + abc + ab'c'
显然,这二者是相等的,证毕.
 
我们经常会需要调换两个数字的值:
var num1 = 1, num2 = 2, temp;temp = num1;num1 = num2; // 2num2 = temp; // 1
 
如果装逼一点的话,可以这样:
var num1 = 1, num2 = 2;num1 = [num2, num2 = num1][0];console.log(num1); // 2console.log(num2); // 1
 
如果想再装的稳一点的话,可以这样:
var num1 = 1, num2 = 2;num1 ^= num2; // num1 = num1 ^ num2 = 1 ^ 2 = 3num2 ^= num1; // num2 = num2 ^ (num1 ^ num2) = num1 = 1num1 ^= num2; // num1 = num1 ^ num2 ^ num1 = num2 = 2console.log(num1); // 2console.log(num2); // 1

4 ~ 运算符

~是对位求反 1变0, 0变1
~4 === -5   ,  ~-5 === 4
对一个整数num按位求反, 等于它的相反数减一   ~num=-num-1;
~~num == -(num-1)-1 ===num; 对一个数两次求反结果为这个数本身
浮点数是不支持位运算的,所以会先直接去除小数部分,转成整数再进行位运算,就好像是对浮点数向下求整
~~可以进行类型转换,位运算会默认将非数字类型转换成数字类型再进行运算 (转换结果为整数 直接去除小数部分)
下面的比较运算结果都为 true
~~true == 1;~~false == 0;~~"" == 0;~~"all" == 0;~~"32all" == 0;~~"all43" == 0;~~[] == 0;~~undefined ==0;~~!undefined == 1;~~null == 0;~~!null == 1;~~(5.9) == 5;~~(5.2) == 5;~~(-5.9) == -5;
其实按位或运算符 | 0 也有这个特性

5 移位运算符 左移<< , 右移>>

移位运算符把位按指定的值向左或向右移动
<< 向左移动 而 >> 向右移动,超过的位将丢失,而空出的位则补0
如  0 1 0 0 0 0 0 0 0 0 0 0 0 1 1(十进制16387) 向左移动两位将变成
   0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 (十进制12)
向右移动两位则是
0 0 0 1 0 0 0 0 0 0 0 0 0 0 0(十进制4096)
 
2向前移动1位变成4 利用这个特性可以做乘法运算
2 << 1 = 4
3 << 1 = 6
4 << 1 = 8
同理 >> 则可以做除法运算
 
任何小数 把它 >> 0可以取整
如3.14159 >> 0 = 3;
其默认将非数字类型的转换为数字类型再做运算的性质与 ~~ , | 0 一样
 
位运算有隐式转换为数字的功能,现在看看js中的一些内置方法将其他类型转换为数字类型:
1 parseInt(7/2) // 3 丢弃小数部分,保留整数部分2 Math.ceil(7/2) // 4 向上取整,有小数就整数部分加13 Math.round(7/2) // 4 四舍五入.4 Math.floor(7/2) // 3 向下取整5 toFixed(n)     Number对象的方法--四舍五入保留n位小数。返回 NumberObject 的字符串表示。var a = 12.3456;  document.write(a.toFixed(2));    //12.35

 

parseInt()parseFloat() 函数会尝试逐个解析字符串中的字符,直到遇上一个无法被解析成数字的字符,然后返回该字符前所有数字字符组成的数字。如第一个字符不能被解析成为数字,返回NaN. 使用运算符 "+" 将字符串转换成数字,只要字符串中含有无法被解析成数字的字符,该字符串都将被转换成 NaN
var s = "10.1asd21";console.log(parseFloat(s)); //10.1console.log('10ab21'); // 10parseFloat('a12.21') ; // NaNparseInt('r43') ; // NaNconsole.log(+s); // NaN
NaN:当算术运算返回一个未定义的或无法表示的值时,NaN就产生了。但是,NaN并不一定用于表示某些值超出表示范围的情况。将某些不能强制转换为数值的非数值转换为数值的时候,也会得到NaN
例如,0 除以0会返回NaN —— 但是其他数除以0则返回Infinity而不是NaN
与 JavaScript 中其他的值不同,不能通过相等操作符(== 和 ===)来判断 ,因为 NaN == NaNNaN === NaN 都会返回 false。 因此,isNaN 就很有必要了。
isNaN(NaN);       // trueisNaN(undefined); // trueisNaN({});        // true isNaN(true);      // falseisNaN(null);      // falseisNaN(37);        // false // stringsisNaN("37");      // false: 可以被转换成数值37isNaN("37.37");   // false: 可以被转换成数值37.37isNaN("");        // false: 空字符串被转换成0isNaN(" ");       // false: 包含空格的字符串被转换成0 // datesisNaN(new Date());                // falseisNaN(new Date().toString());     // trueisNaN("blabla")   // true: "blabla"不能转换成数值

转载于:https://www.cnblogs.com/7qin/p/9710506.html

你可能感兴趣的文章
C# 获取系统时间及时间格式转换
查看>>
WCF、WebAPI、WCFREST、WebService之间的区别
查看>>
2018-2019-2-20175332-实验四《Android程序设计》实验报告
查看>>
全栈12期的崛起之捡点儿有用的说说
查看>>
基础类型
查看>>
属性动画
查看>>
标识符
查看>>
Swift 常量&变量
查看>>
Sqli labs系列-less-4 这关好坑!!!
查看>>
路由跟踪工具0trace
查看>>
给大家分享一张CSS选择器优选级图谱 !
查看>>
Win7中不能调试windows service
查看>>
T-SQL触发器,限制一次只能删除一条数据
查看>>
boost库使用:vs2013下boost::container::vector编译出错解决
查看>>
通过httplib2 探索的学习的最佳方式
查看>>
理解运算符重载 4
查看>>
快来熟练使用 Mac 编程
查看>>
第二周
查看>>
断言简介
查看>>
Node.js 入门:Express + Mongoose 基础使用
查看>>