web-dev-qa-db-ja.com

負の2進数をintに変換するにはどうすればよいですか?

データソースからノードred modbusノードを介してデータを読み取りたい。範囲は-20000〜20000ですが、ノードは負の数を処理できないため、それらを2進数(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として変換するため、2進数1111 1111 1111 1111 1111 1100 0001 1000は、-1000ではなく、4.294.966.296‬と見なされます。しかし、次の残りを1ライムで満たす場合:1111 1111 1111 1111 1111 1111 1111 1111 1111 1100 0001 1000は18446744073709552000を出力します

ありがとう

6
c0nr3f

まず、関数ノードで新しいmsgオブジェクトを作成するのは本当に悪い習慣です。msg.payload値を更新して元のオブジェクトを渡すだけです。

次にこれを行う最も簡単な方法は、バッファーを操作することです

例えば.

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

return msg;

手動モードの結合ノードは、2つの小さいバッファーを結合して、長さが16ビットの1つにすることができます。

2
hardillb

ええと、JavaScriptはこれを行う強力な型がないため、現時点では不十分です。おそらく最善ではありませんが、これを行う方法の1つは、カスタム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}

これはより高度なものに発展する可能性があり、ブラウザでも使用できます。

1
Tim Nimets