Martin Gemme - 7 months ago 40

Javascript Question

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!

Answer

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.

And just double-checking, those steps with `-3144134277.5187168`

give you `1150833019`

, which is as it's supposed to be as well.