zoukankan      html  css  js  c++  java
  • Javascript 16进制转有符号的10进制整数

      在赶项目中开发一个单片机对应的数据接口,需要将一个两字节的十六进制转化为-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提供的位运算符,我想这就是情怀吧。
  • 相关阅读:
    Mutex和Lock
    Thread和Promise以及packaged_task
    async和Future
    《并行程序设计导论》——读书笔记汇总
    UnrealEngine4蓝图可视化编程 完整例子 勘误
    BOOST下载
    sql 解析xml
    AutoResetEvent 笔记2
    ssh免密登录设置 (普通用户和root用户)
    npm设置淘宝镜像
  • 原文地址:https://www.cnblogs.com/BlackFungus/p/9473008.html
Copyright © 2011-2022 走看看