In R if I do bitXor(2496638211, -1798328965) I get 120 returned.
In nodeJS 2496638211 ^ -1798328965; returns 120.
How do I do this in C#? (Think I'm struggling to understand c# type declaration and the way R & nodeJS presumably convert to 32 bits)
In C# you would have to use unchecked and cast to int:
unchecked
{
int result = (int)2496638211 ^ -1798328965;
Console.WriteLine(result); // Prints 120
}
You could write a method to do this:
public static int XorAsInts(long a, long b)
{
unchecked
{
return (int)a ^ (int)b;
}
}
Then call it:
Console.WriteLine(XorAsInts(2496638211, -1798328965)); // Prints 120
Note that by casting to int, you are throwing away the top 32 bits of the long. This is what bitXor() is doing, but are you really sure this is the behaviour you want?
2496638211 is larger than an 32bit integer and in 64 bit systems with C# integers defaults long thus the hex value representation is0x94CFAD03. That 9 overlaps with the sign bits. This is also means that -1798328965 results in 0xFFFFFFFF94CFAD7B due to the negative number representation. So C# gets 0xFFFFFFFF00000078 that is the correct answer.
JS XOR uses 32 bit operands so it truncates 2496638211. Thus JS gets 0x00000078 that is not technically the correct answer. My assumption is that R does the same or similar.
In JS use Number.isSafeInteger() as well as Number.MAX_SAFE_INTEGER. In C# check int.MaxValue vs long.MaxValue to see the difference vs JS.
To recreate the JS behavior in C# wrap it in an unchecked block as per Matthew Watson post. The unchecked keyword is used to suppress overflow-checking for integral-type arithmetic operations and conversions.