Bitwise operator issue

I am having a meltdown on something simple.
I am trying to route the odd and even numbers through two paths of a function.

I seem to have my code not operating as expected.

[{"id":"f8ce0fa1.b745e8","type":"inject","z":"52d0e4d.d0a231c","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":210,"y":160,"wires":[["7bf9cc4c.9d28e4"]]},{"id":"9da4c0c1.0a30b8","type":"function","z":"52d0e4d.d0a231c","name":"","func":"if ((msg.payload & 1) == 1){\n    var msg1 = msg.payload;\n    return msg1;\n} else {\n    var msg2 = msg.payload;\n    return msg2;\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","x":720,"y":160,"wires":[["72855935.ef7c88"],["2c3c854e.7b7fd2"]]},{"id":"7bf9cc4c.9d28e4","type":"random","z":"52d0e4d.d0a231c","name":"","low":"0","high":"1000000","inte":"true","property":"payload","x":410,"y":160,"wires":[["9da4c0c1.0a30b8","72855935.ef7c88","2c3c854e.7b7fd2"]]},{"id":"72855935.ef7c88","type":"debug","z":"52d0e4d.d0a231c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":890,"y":100,"wires":[]},{"id":"2c3c854e.7b7fd2","type":"debug","z":"52d0e4d.d0a231c","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":890,"y":220,"wires":[]}]

Try this.

Demo

[{"id":"f8ce0fa1.b745e8","type":"inject","z":"83a23089.dc697","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":860,"y":580,"wires":[["e3d42c24.bd3aa"]]},{"id":"9da4c0c1.0a30b8","type":"function","z":"83a23089.dc697","name":"","func":"function getBit(number, bitPosition) {\n    return (number & (1 << bitPosition)) === 0 ? 0 : 1;\n}\n\nif ( getBit(msg.payload, 0) ){\n    return [msg, null];\n} else {\n    return [null, msg];\n}","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1220,"y":580,"wires":[["72855935.ef7c88"],["2c3c854e.7b7fd2"]]},{"id":"72855935.ef7c88","type":"debug","z":"83a23089.dc697","name":"bit 0 is on","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":1420,"y":540,"wires":[]},{"id":"2c3c854e.7b7fd2","type":"debug","z":"83a23089.dc697","name":"bit 0 is off","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":1420,"y":620,"wires":[]},{"id":"e3d42c24.bd3aa","type":"change","z":"83a23089.dc697","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"$ceil(($random() * 10))\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":1040,"y":580,"wires":[["9da4c0c1.0a30b8"]]}]

PS, no need for a contrib node for random numbers :slight_smile:

@Steve-Mcl - the random node is installed as standard by the Pi install script :wink:

Ha. I'd never noticed (or forgot).

Curious - why not on non standard installs? Or rather why PI only Dave?

Because it was/is useful for some beginner exercises and tutorials.

Thanks, but can it be simplified? I would like to know the least significant bit of any data type. Number, String, Array, Buffer....:slightly_smiling_face:

Not if you want it to be universal & to report if the LSB of a Number, String, Array or Buffer - that makes it somewhat more complicated and is definitely open to interpretation.

  • Regarding string - I assume you mean the number represented by the string (and not the LSB of the ascii char in position[0])

  • Regarding Buffer - I assume you mean the LSB of byte in position [0] and not byte reversed and not read as Int16 or float etc?

On such solution (function code part)...

var input = msg.payload;
var t = (typeof input) + "";
if(t == "object") {
    if (Buffer.isBuffer(input)) {
        if (!input.length) {
            node.warn("Buffer is empty");
            return null;
        }
        input = input[0];
        t = (typeof input) + ""; //update type
    } else if(Array.isArray(input)) {
        if (!input.length) {
            node.warn("Array is empty");
            return null;
        }
        input = input[0];
        t = (typeof input) + ""; //update type
    } 
}

switch (t) {
    case "number":
        msg.payload = getBit(input, 0);
        break;
    case "string":
        let n = parseInt(input);
        if (isNaN(n)) {
            node.warn("payload is not a number");
            return null;
        }
        msg.payload = getBit(n, 0);
        break;
    default:
        node.warn(`payload type ${t} is not supported`);
        return null;
}

return msg; 

function getBit(number, bitPosition) {
    return (number & (1 << bitPosition)) === 0 ? 0 : 1;
}

Here is my interpretation...

flow...

[{"id":"f8ce0fa1.b745e8","type":"inject","z":"83a23089.dc697","name":"buffer [3,4,5]","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[3,4,5]","payloadType":"bin","x":1070,"y":700,"wires":[["9da4c0c1.0a30b8"]]},{"id":"9da4c0c1.0a30b8","type":"function","z":"83a23089.dc697","name":"get LSB","func":"\nvar input = msg.payload;\nvar t = (typeof input) + \"\";\nif(t == \"object\") {\n    if (Buffer.isBuffer(input)) {\n        if (!input.length) {\n            node.warn(\"Buffer is empty\");\n            return null;\n        }\n        input = input[0];\n        t = (typeof input) + \"\"; //update type\n    } else if(Array.isArray(input)) {\n        if (!input.length) {\n            node.warn(\"Array is empty\");\n            return null;\n        }\n        input = input[0];\n        t = (typeof input) + \"\"; //update type\n    } \n}\n\nswitch (t) {\n    case \"number\":\n        msg.payload = getBit(input, 0);\n        break;\n    case \"string\":\n        let n = parseInt(input);\n        if (isNaN(n)) {\n            node.warn(\"payload is not a number\");\n            return null;\n        }\n        msg.payload = getBit(n, 0);\n        break;\n    default:\n        node.warn(`payload type ${t} is not supported`);\n        return null;\n}\n\nreturn msg; \n\nfunction getBit(number, bitPosition) {\n    return (number & (1 << bitPosition)) === 0 ? 0 : 1;\n}","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1220,"y":580,"wires":[["625e312c.fb9fd"]]},{"id":"72855935.ef7c88","type":"debug","z":"83a23089.dc697","name":"bit 0 is on","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":1540,"y":555,"wires":[]},{"id":"2c3c854e.7b7fd2","type":"debug","z":"83a23089.dc697","name":"bit 0 is off","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":1540,"y":605,"wires":[]},{"id":"625e312c.fb9fd","type":"switch","z":"83a23089.dc697","name":"On or Off","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"},{"t":"eq","v":"0","vt":"num"}],"checkall":"true","repair":false,"outputs":2,"x":1360,"y":580,"wires":[["72855935.ef7c88"],["2c3c854e.7b7fd2"]]},{"id":"849c8a4e.acb318","type":"inject","z":"83a23089.dc697","name":"string 256","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"256","payloadType":"str","x":1060,"y":580,"wires":[["9da4c0c1.0a30b8"]]},{"id":"80d1ce63.5cf82","type":"inject","z":"83a23089.dc697","name":"Number 7","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"7","payloadType":"num","x":1060,"y":620,"wires":[["9da4c0c1.0a30b8"]]},{"id":"ffe8ad2d.be95b","type":"inject","z":"83a23089.dc697","name":"Array [6,8,10]","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[6,8,10]","payloadType":"json","x":1070,"y":660,"wires":[["9da4c0c1.0a30b8"]]}]

Awesome, I think this was a good topic so folks can see the value of bit-wise operators. These are in general very fast opcodes. When I was in Ron Klienmans C class at De Anza. We were asked to determine if a number was odd or even. I knew to use a bit-wise operator to do this. But most folks didn't know about them and made very complex attempts.I am writing a new kind of sort. It is a zipper sort. It pushes the odds to one side and the evens another. There are 2 arrays and the sizeof array is important. So when a value comes in knowing the sizeof the array it is pushed to the left or right of the array a value to examine. If a value doesn't exist its inserted one way, if it does exist it is compares the left and right and ether moves or inserts. It is looking for a optimum value delta of 2. I am just writing it here for fun, but will reduce it to assembler at the end and see what I can do to reduce it to the fewest steps.

At the end you have a left and right side to the pyramid. The you just zipper them both up.