一次JavaScript 实现原码与补码相互转换
业务需求是这样的,通过小程序连接蓝牙,连接之后通过指令进行通讯。有个温度设置的功能,输入设定的温度,发送给接蓝牙。
蓝牙接收到并识别,返回一个当前温度值。关键就是这个温度值,底层规定的有符号位的十六进制数,两位十六进制,转为二进制也就是有8位二进制,也就是-127~127;
负数的补码怎么表示?
为了方便底层的识别和运算,二进制使用补码,我们知道 正数的补码是它本身,而负数的补码则是反码的基础上加1,例如-8这个数,转为二进制10001000,反码11110111,补码则等于反码加1为11111000;最后由补码转为十六进制HEX。
也就是,非符号位部分,即原码的绝对值-1的反码会得到补码。这样做的好处是一次性将十进制值算好,再转二进制取反,毕近js的运算都是基于十进制的。
//拿四位二进制举例 1110 -6 //原码 1010 (1001 + 1)//补码 //另一角度来讲 用5的反码 符号位补1即 0101 -> 0010 -> 1010
js代码这么写
//十进制转二进制补码 tenToTwo(n){ // write code here //-123的二进制表示为-1111011,123的为1111011,因此首先要得到负数二进制的补码表示 //其后面部分的补码0000101 = 122的正码1111011按位取反, //这个正码加上前面的0即是再全部按位取反即得-123的补码表示 if(n < 0) { n = -n; n = n - 1; var str = (Array(8).join("0") + n.toString(2)).slice(-8); str = this.exchange(str); }else{ var str = (Array(8).join("0") + n.toString(2)).slice(-8); } return str; }, //如果是负数,0变1,1变0 原码转反码 exchange(str) { var arr = str.split(''); for (var i = 0; i < arr.length; i++) { if (arr[i] == 0) { arr[i] = 1; } else { arr[i] = 0; } } str = arr.join(""); return str; }
二进制转换完成之后,再转为设备可以识别的HEX
//二进制转16进制 bin_to_hex(str) { let hex_array = [{ key: 0, val: "0000" }, { key: 1, val: "0001" }, { key: 2, val: "0010" }, { key: 3, val: "0011" }, { key: 4, val: "0100" }, { key: 5, val: "0101" }, { key: 6, val: "0110" }, { key: 7, val: "0111" }, { key: 8, val: "1000" }, { key: 9, val: "1001" }, { key: 'a', val: "1010" }, { key: 'b', val: "1011" }, { key: 'c', val: "1100" }, { key: 'd', val: "1101" }, { key: 'e', val: "1110" }, { key: 'f', val: "1111" }] let value = '' let list = [] if(str.length% 4 !== 0){ let a = "0000" let b = a.substring(0, 4 - str.length % 4) str = b.concat(str) } while (str.length > 4) { list.push(str.substring(0, 4)) str = str.substring(4); } list.push(str) for (let i = 0; i < list.length; i++) { for (let j = 0; j < hex_array.length; j++) { if (list[i] == hex_array[j].val) { value = value.concat(hex_array[j].key) break } } } return value },