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提供的位運算符,我想這就是情懷吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM