I want to read Data via node red modbus node from a data source. The range is -20000 to 20000, but the node cannot handle negative numbers, so I had to convert them to binary numbers (DWORD), split them in the lower and higher word and convert these words back to integers.
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;
For visualisation I want to use the dashboard nodes, but therefor I need to join the 2 binary strings together and convert them to an int.
Problem:
node red converts them as a qword, so the binary number 1111 1111 1111 1111 1111 1100 0001 1000 is seen as 4.294.966.296, not as -1000. But if i fill the next rest with 1 lime so: 1111 1111 1111 1111 1111 1111 1111 1111 1111 1100 0001 1000 puts out 18446744073709552000
Thanks
parseInt
works on variable-length strings as input, which means that it cannot recognize the most significant bit as a sign bit. In other words: It parses binary strings like decimal strings, using a -
as sign; so you have to use a different method than parseInt
.
What hinders you from taking that 16-bit value and just pass it as unsigned? You'd just have to check whether the value coming in to your javascript is bigger than 32767, then do the two-complement conversion manually:
Your incoming numbers range would then be 0..20000 for positive "originals" and 45536..65535 for the original range -20000..-1 (if I'm thinking correct right now, I didn't verify that). This would mean that conversion is easy:
if( number > 32767 ) {
number = -65536 + number;
}
Or, for any binary number type (that is smaller than the number size of the language you're working in):
if( number > SIGNED_MAX_INT ) {
number = -(UNSIGNED_MAX_INT+1) + number;
}
(Those constants don't exist as written, they're more like pseudo code here)