按照常识,位运算x|0,要么等于x,要么等于0

那么在JS的世界你的认知就要被颠覆了

下面请看

不带或0运算:
(window.crypto.getRandomValues(new Uint32Array(1))[0] * 0x10000 )
168546249998336
(window.crypto.getRandomValues(new Uint32Array(1))[0] * 0x10000 )
18707488702464
(window.crypto.getRandomValues(new Uint32Array(1))[0] * 0x10000 )
15579009253376
(window.crypto.getRandomValues(new Uint32Array(1))[0] * 0x10000 )
194841754140672
(window.crypto.getRandomValues(new Uint32Array(1))[0] * 0x10000 )
262611854950400
(window.crypto.getRandomValues(new Uint32Array(1))[0] * 0x10000 )
171394313420800 带或0运算:
(window.crypto.getRandomValues(new Uint32Array(1))[0] * 0x10000 )|0
-1037238272
(window.crypto.getRandomValues(new Uint32Array(1))[0] * 0x10000 )|0
511180800
(window.crypto.getRandomValues(new Uint32Array(1))[0] * 0x10000 )|0
1204224000
(window.crypto.getRandomValues(new Uint32Array(1))[0] * 0x10000 )|0
-2026438656

可以看到明显的带或0运算与不带或0运算的结果无论是位数还是符号位都有不同。

那这中间到底发生了什么?

这里找一个数字为例:117063531626496

要想验证这个问题,思路如下:

1,对比变更前后的数字的二进制格式

2,找到是否有数字表示的安全边界

首先按照思路1,我们看一下这个数字和这个数字或0后的二进制格式分别是什么:

117063531626496的二进制格式:

var num = 117063531626496; num.toString(2);
输出:'11010100111011111111010001110000000000000000000' 117063531626496 | 0
输出:-96993280 -96993280的二进制格式:
var num = -96993280; num.toString(2);
'-101110010000000000000000000'

对比对比:

11010100111011111111010001110000000000000000000
-101110010000000000000000000

除了后面的0位数相同,没有找到明显的线索

那么我们按照思路2,来看一下原因:

通过官网对于js的number的定义,是64位的统一类型

但是我们通过 Number.MAX_SAFE_INTEGER可以看到number的安全最大值是:9007199254740991

通过转为2进制,可以发现这个数字是个54位的1:
var num = 9007199254740991; num.toString(2)
'11111111111111111111111111111111111111111111111111111'

那这个值可以正常地或0吗?实际上还是不行

9007199254740991|0
-1
9007199254740990|0
-2

那这个边界到底是多少呢?对于其它语言Integer的默认最大值一般为2的32次方-1,也就是2147483647

这次再来试一下:

2147483647|0
2147483647
如果对这个值再+1,重试呢
2147483648|0
-2147483648

可以发现这个边界就是32位整数的最大值。

超过这个值的数字再与0进行位运算则可能得到一个错误的结果。

JS神奇的或0(|0)的更多相关文章

  1. 在JS中关于堆与栈的认识function abc(a){ a=100; } function abc2(arr){ arr[0]=0; }

    平常我们的印象中堆与栈就是两种数据结构,栈就是先进后出:堆就是先进先出.下面我就常见的例子做分析: main.cpp int a = 0; 全局初始化区 char *p1; 全局未初始化区 main( ...

  2. 在 Ubuntu 14.04/15.04 上配置 Node JS v4.0.0

    大家好,Node.JS 4.0 发布了,这个流行的服务器端 JS 平台合并了 Node.js 和 io.js 的代码,4.0 版就是这两个项目结合的产物——现在合并为一个代码库.这次最主要的变化是 N ...

  3. MongoDB error: couldn't connect to server 127.0.0.1:27017 src/mongo/shell/mongo.js(转)

    rror: couldn't connect to server 127.0.0.1:27017 src/mongo/shell/mongo.js 一般这种情况就是:自己指定的数据库,所以不能.自动加 ...

  4. Node.js 4.0.0:灵雀云和 OneAPM 的整合测试

    关于 Node.js 4.0.0 稳定版刚刚推出,备受期待,迫不及待地想用它写点东西:此外,要把 Demo 放到 Internet 上得有一个公网 IP ,看到灵雀云挺不错的而且提供域名解析,简直业界 ...

  5. couldn't connect to server 127.0.0.1:27017 at src/mongo/shell/mongo.js:145

    当直接执行./mongo 出现这样的提示:couldn't connect to server 127.0.0.1:27017 at src/mongo/shell/mongo.js:145 解决: ...

  6. [js高手之路]Vue2.0基于vue-cli+webpack Vuex用法详解

    在这之前,我已经分享过组件与组件的通信机制以及父子组件之间的通信机制,而我们的vuex就是为了解决组件通信问题的 vuex是什么东东呢? 组件通信的本质其实就是在组件之间传递数据或组件的状态(这里将数 ...

  7. 为什么js中要用void 0 代替undefined

    这个是Backbone.js中的一句源码 if (callback !== void 0 && 'context' in opts && opts.context == ...

  8. [转] node升级到8.0.0在vscode启动js执行文件报错

    由于升级node 到 8.0.0 版本 vscode 启动一直报错: `node --debug` and `node --debug-brk` are invalid. Please use `no ...

  9. Backbone.js 1.0.0源码架构分析(一)

    Backbone.js 是javascript 语言中 首个实现MVC设计模式的类库,API接口方法重度依赖于underscore.js,DOM选择器则依赖于jQuery.js或者zepto.js. ...

  10. JS异步执行之setTimeout 0的妙用

    最近在工作中遇到一些问题,大致是关于js执行问题的.由于没搞清执行顺序,导致出现了一些奇怪的bug. 所以这里整理一些有关异步执行的知识(冰山一角角)... 大家都知道js是单线程的,执行起来是顺序的 ...

随机推荐

  1. netcore5下ocelot网关简单使用

    1.新建aspnetcoremvc项目,带home控制器的就可以了,测试用能启动就行,代码无需做任何更改. 2.新建空的aspnetcoremvc项目,做如下更改: 1..  2.. 3..  4.. ...

  2. Mybatis学习四(分页助手pagehelper)

    Mybatis学习过程中有一个很重要的插件分页助手(pagehelper) 能够运用这个插件也非常简单 1.导入jar包 [jsqlparser-2.0.jar包] [点击下载https://gith ...

  3. C 语言编程 — 数据类型转换

    目录 文章目录 目录 前文列表 数据类型转换 隐式(自动)类型转换 常用的算术转换 显式(强制)类型转换 前文列表 <程序编译流程与 GCC 编译器> <C 语言编程 - 基本语法& ...

  4. RocketMq开启安全认证ACL-解决服务器系统安全漏洞

    1.为什么要开启ACL 通过之前的文章我们已经知道怎么安装RocketMq了.如果你还不会安装RocketMq可以查看我的这篇文章:快速入门一篇搞定RocketMq-实现微服务实战落地 进行软件安装, ...

  5. springboot 整合 recketMQ 详细步骤

    前提 RocketMQ的部署环境可用 1 依赖包 <dependency> <groupId>org.apache.rocketmq</groupId> <a ...

  6. mysql 5.6 inner join and 慢优化

    慢示例: SELECT o.id FROM o_schoolnotice o INNER JOIN o_schoolnotice_parent p ON o.id = p.noticeid AND p ...

  7. WPF如何自定义TabControl控件样式示例详解

    一.前言 程序中经常会用到TabControl控件,默认的控件样式很普通.而且样式或功能不一定符合我们的要求.比如:我们需要TabControl的标题能够居中.或平均分布:或者我们希望TabContr ...

  8. Flutter(八):Flutter路由管理(Router)

    目录 一.术语 路由(route): 导航(Navigator): 二.路由管理 1.Navigator示例代码 2.路由定义(命名路由) 在App中定义router: 3.Navigator方法介绍 ...

  9. ReplayKit2 有线投屏项目-反向Socket实现

    一.需求 我们在使用RTMP协议进行推流的时候,底层仍然采用的是TCP协议或者QUICK协议,有客户端主动发起请求.但是在有线投屏中,需要PC端向手机发起请求建立连接 二.实现 在客户端主动发起请求之 ...

  10. react 高阶函数

    HOC(Higher Order Components)就是一个函数,传给它一个组件,它返回一个新的组件. 高阶组件:就相当于手机壳,通过包装组件,增强组件功能. 实现步骤: 首先创建一个函数 指定函 ...