# IEEE-754 Floating Point Converter

Hello, I am using Node-RED to convert convert IEEE-754 Floating Point to decimal.
I am using this code to convert the values wich I get the right positive values but I obtain -Infinity for the negative values.

Code:
var sign = buf.readFloatBE() >> 31 === 0 ? 1 : -1 ;
var exponent = (buf.readFloatBE() & 0b01111111100000000000000000000000);
var significand = (buf.readFloatBE() & ~(-1 << 23));
msg.payload = sign * significand * Math.pow(2, exponent);
return msg;

That exponent calc doesn't look right, it will give you a huge number if the exponent is non-zero. I would have expected to see it shifted right.
Are you sure you get the right values for +ve numbers? Have you tried with a big +ve?
Where did you get the code?

Yes, I get the right +ve values. I didn't tried with a big +ve values ( The maximum value that I converted it is about 4000).

Where did you get that code? It is not right.

Or if you did not copy some code where is the algorithm you are trying to replicate?

I have tried several code after I changed them to get the value that I had . Can you help me please ?

I am not going to start working out the algorithm to do the conversion. If you google and find the algorithm to use (which presumably you have already in order to get nearly there) then I can help you code it in javascript.

``````
I found this code but I didn't get the right Values

function Bytes2Float32(bytes) {
var sign = (bytes & 0x80000000) ? -1 : 1;
var exponent = ((bytes >> 23) & 0xFF) - 127;
var significand = (bytes & ~(-1 << 23));

if (exponent == 128)
return sign * ((significand) ? Number.NaN : Number.POSITIVE_INFINITY);

if (exponent == -127) {
if (significand == 0) return sign * 0.0;
exponent = -126;
significand /= (1 << 22);
} else significand = (significand | (1 << 23)) / (1 << 23);

return sign * significand * Math.pow(2, exponent);
}
``````

That looks more likely to be correct. Have you got some sample values and what they should convert to?

That function works for me with examples from https://en.wikipedia.org/wiki/Single-precision_floating-point_format

``````[{"id":"f64c029.2c5838","type":"function","z":"2ae8b25a.bffaa6","name":"Bytes to float","func":"let bytes = Number(msg.payload);\nmsg.payload = Bytes2Float32(bytes)\nreturn msg;\n\nfunction Bytes2Float32(bytes) {\n    var sign = (bytes & 0x80000000) ? -1 : 1;\n    var exponent = ((bytes >> 23) & 0xFF) - 127;\n    var significand = (bytes & ~(-1 << 23));\n\n    if (exponent == 128) \n        return sign * ((significand) ? Number.NaN : Number.POSITIVE_INFINITY);\n\n    if (exponent == -127) {\n        if (significand === 0) return sign * 0.0;\n        exponent = -126;\n        significand /= (1 << 22);\n    } else significand = (significand | (1 << 23)) / (1 << 23);\n\n    return sign * significand * Math.pow(2, exponent);\n}","outputs":1,"noerr":0,"x":310,"y":612,"wires":[["6e888b6a.40c874"]]},{"id":"6e888b6a.40c874","type":"debug","z":"2ae8b25a.bffaa6","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":502,"y":612,"wires":[]},{"id":"2dc3b0d4.06517","type":"inject","z":"2ae8b25a.bffaa6","name":"1","topic":"","payload":"0x3f800000","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":89,"y":614,"wires":[["f64c029.2c5838"]]},{"id":"43e54f8e.0cf598","type":"inject","z":"2ae8b25a.bffaa6","name":"-2","topic":"","payload":"0xc0000000","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":84,"y":650,"wires":[["f64c029.2c5838"]]},{"id":"a8fc7865.b2a438","type":"inject","z":"2ae8b25a.bffaa6","name":"Pi","topic":"","payload":"0x40490fdb","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":82,"y":684,"wires":[["f64c029.2c5838"]]}]
``````

Thank you very much @Colin.
But I have just one question to ask. befor the function node I have a node which I obtain a buffer like this [67,76,0,0]. I have to change Number to buffer? like this :
return msg;
I changed it but I get always 0.

It is important to be careful in your choice of words. You say you have a buffer like [67,67,0,0] but then say you want to use buffer.from on it. If it is already a buffer then why do buffer.from? I suspect you mean that it is an array. If so then there is no need to convert it to a buffer. If the array is in msg.payload you can do

``````let bytes = (((((msg.payload[0] << 8) + msg.payload[1]) << 8) + msg.payload[2]) << 8) + msg.payload[3]
return msg;
``````
1 Like

The wikipedia post has an error. Not in the conversion but 3.1415927410 is not pi!

 No it isn't, that is as close as you can get in single precision float.

As this has come up before I have added a flow to flows library with the function to do this conversion.

2 Likes

Thank you very much @Colin.

Need help. How to modify this function to convert from double (binary64) to decimal.
I try this, but it's not work

``````
let intValue;
if (typeof msg.payload === "number") {
} else if (typeof msg.payload === "string") {
} else if (msg.payload.length == 4) {
// four byte array or buffer
} else {
}

return msg;

function Int2Float32(bytes) {
var sign = (bytes & 0x80000000) ? -1 : 1;
var exponent = ((bytes >> 52) & 0xFF) - 1023;
var significand = (bytes & ~(-1 << 52));

if (exponent == 1)
return sign * ((significand) ? Number.NaN : Number.POSITIVE_INFINITY);

if (exponent == -1023) {
if (significand === 0) return sign * 0.0;
exponent = -1022;
significand /= (1 << 51);
} else significand = (significand | (1 << 52)) / (1 << 52);

return sign * significand * Math.pow(2, exponent);
}
``````

Send the incoming message to a debug node and show us what you see, otherwise we don't know what you are starting with

``````msg.payload : Object
object
data: array[4]
0: 16550
1: 25493
2: 13159
3: 782
buffer: buffer[8][raw](http://127.0.0.1:1880/#)
0: 0x40
1: 0xa6
2: 0x63
3: 0x95
4: 0x33
5: 0x67
6: 0x3
7: 0xe
``````

It's mast be 2.87 kWh

Device which i read registers is pac3200, offset 801, 4 regesters, double format, Overflow 1.0e+12 .

After converting, I have
`[{"id":"f2043821.10b2a8","type":"function","z":"7b2adc08.02a074","name":"IEEE-754 to float","func":"/* Converts from an number, string, buffer or array representing an IEEE-754 value\n * to a javascript float.\n * The following may be given in msg.payload:\n * A string representing a number, which may be hex or binary\n * examples, \"1735\" \"0x02045789\" 0b01000000010010010000111111011011\n * An integer value\n * A four element array or buffer of 8 bit values, most significant byte first.\n*/ \n// first make a number from the given payload if necessary\nlet intValue;\nif (typeof msg.payload === \"number\") {\n intValue = msg.payload;\n} else if (typeof msg.payload === \"string\") {\n intValue = Number(msg.payload);\n} else if (msg.payload.length == 4) {\n // four byte array or buffer\n intValue = (((((msg.payload[0] << 16) + msg.payload[1]) << 16) + msg.payload[2]) << 16) + msg.payload[3];\n} else {\n node.warn(\"Unrecognised payload type or length\");\n}\n\nmsg.payload = Int2Float32(intValue);\nreturn msg;\n\nfunction Int2Float32(bytes) {\n var sign = (bytes & 0x80000000) ? -1 : 1;\n var exponent = ((bytes >> 52) & 0xFF) - 1023;\n var significand = (bytes & ~(-1 << 52));\n\n if (exponent == 1) \n return sign * ((significand) ? Number.NaN : Number.POSITIVE_INFINITY);\n\n if (exponent == -1023) {\n if (significand === 0) return sign * 0.0;\n exponent = -1022;\n significand /= (1 << 51);\n } else significand = (significand | (1 << 52)) / (1 << 52);\n\n return sign * significand * Math.pow(2, exponent);\n}","outputs":1,"noerr":0,"x":390,"y":80,"wires":[["583f7267.d123bc"]]},{"id":"583f7267.d123bc","type":"debug","z":"7b2adc08.02a074","name":"Value","active":true,"tosidebar":true,"console":true,"tostatus":false,"complete":"payload","x":600,"y":80,"wires":[]},{"id":"485407f3.a2f768","type":"inject","z":"7b2adc08.02a074","name":"fromeRegesters","topic":"","payload":"[16550,25493,13159,782]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":80,"wires":[["f2043821.10b2a8"]]}]`