Advise on preferred way to convert numbers to ints

As well explained in this StackOverflow topic, there are several ways to get from a number | string | unknown to an integer value. When we leave rounding (Math.floor, Math.round, math.ceil) out of the equation, there are several ways to get a (truncated) integer equal to how things work in the C (like) world:

// x = Number.MAX_SAFE_INTEGER/10 // =900719925474099.1

// value=x            x=900719925474099    x=900719925474099.4  x=900719925474099.5

Math.trunc(value) //  900719925474099      900719925474099      900719925474099
parseInt(value)   //  900719925474099      900719925474099      900719925474099
value | 0         //  858993459            858993459            858993459
~~value           //  858993459            858993459            858993459
value >> 0        //  858993459            858993459            858993459
value >>> 0       //  858993459            858993459            858993459
value - value % 1 //  900719925474099      900719925474099      900719925474099

// x = Number.MAX_SAFE_INTEGER/10 * -1 // -900719925474099.1

// value = x      // x=-900719925474099   x=-900719925474099.5 x=-900719925474099.6

Math.trunc(value) // -900719925474099     -900719925474099     -900719925474099
parseInt(value)   // -900719925474099     -900719925474099     -900719925474099
value | 0         // -858993459           -858993459           -858993459
~~value           // -858993459           -858993459           -858993459
value >> 0        // -858993459           -858993459           -858993459
value >>> 0       //  3435973837           3435973837           3435973837
value - value % 1 // -900719925474099     -900719925474099     -900719925474099

All methods work for small positive values, only parseInt, Math.trunc and % 1 work for all. A rule that could guide the not so experienced TypeScript/Javascript developer (including me) to choose the right method, would be appreciated.

Hello @Corniel,

we already have a ticket opened to implement something similar: Jira

I would not go that far in recommending any of the valid ones: some users may prefer readability, some others performance. But to raise awareness that bitwise operators truncate to 32bit I agree is a very valid rule.

Thanks again for your rule ideas @Corniel !

1 Like

II think I would discourage the use of at least parseInt and ``>>>. I was hoping that your analyzer could detect if truncating to Int32is safe or not. (I personally like~~` a lot in calculations).

And ~~ is perfectly fine if you are working with smallish numbers. That’s why this rule should just be considered a small warning. Why would you discourage the usage of parseInt. You mean the preferred way should be Number.parseInt?

Sadly that’s not possible in the scope of static analysis. That would require some symbolic execution engine, and most code depends on user input. So no, we are not capable of detecting that

1 Like

Whell, let me rephrase: I think that parseInt/Number.parseInt should only be used when the input is not already ensures to be number. Math.truncate is (I think) preferred when the type number is guaranteed. For me the reason is that parseInt tells me a different story than Math.truncate, and the latter fits better when converting numbers.

1 Like

Revisiting this topic:

I think (n >> 0) and (n >>> 0) and n - n % 1 should be discouraged, just as Number.intParse() when the input is known to be a number.