The way | works in javaScript is detailed in the spec, but primarily what you're seeing is that | implicitly converts its operands to 32-bit ints before doing the bitwise OR (which is a no-op because the second arg is 0). So really what you're seeing is the result of the ToInt32 operation:
- Let number be ?
ToNumber(argument). (You can largely ignore this bit.)
- If number is
NaN, +0, -0, +∞, or -∞, return +0.
- Let int be the mathematical value that is the same sign as number and whose magnitude is
floor(abs(number)).
- Let int32bit be int modulo 2^32.
- If int32bit ≥ 2^31, return int32bit - 2^32; otherwise return int32bit.
So in C#, I think that's roughly:
double value = 3144134277.5187168;
bool negative = value < 0;
long n = Convert.ToInt64(Math.Floor(Math.Abs(value)));
n = n % 4294967296;
n = n > 2147483648 ? n - 4294967296 : n;
int i = (int)n;
i = negative ? -i : i;
Console.WriteLine(i); // -1150833019
...written verbosely for clarity. Note that the sign isn't added back to the result in quite the same place as the spec; when I did that, it didn't work correctly, which probably has to do with differing definitions between the spec's "modulo" and C#'s % operator.
And just double-checking, those steps with -3144134277.5187168 give you 1150833019, which is as it's supposed to be as well.