温馨提示:本文翻译自stackoverflow.com,查看原文请点击:javascript - How can I convert negative binary number to int?
javascript modbus-tcp node-red node.js

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

发布于 2020-09-05 08:08:50

我想通过节点红色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。

问题:

红色节点将其转换为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

谢谢

查看更多

提问者
c0nr3f
被浏览
8
orithena 2020-05-13 23:25

parseInt在可变长度字符串上作为输入工作,这意味着它无法将最高有效位识别为符号位。换句话说:它使用-as符号解析二进制字符串,如十进制字符串因此您必须使用不同于的方法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;
}

(这些常量不像编写的那样存在,这里更像是伪代码)