在赶项目中开发一个单片机对应的数据接口,需要将一个两字节的十六进制转化为-256~255的10进制数。百度了好久都没有对应且简明的教程,干脆就自己写一篇。
 
  我们都知道JavaScript整数类型有两种,有符号整数和无符号整数,而平时我们定义时所有的整数字面量默认都是32位有符号整数,因此两个字节的十六进制数使用parseInt()函数无法成功转出负数。
var hex="FF00"
console.log(parseInt(hex,16));//这里本意我们是想转出-256,但结果却是65280
       
  这里我们就需要温习一下数据在底层的转换,我们都知道数据在计算机里都是用二进制形式存储的。有符号的整数有两种方式存储,一种正数存储,一种负数存储。正数存储就是以真二进制的方式,最高位为0,后面每一位都表示2的幂次。而负数则麻烦的多,它采用二进制补码的形式存储。确定一个负数的二进制需要三步:
  1.确定该数字的绝对值的二进制,因为是负数所以最高位的“0”改为“1”,其为原码。
  2.将该绝对值,除了最高位的符号位外其他位的“0”替换成“1”,“1”替换成“0”,这就是二进制的反码。
  3.反码加上1,确定其补码。
 
        比如-256转换为二进制,具体步骤如下:
  1.先将256转换为二进制数为1 0000 0000,因位数不是8的倍数,需要在不足的高位补上0,得0000 0001 0000 0000。因为-256是负数,所以最高位改为1000 0001 0000 0000。
  2.再将除了符号位其他位的1和0对换,得1111 1110 1111 1111。
  3.把反码加上1得1111 1111 0000 0000。
  现在再把它转为16进制,就得到上面我们一开始的“FF00”了。
  ps:看到一个关于负数为什么是用补码存储的有趣说法,说计算机喜欢加法,正数的二进制和负数的二进制相加得0,这样极大减少了内存占用。
 
  现在我们知道了数据间底层的转换,就能来写16进制转换的函数了。
  先随便定义一个变量
let i="FF00";
  JavaScript只提供了2-32进制转换为10的函数,和10进制转换为2-32的方法,所以我们要把一个16进制转换为2进制需要使用其10进制作为中间量。
let two = parseInt(i, 16).toString(2);
  再求出变量应有的位数,在不足的位数上补“0”。
  let bitNum=i.length*4;
if (two.length < bitNum) {
while (two.length < bitNum) {
two = "0" + two;
}
}
  判断它的最高位是否是0,如果是,转换为10进制后原样输出。
  if (two.substring(0, 1) == "0") {
two = parseInt(two, 2);
}
  如果不是按照之前提供的步骤处理一下。
else {
let two_unsign = "";
two = parseInt(two, 2) - 1;//减一
two = two.toString(2);
two_unsign = two.substring(1, bitNum);//截取除了最高位以外的位
two_unsign = two_unsign.replace(/0/g, "z");//反码
two_unsign = two_unsign.replace(/1/g, "0");
two_unsign = two_unsign.replace(/z/g, "1");
two = parseInt(-two_unsign, 2);//补上负号
}
  我们封装一下。
module.exports=(i)=>{
let two = parseInt(i, 16).toString(2);
let bitNum=i.length*4;
if (two.length < bitNum) {
while (two.length < bitNum) {
two = "0" + two;
}
} if (two.substring(0, 1) == "0") {
two = parseInt(two, 2); return two;
} else {
let two_unsign = "";
two = parseInt(two, 2) - 1;
two = two.toString(2);
two_unsign = two.substring(1, bitNum);
two_unsign = two_unsign.replace(/0/g, "z");
two_unsign = two_unsign.replace(/1/g, "0");
two_unsign = two_unsign.replace(/z/g, "1");
two = parseInt(-two_unsign, 2); return two;
}
}
   最后我们来试试

大功告成,美滋滋!
 
 ps:可能有人会好奇为什么不用JavaScript提供的位运算符,我想这就是情怀吧。

Javascript 16进制转有符号的10进制整数的更多相关文章

  1. C#中2、8、16进制 有符号转换10进制正负数

    曾经让我苦想的其他进制转有符号整型问题,结果自己想到方法解决后才发现原来如此简单. 1.Int16(2个byte长度 ) : 方法 :Convert.ToInt16(进制编码,进制) a.16进制转1 ...

  2. 数组中hashCode就是内存地址,以及汉字幻化为16进制或10进制

    int[] arr4={1,2,3,4,5}; System.out.println("arr4: "+arr4); System.out.println("arr4.h ...

  3. 2019牛客暑期多校训练营(第五场)B:generator 1 (10进制快速幂)

    题意:给定x0,x1,a,b,满足xi=a*xi-1+b*xi-2: 求xn,n<10^(10^6): 思路:10进制快速幂裸题.降幂来写好像也是可以的,但是循环节不是phi(mod),所以数学 ...

  4. SQLSERVER 16进制与10进制转换

    最近工控项目中遇到的16进制与10进制转换,在.NET中比较容易实现,在SQLSERVER中发现没有直接的转换,尤其是出现超出范围的long负数,即无符号64位整数在sqlserver中的存储.网上找 ...

  5. python中的2、8、16、10进制之间的转换

    python除法的坑 众所周知,python除法有两个运算符,一个是/,还有一个是//,那么这两个有什么不同之处呢? 从图片可以得知,使用//返回一个float类型,而使用/返回一个int类型.我们总 ...

  6. python进制转化函数,10进制字符串互转,16进制字符串互转

    来了老弟,emmmmm,今天想到平时经常用到编码转化,把字符串转化为16进制绕过等等的,今天想着用python写个玩,查询了一些资料,看了些bolg 上面的两个函数是将二进制流转化为16进制,data ...

  7. java中 8进制 10进制 2进制 16进制 相互转换

    十进制转成十六进制: Integer.toHexString(int i) 十进制转成八进制 Integer.toOctalString(int i) 十进制转成二进制 Integer.toBinar ...

  8. JavaScript中二进制与10进制互相转换

    webpack打包生成的代码中涉及了一些二进制位与的操作, 所以今天来学习一下JavaScript中的二进制与十进制转换操作吧 十进制转二进制: var num = 100 num.toString( ...

  9. c#与js中10进制16进制的转化,记录防忘

    js: var param="11"; param=parseInt(param,16);  //17 param=parseInt(param,10);  //11 //后面的参 ...

随机推荐

  1. ThinkPHP6.0 容器和依赖注入

    ThinkPHP6.0 容器和依赖注入 分为如下两部分: 依赖注入 容器 依赖注入 依赖注入其实本质上是指对类的依赖通过构造器完成自动注入: 在控制器架构方法和操作和方法中一旦对参数进行对象类型约束则 ...

  2. HDU3829 Cat VS Dog

    题目链接:https://vjudge.net/problem/HDU-3829 题目大意: 有\(P\)个小孩,\(N\)只猫,\(M\)只狗.每个小孩都有自己喜欢的某一只宠物和讨厌的某一只宠物(其 ...

  3. Kattis - entertainmentbox

    题目链接:https://vjudge.net/problem/Kattis-entertainmentbox 题目大意: 一种叫做不知道什么的盒子可以同时录 k 个节目,现给出 n 个节目的开始和结 ...

  4. POJ3255

    题目链接:http://poj.org/problem?id=3255 解题思路: 昨晚两点多睡不着翻起来刷<挑战>的题,结果遇到这道求次短路的题,一脸懵逼.想了半小时没什么思路就看他的解 ...

  5. 27-1 分组-having

    group by select * from TblStudent --1.请从学生表中查询出每个班的班级id和班级人数 select tsclassId as 班级id, 班级人数=count(*) ...

  6. vue项目中关闭eslint的方法

    非常简单的操作方法!不用再去为了烦人的代码标准报错而苦恼了! 方法一:在项目根目录下增加 vue.config.js 文件 添加以下代码: module.exports = { lintOnSave: ...

  7. Redis数据迁移同步工具(redis-shake)

    前言 最近线上一台自建redis服务的服务器频繁报警,内存使用率有点高,这是一台配置比较简陋(2C8G)的机子了,近期也打算准备抛弃它了.抛弃之前需对原先的数据进行迁移,全量数据,增量数据都需要考虑, ...

  8. 自定义cursor鼠标 图片

    1.CSS3自定义鼠标样式 最近想要使用自定义鼠标样式,看了cursor的样式不好看,就想到cursor属性能不能自定义图片,翻看了下CSS3文档,发现是可以的 格式为:cursor:url('图片u ...

  9. 基于 kubeadm 搭建高可用的kubernetes 1.18.2 (k8s)集群二 搭建高可用集群

    1. 部署keepalived - apiserver高可用(任选两个master节点) 1.1 安装keepalived # 在两个主节点上安装keepalived(一主一备) $ yum inst ...

  10. ES6-Promise承诺

    1.扩展:ajax 1.1 代码如下 $.ajax({ url:'地址', type:'get/post', data:{}, dataType:'json/jsonp', success:funct ...