摘要:之前在某个项目中,遇到了许多的二进制操作场景,因此总结下中的二进制操作方法。有符号右移将的二进制表示向右移位,丢弃被移出的位。用来表示原始的二进制数据缓存区,但是不可直接对进行操作,需要借助或者类型数组对象来对缓存区的内容进行读写。
之前在某个项目中,遇到了许多JS的二进制操作场景,因此总结下JS中的二进制操作方法。
所谓二进制操作,是指操作变量实际存储的值,比如获取字符A的Unicode值,或者将值100填入到8个字节中。
1. 位操作符JS中的位操作与很多语言类似,具体的位运算符如下表所示。
运算符 | 用法 | 描述 |
---|---|---|
按位与 | a & b | 对于每一个比特位,只有两个操作数相应的比特位都是1时,结果才为1,否则为0。 |
按位或 | a | b | 对于每一个比特位,当两个操作数相应的比特位至少有一个1时,结果为1,否则为0。 |
按位异或 | a ^ b | 对于每一个比特位,当两个操作数相应的比特位有且只有一个1时,结果为1,否则为0。 |
按位非 | ~ a | 反转操作数的比特位,即0变成1,1变成0。 |
左移 | a << b | 将 a 的二进制形式向左移 b (< 32) 比特位,右边用0填充。 |
有符号右移 | a >> b | 将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位。 |
无符号右移 | a >>> b | 将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位,并使用 0 在左侧填充。 |
在介绍具体的方法前,我们需要先了解下UCS-2和UTF-16编码。
UCS-2是一个16bit长度的编码集,它的表示范围是0到0xFFFF。UTF-16的表示范围是0到0x10FFFF,它由1个或者2个16bit的编码单元组成。其中UCS-2是UTF-16的子集,UTF-16编码在0到0x00FFFF的范围称为BMP(基本多文种平面),BMP与UCS-2的编码完全一致。
更详细的说明可以参考这里。
2.1 String.fromCharCodefromCharCode 方法返回指定的UCS-2编码对应的字符串。它是String上的静态方法,不可通过字符串对象直接访问。
因为入参是UCS-2编码值,所以不能多于16bit,即入参值要小于65536。如果入参需要大于65536,可以使用 String.fromCodePoint 。
String.fromCharCode(65) // A String.fromCharCode(65, 66, 68) // ABD2.2 String.prototype.charCodeAt
charCodeAt 返回字符串指定位置的字符的UTF-16编码。该方法可以直接从字符串对象进行调用。
如果该字符不能使用一个UTF-16编码单元(16bit)来表示时,该方法只会返回第一个编码单元。如果需要获取完整的编码,可以使用 String.prototype.codePointAt 。
"AB".charCodeAt(0) // 65 "AB".charCodeAt(1) // 663. ArrayBuffer
ArrayBuffer用来表示原始的二进制数据缓存区,但是不可直接对ArrayBuffer进行操作,需要借助DataView或者类型数组对象来对缓存区的内容进行读写。
3.1 DataViewDataView 可以理解为数据视窗,通过 DataView 对象可以对 ArrayBuffer 进行读写操作。
const buffer = new ArrayBuffer(4); // 申请2个字节长度的缓存区 const view1 = new DataView(buffer); // view1的范围是整个缓存区 const view2 = new DataView(buffer, 2, 1) // view2的范围是从第2个字节开始往后的一个字节 // 向一个16bit的内容中填入一个带符号的数 // 参数的含义依次为 输入内容的位置、输入的值、是否使用小端方式(默认大端) view1.setInt16(0, 0x0A0B, false); view1.getInt8(0); // 10,即0x0A view1.getInt8(1); // 11,即0x0B view2.setUint8(0, 255); view2.getInt8(0); // 按照有符号数来读取,结果为-1
更多的操作方法可以参考DataView。
3.2 类型数组对象类型数组对象有很多种,比如Uint8Array, Int32Array等。将ArrayBuffer转化为类型数组后,就可以像数组一样来操作缓存区。
const buffer = new ArrayBuffer(8); const arr1 = new Int16Array(buffer); const arr2 = new Uint8Array(buffer); arr1[0] = 256; arr2[6] = 255; console.log(arr1); // [256, 0, 0, 255] console.log(arr2); // [0, 1, 0, 0, 0, 0, 255, 0]
参考文献
按位操作符 - JavaScript | MDN
Unicode字符平面映射
JavaScript’s internal character encoding: UCS-2 or UTF-16?
String.fromCharCode() - JavaScript | MDN
String.prototype.charCodeAt() - JavaScript | MDN
ArrayBuffer - JavaScript | MDN
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/101714.html
摘要:在创建时大小已经被确定且是无法调整的,在内存分配这块是由层面提供而不是具体后面会讲解。在这里不知道你是否认为这是很简单的但是上面提到的一些关键词二进制流缓冲区,这些又都是什么呢下面尝试做一些简单的介绍。 showImg(https://segmentfault.com/img/remote/1460000019894717?w=1280&h=850); 多数人都拥有自己不了解的能力和机...
摘要:原码补码和反码原码一个数在计算机中是以二进制的形式存在的,其中第一位存放符号正数为负数为。中的位运算在中按位操作符会将其操作数转成补码形式的有符号位整数。原文链接由扯到中的位运算 这个话题的由来是2016年3月份的时候 NPM 社区发生了‘left-pad’事件,不久后社区就有人发布了用来补救的,也是现在大家能用到的 left-pad 库。 最开始这个库的代码是这样的。 module....
摘要:类型化数组也是中新引入的。用一句话解释类型化数组就是它是操作二进制数据的接口。类型化数组类型化数组的应用二进制数据的接口主要应用于文件,在中涉及文件处理的几乎都可以应用,主要是,,。 类型化数组(Typed Array)也是HTML5中新引入的API。用一句话解释类型化数组就是:它是JS操作二进制数据的接口。 众所周知,直接操作二进制数据可以使程序更为高效, 尽管JS对常规数组做了很多...
摘要:如何让根据拆箱转换,以及的隐式转换,可以如下写为什么计算机中所有的数据都是以二进制存储的,所以在计算机计算时要把数据先转换成二进制进行计算,然后把计算结果转换成十进制。会存在精度丢失问题和的二进制都是以无线循环的小数的二进制的二进制 本想着记笔记里,但是笔记里没有分类,还是以文章的形式,当个人总结吧,这一篇就当作JS基础篇的记录吧,有修改的和新增的持续更新~ 关于JS的一些小技巧 1:...
阅读 2574·2021-09-06 15:02
阅读 3204·2021-09-02 10:18
阅读 2825·2019-08-30 15:44
阅读 687·2019-08-30 15:43
阅读 1952·2019-08-30 14:08
阅读 2762·2019-08-30 13:16
阅读 1400·2019-08-26 13:52
阅读 933·2019-08-26 12:21