JavaScript位运算符 2

按位运算符是把操作数看作一系列单独的位,而不是一个数字值。所以在这之前,不得不提到什么是“位”:

数值或字符在内存内都是被存储为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; // 2
num2 = temp; // 1

如果装逼一点的话,可以这样:

var num1 = 1, num2 = 2;
num1 = [num2, num2 = num1][0];
console.log(num1); // 2
console.log(num2); // 1

如果想再装的稳一点的话,可以这样:

var num1 = 1, num2 = 2;
num1 ^= num2; // num1 = num1 ^ num2 = 1 ^ 2 = 3
num2 ^= num1; // num2 = num2 ^ (num1 ^ num2) = num1 = 1
num1 ^= num2; // num1 = num1 ^ num2 ^ num1 = num2 = 2
console.log(num1); // 2
console.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 向上取整,有小数就整数部分加1
3 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.1
console.log(‘10ab21‘); // 10
parseFloat(‘a12.21‘) ; // NaN
parseInt(‘r43‘) ; // NaN
console.log(+s); // NaN

NaN:当算术运算返回一个未定义的或无法表示的值时,NaN就产生了。但是,NaN并不一定用于表示某些值超出表示范围的情况。将某些不能强制转换为数值的非数值转换为数值的时候,也会得到NaN

例如,0 除以0会返回NaN —— 但是其他数除以0则返回Infinity而不是NaN

与 JavaScript 中其他的值不同,NaN不能通过相等操作符(== 和 ===)来判断 ,因为 NaN == NaNNaN === NaN 都会返回 false。 因此,isNaN 就很有必要了。

isNaN(NaN);       // true
isNaN(undefined); // true
isNaN({});        // true

isNaN(true);      // false
isNaN(null);      // false
isNaN(37);        // false

// strings
isNaN("37");      // false: 可以被转换成数值37
isNaN("37.37");   // false: 可以被转换成数值37.37
isNaN("");        // false: 空字符串被转换成0
isNaN(" ");       // false: 包含空格的字符串被转换成0

// dates
isNaN(new Date());                // false
isNaN(new Date().toString());     // true

isNaN("blabla")   // true: "blabla"不能转换成数值
 

原文地址:https://www.cnblogs.com/7qin/p/9710506.html

时间: 2024-10-16 14:44:48

JavaScript位运算符 2的相关文章

JavaScript位运算符

位运算符是在数字底层(即表示数字的 32 个数位)进行操作的. 重温整数 ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数).在 ECMAScript 中,所有整数字面量默认都是有符号整数,这意味着什么呢? 有符号整数使用 31 位表示整数的数值,用第 32 位表示整数的符号,0 表示正数,1 表示负数.数值范围从 -2147483648 到 2147483647. 可以以两种不同的方式存储二进制形式的有符号整数,一种用于存储正数,一种用于存储负数

详解位运算符的一些特点

我们都知道位运算符比正常的运算符速度要快,但是为什么会快呢?首先我们正常的运算符也是通过计算机通过位运算调用栈来实现的. 那么javascript位运算符有哪些呢? 1.          &      按位与             2.          |        按位或 3.          ^       按位异或 4.          ~      取反 5.  >>     按位左移 6.         >>     按位右移 说明: (1)位运算

关于位运算符的计算法方法

我们都知道位运算符比正常的运算符速度要快,但是为什么会快呢?首先我们正常的运算符也是通过计算机通过位运算调用栈来实现的.位运算符计算时,首先将运算量转化为2进制. 那么javascript位运算符有哪些呢? 1.          &      按位与             2.          |        按位或 3.          ^       按位异或 4.          ~      取反 5.  >>     按位左移 6.         >>

javascript(六)运算符

运算符概述 JavaScript中的运算符用于算术表达式. 比较表达式. 逻辑表达式. 赋值表达式等.需要注意的是, 大多数运算符都是由标点符号表示的, 比如 "+" 和"=" . 而另外一些运算符则是由关键字表示的, 比如delete和instanceof. 关键字运算符和标点符号所表示的运算符一样都是正规的运算符. 算术运算符 赋值 y = 5, 以下表格将向你说明算术运算符的使用: 算符 描述 例子 y 值 x 值 + 加法 x = y + 2 y = 5 x

javascript运算符——位运算符

× 目录 [1]二进制 [2]非 [3]与[4]或[5]异或[6]左移[7]右移[8]>>>[9]应用 前面的话 位运算符是非常底层的运算,由于其很不直观,所以并不常用.但是,其速度极快,且合理使用能达到很好的效果.本文将介绍javascript中常常被忽视的运算符——位运算符 二进制表示 ECMAScript中的所有数值都以IEEE-754 64位格式存储,但位操作符并不直接操作64位的值,而是以32位带符号的整数进行运算的,并且返回值也是一个32位带符号的整数 这种位数转换使得在对特

javascript学习笔记---ECMAScript运算符(位运算符)

位运算符是在数字底层(即表示数字的 32 个数位)进行操作的. 位运算 NOT 位运算 NOT 由否定号(~)表示,它是 ECMAScript 中为数不多的与二进制算术有关的运算符之一. 位运算 NOT 是三步的处理过程: 把运算数转换成 32 位数字 把二进制数转换成它的二进制反码 把二进制数转换成浮点数 例如: var iNum1 = 25; //25 等于 00000000000000000000000000011001 var iNum2 = ~iNum1; //转换为 11111111

JavaScript的位运算符、赋值运算符、其他运算符、三元运算符、运算符优先级

一. 位运算符 在一般的应用中,我们基本上用不到位运算符.虽然,它比较基于底层,性能和速度会非常好,而就是因为比较底层,使用的难度也很大,底层运算是转换成二进制进行运算的. 位运算符有七种,分别是:位非 NOT(~).位与 AND(&).位或 OR(|).位异或 XOR(^).左移(<<).有符号右移(>>).无符号右移(>>>). var box = ~25; //-26 var box = 25 & 3; //1 var box = 25 |

Javascript基础--运算符与表达式

一.运算符 1.运算符分类: 按功能:算术运算符:+.-.*./.%.++.-- 例:12+12-11+5*6+20/5+5%2+(5%-2)+(-5++2)+(a++)+(++a)+(--a)+(a--).注意取模运算符中返回结果值和第一个参数正负相关和第二个参数无关. 赋值运算符:= 字符串运算符:+.拼接运算符 逻辑运算符:&&(一非全非),||(一真全真全真) 关系运算符:>.>=.<.<=.==.!=.===.!== 逐位运算符: 其他运算符:条件运算符

JavaScript的运算符(操作符)和优先级

最近因为在读 Underscore.js 的源代码,加上重拾之前没有完成 ife 中的 JavaScript 部分的 task2,其中大量简略的语句写法,尤其喜欢 ?: 这个三目运算符和其他运算符连用.因为对于运算符优先级的概念一直很模糊,然后经常被绕进圈子里面.下面整理下常用的运算符和它们的优先级差异. 一.运算符 1. 一元运算符 (1)  递增递减运算符 主要就是 a++ 和 ++a 的区别,执行前置递增和递减运算时,变量的值都是在语句被求值之前改变的. var num1 = 10; va