javascript中负数算术右移、逻辑右移的奥秘探索_javascript技巧

javascript中负数的算术右移和逻辑右移都十分的让人迷惑,特别是逻辑右移>>>,你会发现即使一个很小的负数,右移之后,也会得到一个无比巨大的数,这是为什么呢?

原来在逻辑右移中符号位会随着整体一起往右移动,这样就是相当于无符号数的移动了,最后得到的就是一个正数,因为符号位不存在了。首先逻辑右移产生的一定是32位的数,然后负数的符号位为1,这意味着从第32位到符号位的位置全部由1填充,这样的数能不大吗例如-1,逻辑右移0位表现形式就是1111 1111 1111 1111 1111 1111 1111 1111 ,这样的数是当作正数来对待的!所以将-1逻辑右移N位,最后的结果都是全为1!

左移运算保留数字的符号位。例如,如果把 -2 左移 5 位,得到的是 -64,而不是 64。“符号仍然存储在第 32 位中吗?”是的,不过这在 ECMAScript 后台进行,开发者不能直接访问第 32 个数位。即使输出二进制字符串形式的负数,显示的也是负号形式(例如,-2 将显示 -10。)

有符号右移运算

有符号右移运算符由两个大于号表示(<$lt;)。它把 32 位数字中的所有数位整体右移,同时保留该数的符号(正号或负号)。有符号右移运算符恰好与左移运算相反。例如,把 64 右移 5 位,将变为 2:

var iOld = 64; //等于二进制 1000000
var iNew = iOld >> 5; //等于二进制 10 十进制 2同样,移动数位后会造成空位。这次,空位位于数字的左侧,但位于符号位之后。ECMAScript 用符号位的值填充这些空位,创建完整的数字,如下图所示:

无符号右移运算

无符号右移运算符由三个大于号(>>>)表示,它将无符号 32 位数的所有数位整体右移。对于正数,无符号右移运算的结果与有符号右移运算一样。

用有符号右移运算中的例子,把 64 右移 5 位,将变为 2:

无符号右移运算用 0 填充所有空位。对于正数,这与有符号右移运算的操作一样,而负数则被作为正数来处理。

由于无符号右移运算的结果是一个 32 位的正数,所以负数的无符号右移运算得到的总是一个非常大的数字。例如,如果把 -64 右移 5 位,将得到 134217726。如果得到这种结果的呢?

要实现这一点,需要把这个数字转换成无符号的等价形式(尽管该数字本身还是有符号的),可以通过以下代码获得这种形式:

var iUnsigned64 = -64 >>> 0;

然后,用 Number 类型的 toString() 获取它的真正的位表示,采用的基为 2:代码如下:

alert(iUnsigned64.toString(2));

这将生成 11111111111111111111111111000000,即有符号整数 -64 的二进制补码表示,不过它等于无符号整数 4294967232。

出于这种原因,使用无符号右移运算符要小心。

现在来说一下负数的算术右移>>:

我们发现-9>>2=-3,为什么是-3呢?

首先符号位是不变的,不参加右移,然后在9右移的过程中,最低位为1的话,那么右移之后最低位仍然为1!这是很奇怪的。

时间: 2024-08-02 12:45:08

javascript中负数算术右移、逻辑右移的奥秘探索_javascript技巧的相关文章

JavaScript知识点总结(四)之逻辑OR运算符详解_javascript技巧

在JavaScript中,逻辑OR运算符用||表示 var bTrue = true; var bFalse = false; var bResult = bTrue || bFalse; 下面的真值表描述了逻辑AND运算符的行为: 在JavaScript中,0,"",false,null,undefined,NaN均表示false, 可以用如下的代码证明: <script type="text/javascript"> var bFalse = fal

JavaScript中数组的22种方法必学(推荐)_javascript技巧

前面的话 数组总共有22种方法,本文将其分为对象继承方法.数组转换方法.栈和队列方法.数组排序方法.数组拼接方法.创建子数组方法.数组删改方法.数组位置方法.数组归并方法和数组迭代方法共10类来进行详细介绍 对象继承方法 数组是一种特殊的对象,继承了对象Object的toString().toLocaleString()和valueOf()方法 [toString()] toString()方法返回由数组中每个值的字符串形式拼接而成的一个以逗号分隔的字符串 [注意]该方法的返回值与不使用任何参数

javascript中2个感叹号的用法实例详解_javascript技巧

在javascript代码中经常会见到!!的情况,本文即以实例形式较为深入的分析javascript中2个感叹号的用法.分享给大家供大家参考之用.具体分析如下: javascript中的!!是逻辑"非非",即是在逻辑"非"的基础上再"非"一次.通过!或!!可以将很多类型转换成bool类型,再做其它判断. 一.应用场景:判断一个对象是否存在 假设有这样一个json对象: { color: "#E3E3E3", "fon

JavaScript中的new的使用方法与注意事项_javascript技巧

原文: JavaScript, We Hardly new Ya  --Douglas Crockford.    http://yuiblog.com/blog/2006/11/13/javascript-we-hardly-new-ya/ 引用 JavaScript是一门基于原型的语言,但它却拥有一个 new 操作符使得其看起来象一门经典的面对对象语言.那样也迷惑了程序员们,导致一些有问题的编程模式. 其实你永远不需要在JavaScript使用 new Object().用字面量的形式{}去

Javascript 中 null、NaN和undefined的区别总结_javascript技巧

1.类型分析: js中的数据类型有undefined,boolean,number,string,object等5种,前4种为原始类型,第5种为引用类型. 代码 复制代码 代码如下: var a1; var a2 = true; var a3 = 1; var a4 = "Hello"; var a5 = new Object(); var a6 = null; var a7 = NaN; var a8 = undefined; alert(typeof a); //显示"u

Javascript中的for in循环和hasOwnProperty结合使用_javascript技巧

与in操作符相比,for in 在循环对象的属性时也会遍历原型链,for in 不会读取不可枚举属性,如数组的length属性. 小结 当检测某个对象是否拥有某个属性时,hasOwnProperty 是唯一可以完成这一任务的方法,在 for in 循环时,建议增加 hasOwnProperty 进行判断,可以有效避免扩展本地原型而引起的错误. 与in操作符相比,for in 在循环对象的属性时也会遍历原型链,for in 不会读取不可枚举属性,如数组的length属性. 复制代码 代码如下: /

javascript中的绑定与解绑函数应用示例_javascript技巧

Mozilla中: addEventListener的使用方式: target.addEventListener(type, listener, useCapture); target: 文档节点.document.window 或 XMLHttpRequest. type: 字符串,事件名称,不含"on",比如"click"."mouseover"."keydown"等. listener :实现了 EventListene

JavaScript中使用ActiveXObject操作本地文件夹的方法_javascript技巧

在Windows平台上, js可以调用很多Windows提供的ActivexObject,本文就使用js来实现文档处理, 和使用js编写ActiveX做一个简单介绍. 复制代码 代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html> <head>  <t

JavaScript中如何通过arguments对象实现对象的重载_javascript技巧

复制代码 代码如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> <script type="text/javascript"> /* *1.js 中不存在函数的重载 2.js函数定义时候的形参个数,和执行时候时,传递的实参的个数可以不一样. 3.js执行时