现在开发遇到一个需求,需要保存100个状态,状态只有01两种状态,如果使用字符串保存100个01,那么就会很长, 然后就想到了转成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呢?14F(发现貌似没什么问题?!真的没问题吗??)

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位状态的问题相关推荐

  1. java项目 github_我们分析了30,000个GitHub项目-以下是Java,JS和Ruby排名前100的图书馆...

    java项目 github 开发人员每天面临的最大难题之一是要使用哪些软件库. 使用热门的新框架还是已经使用了十年的"无聊"的经过反复测试的框架? 使框架成功的主要因素之一是其用户 ...

  2. 我们分析了30,000个GitHub项目-以下是Java,JS和Ruby排名前100的图书馆

    开发人员每天面临的最大难题之一是要使用哪些软件库. 选择热门的新框架还是已经使用了10年的"无聊"的经过反复测试的框架? 使框架成功的主要因素之一是其用户和贡献者社区. 虽然很容易 ...

  3. php输出圆周率100位,JS计算圆周率到小数点后100位实现步骤详解

    这次给大家带来JS计算圆周率到小数点后100位实现步骤详解,JS计算圆周率到小数点后100位的注意事项有哪些,下面就是实战案例,一起来看一下. 浮点数的有效数位是16位,我自己做了一个大数类,能存储1 ...

  4. php输出圆周率100位,怎样使用JS实现计算圆周率到小数点后100位

    这次给大家带来怎样使用JS实现计算圆周率到小数点后100位,使用JS实现计算圆周率到小数点后100位的注意事项有哪些,下面就是实战案例,一起来看一下. 浮点数的有效数位是16位,我自己做了一个大数类, ...

  5. js求渐升数的第100位

    我弟考了道数学竞赛题,问我能不能用代码算结果.. 题目是这样的 用 1.2.3.4.5 组合数字,然后排列大小,从小到大,求排在第100位的数值大小 function foo(chars) {var ...

  6. 魔方APP项目-07-客户端提交登录信息、在APICloud中集成防水墙验证码,前端获取显示并校验验证码、服务端校验验证码、保存用户登录状态,APICloud提供的数据存储、客户端保存用户登陆数据

    用户登录 一.客户端提交登录信息 html/login.html,代码: <!DOCTYPE html> <html> <head><title>登录& ...

  7. html 存储登录状态,Vue中保存用户登录状态实例代码

    首先我们假设,这里的登录组件(register.vue)是App.vue组件的子组件,是通过路由进入登录组件的. 登录组件中用户点击登录后,后台会传过来一个用户名,我的App.vue组件中需要拿到这个 ...

  8. python浮点数保留两位小数_(RPA)学习——Python 保存两位小数

    原标题:(RPA)学习--Python 保存两位小数 解释 python 由于 float 方法的浮点数处理精度不足导致,处理或者保存小数的时候可能出现不准准确的请款 python 的 round在保 ...

  9. 研究100位同行,我总结了从0到5年的新媒体晋级宝典

    作者:正经裸奔新青年 全文共 7906 字,阅读需要 17 分钟 ---- / BEGIN / ---- –  I  – 这是一篇从0到5年的新媒体晋级宝典,它的珍贵在于: 我们研究了100位新媒体的 ...

最新文章

  1. docker-runc not installed on system 问题
  2. BZOJ.4144.[AMPPZ2014]Petrol(Kruskal重构树)
  3. u32、u16、u8 数据类型
  4. 一个案例说出python的十余个语法知识点
  5. mysql clob转string_Java获取Oracle中CLOB字段转换成String
  6. codeforces F.F. Teodor is not a liar! 最长不降子序列
  7. html button跳转页面_Html
  8. Linux 变量和结构体
  9. python基础版课件_Python入门基础ppt课件.ppt
  10. 基于 WinPcap/Npcap 网络桥接与局域网网关
  11. 钢板弹簧matlab,Matlab/GUI在钢板弹簧悬架设计中的应用
  12. python百度贴吧发帖签到_百度贴吧签到脚本
  13. 外贸企业管理系统解决方案丨汇信
  14. 【量子机器学习】HHL算法: Quantum algorithm for solving linear systems of equations
  15. 电脑怎么设置计算机系统,细说电脑怎么设置wifi
  16. 不平凡的2021,末流普本生秋招上岸大厂的历程
  17. 学习打印机,了解打印命令
  18. python|面向对象(一)
  19. Android--Button、TabLayout英文小写自动变为大写的问题
  20. 基于FPGA实现的DDS双通道信号发生器

热门文章

  1. 5分钟通俗易懂了解什么是云存储
  2. Revi插件技巧:管道【风口下延】自定义长度?
  3. 2021-2027全球与中国连续式网带炉市场现状及未来发展趋势
  4. php微信开发查询分组,微信开发之用户组的介绍
  5. 双重 for循环概述
  6. CANoe.DiVa操作指南——配置特定测试序列
  7. Arduino ESP8266 使用LittleFS存储配置文件实践
  8. 聊聊gorm的OnConflict
  9. 开发流程中的问题总结和建议
  10. 下一代云计算模式:Docker正掀起个性化商业革命