如何将负二进制数转换为int?

时间:2020-05-13 12:51:45

标签: javascript node.js node-red modbus-tcp

我想通过节点红色modbus节点从数据源读取数据。范围是-20000到20000,但是该节点无法处理负数,因此我不得不将它们转换为二进制数(DWORD),将它们分为上下两个字,然后将这些字转换回整数。

var low

function dec2bin(dec){
    return (dec >>> 0).toString(2);
}

var a = msg.payload

if (a >= 0){

    a = dec2bin(a);
    a = parseInt(a,2);

} else {

    a = dec2bin(a);
    a = a.substr(16);
    a = parseInt(a,2);

} 

low = { payload: a };

return low;

为实现可视化,我想使用仪表板节点,但是为此,我需要将2个二进制字符串连接在一起,并将它们转换为int。

问题:

节点red将它们转换为qword,因此二进制数1111 1111 1111 1111 1111 1100 0001 1000被视为4.294.966.296,而不是-1000。但是,如果我用1石灰填充下一个其余部分,则为:1111 1111 1111 1111 1111 1111 1111 1111 1111 1100 0001 1000 拿出18446744073709552000

谢谢

3 个答案:

答案 0 :(得分:3)

parseInt适用于可变长度字符串作为输入,这意味着它无法将最高有效位识别为符号位。换句话说:它使用-作为符号来解析二进制字符串,如十进制字符串;因此您必须使用与parseInt不同的方法。

什么阻碍您采用该16位值并将其作为无符号值传递?您只需要检查javascript中传入的值是否大于32767,然后手动执行双补码转换即可:

您输入的数字范围对于正数“原点”将是0..20000,对于原始范围-20000 ..- 1将是45536..65535(如果我现在想对的话,我没有验证)。这意味着转换很容易:

if( number > 32767 ) {
  number = -65536 + number;
}

或者,对于任何二进制数字类型(小于您使用的语言的数字大小):

if( number > SIGNED_MAX_INT ) {
  number = -(UNSIGNED_MAX_INT+1) + number;
}

(这些常量不如所写的那样存在,它们更像是伪代码)

答案 1 :(得分:2)

首先,在函数节点中创建新的msg对象是一种非常糟糕的做法,您应该只更新msg.payload的值并传递原始对象。

下一步,最简单的方法是使用Buffer

例如

var b = Buffer(4)
b.writeUInt32BE(msg.playload)
msg.payload = b.readInt32BE()

return msg;

处于手动模式的连接节点可以将2个较小的缓冲区合并为16位长度之一。

答案 2 :(得分:1)

嗯,JavaScript在这一点上是la脚的,因为它没有强大的类型来执行此操作。可能不是最好的方法,但是执行此操作的方法之一是创建自定义Int类。

class Int {
  constructor(length, binaryStr) {
    const cleanBinary = "0".repeat(length - binaryStr.length) + binaryStr
    if (cleanBinary.startsWith("1")) {
      const invertedBinary = cleanBinary.split("")
        .map(char => char === "1" ? "0": "1")
        .join("")
      this.decValue = -parseInt(invertedBinary, 2) - 1
    } else {
      this.decValue = parseInt(cleanBinary, 2)
    }
  }
}

类似的东西

new Int(8, "11111100")
> Int {decValue: -4}
strBin = "11111111111111111111110000011000";
new Int(strBin.length, strBin)
> Int {decValue: -1000}

这可能会发展成更高级的功能,也可以在浏览器中使用。

相关问题