JS 怎么使用十六进制保存100位状态的问题
现在开发遇到一个需求,需要保存100个状态,状态只有
0
和1
两种状态,如果使用字符串保存100个0
和1
,那么就会很长, 然后就想到了转成16进制
思考
但是在
JS
里最大的安全整数Number.MAX_SAFE_INTEGER
内最大也只能9007199254740991
这么大。
// 将最大安全整数转成16进制
(Number.MAX_SAFE_INTEGER).toString(16)
// 0x1FFFFFFFFFFFFF
结果发现只有13个
F
,一个F
可以表示4位(1111
),即13*4=52
正常只能保存52位
// 转成二进制
parseInt('0xFFFFFFFFFFFFF').toString(2)
// 1111111111111111111111111111111111111111111111111111// 计算下长度
parseInt('0xFFFFFFFFFFFFF').toString(2).length
// 52
如果要是再加一个
F
呢?14个F
(发现貌似没什么问题?!真的没问题吗??)
parseInt('0xFFFFFFFFFFFFFF') // 72057594037927940
现在做下转换成二进制和计算下长度
// 转成二进制
parseInt('0xFFFFFFFFFFFFFF').toString(2)
// '100000000000000000000000000000000000000000000000000000000'// 计算下长度
parseInt('0xFFFFFFFFFFFFFF').toString(2).length
// 57
可以看出已经出现问题了,转换成的二进制不对,长度也不对。
那么没办法了,在安全的范围内只有52位可以用(写代码也是要注意安全的,不然出错了,都不知为什么)
然后就想到了,使用两个不就有
52 * 2 = 104
个了,那么就满足需要了
实现
保存数据的格式,我使用的是
.
进行数据分割,即整数.小数
的数据格式。
那么就分开处理就可以了,我是优先使用整数部分,即[0-49].[50-99]
这种方式保存
后来发现一个问题不能直接使用位运算,因为位运算只支持32位以内的,这样就麻烦了
我是通过将十六进制转成二进制字符串,然后再转成十六进制,这样就不牵扯位运算了
关于位置的保存,由于数组是左边是0位,我们直接改变0位,那么就会造成初始的数据就会很大,所以我们要反过来,从数组的最高位开始改变。
// 第一位为1
1 '1000' => 8 '0001' => 1
// 第二位为1
3 '1100' => 8 '0011' => 3
// 第三位为1
7 '1110' => 8 '0111' => 7
我们使用后面的保存方式,这样数据转换之后就会从小到大了,也符合我们的习惯。
基础版转换
现在这个只能支持50位以内的
/*** 二进制增量运算* @param {String} data 十六进制* @param {Number} pos 位* @return {String} 计算后的十六进制值*/
function addBinaryVal(data, pos) {// 超过50位的不进行转换了if (pos >= 50){return data;}// 先将十六进制转成二进制,再在前面填充 0,然后进行分割成数组,再替换指定位置的状态,最后再转成十六进制let binaryData = parseInt(data, 16).toString(2).padStart(50, '0').split('');// 改变指定位置binaryData[49-pos] = '1';return '0x' + parseInt(binaryData.join(''), 2).toString(16)
}
加强版转换
可以支持100位或者150位甚至更高,我这里只是100位,可以按照需要自行扩展
封装一个方法进行状态变更
/*** 将十六进制字符串指定位置值置为1* 对两个十六进制字符串单独计算,然后再还原* @param {String} data 数据 两个十六进制字符串* @param {Number} pos 位置 范围限制[0,99]* @return {String} 改变后的字符串*/
function replaceBinaryValByPos(data, pos){if (pos > 100 || pos < 0){logger.error("getBinaryValByPos data: %j pos: %j is invalid");return data;}let tempData = data.split('.');if(pos < 50){tempData[0] = addBinaryVal(tempData[0], pos);}else{tempData[1] = addBinaryVal(tempData[1], pos-50);}return tempData.join('.');
}let val = '0xa.0xa' // '1010.1010'
val = replaceBinaryValByPos(val, 0) // '1011.1010'
console.log(val) // '0xb.0xa'val = replaceBinaryValByPos(val, 50) // '1010.1011'
console.log(val) // '0xa.0xb'
获取对应位的状态
封装一个方法固定方法获取数据的状态
/*** 十六进制字符串指定位置的状态* 最大安全整数转换成二进制 可以有53位 只取用50位,两个字符串就可以有100位* @param {String} data 数据 两个十六进制字符串* @param {Number}pos 位置 范围限制[0,99]* @return {boolean} 状态 [true,false]*/
function getBinaryValByPos(data, pos){if (pos > 100 || pos < 0){logger.error("getBinaryValByPos data: %j pos: %j is invalid");// 无效状态返回true 表示已经生效,防止因未生效的重复操作return true;}if(pos < 50){let val = parseInt(data.split('.')[0], 16).toString(2).padStart(50, '0');return val.charAt((50-1) - pos) === '1';}else{let val = parseInt(data.split('.')[1] || '0x0', 16).toString(2).padStart(50, '0');return val.charAt((100-1) - pos) === '1';}
}let val = '0xa.0xb' // ==> '1010.1011'
console.log(getBinaryValByPos(val,0)) // false
console.log(getBinaryValByPos(val,1)) // true
console.log(getBinaryValByPos(val,2)) // false
将十六进制的数据转换成二进制字符串
这里是将十六进制的数据转换成二进制字符串,不过数据状态是从左到右的保存
这样方便使用
/*** 获取二进制格式字符串* 反向组合 从左往右算* @param data 数据 两个十六进制字符串* @return {string} 二进制字符串*/
function getBinaryStr(data) {let tempData = data.split('.');let len = 50;let strArr = [];strArr[0] = parseInt(tempData[0], 16).toString(2).padStart(len, '0').split('').reverse().join('');strArr[1] = parseInt(tempData[1], 16).toString(2).padStart(len, '0').split('').reverse().join('');return strArr.join('');
}let val = '0xa.0xb' // 1010 1011 翻转=> 01011101
val = getBinaryStr(val);
console.log(val) // '0101000...0001101000...000' =>总长度100
结束
这里只是我想到的方法,如果有更好的方法,可以一起探讨交流
要是有更好的发现再更新,加油!
JS 怎么使用十六进制保存100位状态的问题相关推荐
- java项目 github_我们分析了30,000个GitHub项目-以下是Java,JS和Ruby排名前100的图书馆...
java项目 github 开发人员每天面临的最大难题之一是要使用哪些软件库. 使用热门的新框架还是已经使用了十年的"无聊"的经过反复测试的框架? 使框架成功的主要因素之一是其用户 ...
- 我们分析了30,000个GitHub项目-以下是Java,JS和Ruby排名前100的图书馆
开发人员每天面临的最大难题之一是要使用哪些软件库. 选择热门的新框架还是已经使用了10年的"无聊"的经过反复测试的框架? 使框架成功的主要因素之一是其用户和贡献者社区. 虽然很容易 ...
- php输出圆周率100位,JS计算圆周率到小数点后100位实现步骤详解
这次给大家带来JS计算圆周率到小数点后100位实现步骤详解,JS计算圆周率到小数点后100位的注意事项有哪些,下面就是实战案例,一起来看一下. 浮点数的有效数位是16位,我自己做了一个大数类,能存储1 ...
- php输出圆周率100位,怎样使用JS实现计算圆周率到小数点后100位
这次给大家带来怎样使用JS实现计算圆周率到小数点后100位,使用JS实现计算圆周率到小数点后100位的注意事项有哪些,下面就是实战案例,一起来看一下. 浮点数的有效数位是16位,我自己做了一个大数类, ...
- js求渐升数的第100位
我弟考了道数学竞赛题,问我能不能用代码算结果.. 题目是这样的 用 1.2.3.4.5 组合数字,然后排列大小,从小到大,求排在第100位的数值大小 function foo(chars) {var ...
- 魔方APP项目-07-客户端提交登录信息、在APICloud中集成防水墙验证码,前端获取显示并校验验证码、服务端校验验证码、保存用户登录状态,APICloud提供的数据存储、客户端保存用户登陆数据
用户登录 一.客户端提交登录信息 html/login.html,代码: <!DOCTYPE html> <html> <head><title>登录& ...
- html 存储登录状态,Vue中保存用户登录状态实例代码
首先我们假设,这里的登录组件(register.vue)是App.vue组件的子组件,是通过路由进入登录组件的. 登录组件中用户点击登录后,后台会传过来一个用户名,我的App.vue组件中需要拿到这个 ...
- python浮点数保留两位小数_(RPA)学习——Python 保存两位小数
原标题:(RPA)学习--Python 保存两位小数 解释 python 由于 float 方法的浮点数处理精度不足导致,处理或者保存小数的时候可能出现不准准确的请款 python 的 round在保 ...
- 研究100位同行,我总结了从0到5年的新媒体晋级宝典
作者:正经裸奔新青年 全文共 7906 字,阅读需要 17 分钟 ---- / BEGIN / ---- – I – 这是一篇从0到5年的新媒体晋级宝典,它的珍贵在于: 我们研究了100位新媒体的 ...
最新文章
- docker-runc not installed on system 问题
- BZOJ.4144.[AMPPZ2014]Petrol(Kruskal重构树)
- u32、u16、u8 数据类型
- 一个案例说出python的十余个语法知识点
- mysql clob转string_Java获取Oracle中CLOB字段转换成String
- codeforces F.F. Teodor is not a liar! 最长不降子序列
- html button跳转页面_Html
- Linux 变量和结构体
- python基础版课件_Python入门基础ppt课件.ppt
- 基于 WinPcap/Npcap 网络桥接与局域网网关
- 钢板弹簧matlab,Matlab/GUI在钢板弹簧悬架设计中的应用
- python百度贴吧发帖签到_百度贴吧签到脚本
- 外贸企业管理系统解决方案丨汇信
- 【量子机器学习】HHL算法: Quantum algorithm for solving linear systems of equations
- 电脑怎么设置计算机系统,细说电脑怎么设置wifi
- 不平凡的2021,末流普本生秋招上岸大厂的历程
- 学习打印机,了解打印命令
- python|面向对象(一)
- Android--Button、TabLayout英文小写自动变为大写的问题
- 基于FPGA实现的DDS双通道信号发生器