系统中常常会存在大量的状态信息,特别是0-1值信息,某个条件是否达成,某个功能是否存在,某个操作是否成功等等,通常的做法是将各种状态条件编号,利用boolean数组来表示。
//0表示a功能,1表示b功能
//a功能生效
status[0]=true;
//b功能生效
status[1]=false;
由于大多数语言实际上是将boolean类型等同于整数类型,javascript也不例外,而其他语言和javascript不同的是:javascript目前必须运行在浏览器中,在特定条件下对于存储要求更加严格(例如cookie的4k限制),这时就要使用不常用的位操作来挖掘每一位存储的潜力。
将开关状态使用 0-1 二进制位表示,即将多个状态压缩到一个整数里面存储,一般一个整数有32位(javascript存在差异,尚不确定),则理论上节省了8倍的空间,代价则是增加了存取的运算。
1.存储数组
使用整数数组来拼成位集合
var store = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
2.设置状态
根据开关状态序号,定位到整数数组中的某个整数,设置特定的某个位为1
var index = Math.floor(num / 32),
index2 = num % 32,
mask = Math.pow(2, index2);
store[index] |= mask;
3.清除状态
根据开关状态序号,定位到整数数组中的某个整数,设置特定的某个位为0
var index = Math.floor(num / 32),
all_one = (Math.pow(2, 32) - 1),
index2 = num % 32,
mask = all_one ^ Math.pow(2, index2);
store[index] &= mask;
4.存储
最后存储到cookie时都要转换成字符串的格式,这里我们有三个选项
1.将 store 的每个 int,直接 toString() 转换成 10 进制字符串
2.将 store 的每个 int,toString(16) 转换成 16 进制字符串
但是这两种都没有充分利用一个字符字节的完全存储空间,即使16进制下4位就已经占据了一个字符字节的空间。
3.更优的解即是:对每8位,通过 String.fromCharCode 转为一个字节,最终存储到cookie。
5.解码
根据cookie中的字节,通过string.charCodeAt 即可获得该字节代表的数字,进一步通过位运算即可获取各个开关状态
var v = S.Cookie.get("test");
for (var i = 0; i < v.length; i++) {
//解码
var n = v[i].charCodeAt(0);
}
简单的可以通过对状态组数字的每一位进行检测是否0,1来得知状态设置为开的序号 :复杂度为 O(n) ,一般 n=32
//slower
function getOnesSlow(n,base,re) {
base=base||0;
var mask=1;
for(var i=0;i<32;i++){
if(n&mask) re.push(i);
mask=mask<<1;
}
}
其实存在更精巧的算法,主要是利用了负数的二进制其实就是由绝对值二进制取反后加一形成的,当一个数字和其负数进行按位与时,返回结果就是除了原数的最低位1保留外,其他都是0,例如
1010 对应负数为 111...0101,加1为 1111...0110
1111...0110 & 1010 = 10
结果 1 的位顺序数即为原数字 1010 的最低位 1的位顺序数
为了能根据 10..0 快速得知1所在的位顺序数,可以预先建立索引而不用循环计数:
var bton={};
var base=1;
for(var i=0;i<32;i++){
bton[base]=i;
base=base<<1;
}
那么现在就可以快速得到数字包含的1所在的位数数组:
//fastest one :
function getOnes(n,base,re){
base=base||0;
while(n){
var mask=n&-n;
re.push(bton[mask]+base);
n &= ~mask;
}
}
最快0次循环,即 n=0,最慢32次循环,即 n=1111...1(javascript位操作对象为32位整数),平均为 16 次循环,速度相比简单的逐位检测算法提高了一倍。
6.问题
在 cookie 中,每个字节并不能完整的表示8bit的信息量,因为ASCII中存在一些区间是特殊作用的字符(比如头32个)。作为HTTP头的一部分,理论上是不能使用这些字符的。
参考Uuencode算法(http://en.wikipedia.org/wiki/Uuencoding
),一般每个ANSI字符可以编码6bit的信息量。(感谢提醒)
demo
延伸阅读
javascript 在位操作领域也开始显露头角,国外有参照java流读取设计的 base64 解码器,甚至 deflate 解码器
,从而产生了直接使用div构建png
图片的演示,非常不错,还有:
Embedding Base64 Image Data into a Webpage
Use Javascript to Take a Screenshot of a Flash Movie
Base64 Encoded Images for Internet Explorer
Parsing Base64 Encoded Binary PNG Images in JavaScript
分享到:
相关推荐
ToggleButton状态的保存,即使程序退出了,下次启动的时候依旧是ToggButton上次选定的状态。本程序适合有一定的编程基础的爱好者学习,用到了SharedPreferences模块,实现数据的保存和读取
开关状态与位置确定后进行保存,然后对所确定的位置状态保存到表格中,通过聚类实现负荷的分类。
2.三个对软件的功能操作,开关和重启,其中重启操作为先关后开,所以需要软件处于开启状态才能使用; 3.重启中关闭软件到打开软件之间间隔20秒; 4.获取软件名,打开软件,鼠标在瞄准图按下,拖到指定软件再松手; 5...
实验一、利用8255实现LED的流水点亮实验 ...此程序中要有两个变量,一个保存当前开关的状态以检测开关状态是否发生了变化,一 个存LED右流水的状态,以便使LED连续右流动。为了使流水显示明显,每个位置应 加延时程序。
当手指松开后,滑块根据开关的状态,滑到最右边或者滑到最左边,同时保存开关的状态,将开关的状态回调给调用者。当然,上述功能系统给定的switch控件也可以实现。 实现步骤: 1. 写一个类继承view,重写两个...
本程序使用定时器,运用状态机的思想,实现了单按键的单击长按操作。 代码简洁规范,可读性强,移植性强。 实验器材: 自制开发板,STM32F03C8T6平台 实验目的: 学习定时器中断、按键使用。实现单击长按操作 ...
漂亮的开关按钮,可滑动和点击,滑动流畅并添加了动画,设置的状态一直保存着不会一重新运行就恢复默认了,目前项目中的设置就用的这个代码效果不错。
• 开关状态切换 • 状态保存 • PID控制器连接器 转换 Convert • 字节-整数 • 双字-时间 • 整数-逻辑信号 • 优先级/优先级范 围-4布尔 • 实数-双整数 • 实数-整数 • 开关-布尔 • 开关-多状态 计数器 ...
TableView演示与切换
1、开关键:开关状态循环;前次调光到关断状态时,按下开关,启动到最低亮度,前次为非关断状态,按下开关则在前次亮度与关断之间切换。 2、调亮(+)键:增加调光亮度,可以一直按下自动增加,直到最大亮度。 3、调...
ORG 000H LJMP MAIN ORG 0030H MAIN: MOV SP,#7 ...再次读P2口的开关状态 CJNE A,20H,LOOP ;P2口数据是否有变化,有则跳转到LOOP,并送P1口显示 SJMP SCAN ;无变化,则跳转到SCAN继续查询P2口, END
8路modbus RTU控制器说明书 产品介绍 本控制器带有8路采集和8路继电器输出,因灵活的使用方式被客户广泛的使用在各个行业及领域。同时带有二次开发协议,...10004 为X4地址,保存着X4当前状态(第四个开关量采集端口
LanHelper具有强大的扫描能力,能扫描到网络上计算机的各种非常有用的信息,包括了计算机的计算机名、工作组名、IP地址、MAC地址、共享文件夹、隐藏共享、共享打印机、共享文件夹是否可写、只读、密码保护等的属性、...
通过建立电力电子变换器的开关布尔矩阵,并消去其中的无效开关向量,得到电路的最简布尔矩阵和与其相对应的有效开关状态。在此基础上将最简布尔矩阵与变换器设计的正常工作状态开关矩阵比较,判断变换器是否存在非设计...
其中财产与安全点击进入仅预置一个按钮开关状态即可,点击可以开关按钮,不用实现具体功能,其他通知,通用等也类似,不用实现功能,通知进入显示是否开启通知开关,,通用显示是否保存缓存信息开关。
其中财产与安全点击进入仅预置一个按钮开关状态即可,点击可以开关按钮,不用实现具体功能,其他通知,通用等也类似,不用实现功能,通知进入显示是否开启通知开关,通用显示是否保存缓存信息开关。
整理完善usb通信(usb打印),可判断设备连接状态和开关机状态,设备连接过程中断开连接后,自动连接. UncaughtExceptionHandler接口实现本地捕获异常log信息保存到本地内存,方便查看调试!
12路modbus RTU控制器说明书 产品介绍 本控制器带有12路采集和12路继电器输出,因灵活的使用方式被客户广泛的使用在各个行业及领域。...10003 为X3地址,保存着X3当前状态(第三个开关量采集端口)
其中财产与安全点击进入仅预置一个按钮开关状态即可,点击可以开关按钮,不用实现具体功能,其他通知,通用等也类似,不用实现功能,通知进入显示是否开启通知开关,,通用显示是否保存缓存信息开关。