Reputation: 345
I'm translating a library from javascript to C#, and felt under this case:
// Javascript
var number = 3144134277.518717 | 0;
console.log(number); // -> -1150833019
From what I read on other post, it might of been used to round values, but in this case the value isn't what I expect it to be (if it was to be rounded) and I can't reproduce in C# the same behavior with:
// C#
3144134277.5187168 | 0 // -> Operator '|' cannot be applied to operands
// of type 'double' and 'int'
// or
Convert.ToInt64(3144134277.5187168) | 0 // -> 3144134278
Thanks for any help!
Upvotes: 2
Views: 375
Reputation: 1075139
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:
ToNumber(argument)
. (You can largely ignore this bit.)NaN
, +0
, -0
, +∞
, or -∞
, return +0
.floor(abs(number))
.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.
Upvotes: 7