Let me talk about the conclusion:

parseInt is more reliable, but pay attention to the type and number of parameters;

There will be some problems with using bitwise operators (`~~`

, `>>0`

, `<<0`

) to "round", and it is not recommended in general;

After all, bit operations are operators, and the efficiency is higher. If this "rounding" operation is a key operation that affects performance, and you know that the operand will not exceed the precision limit, you can consider using bit operations

## 1. Usage and problems of parseInt

`Number.parseInt`

accepts two parameters by default

The first parameter is a string type value by default. If it is not, it will be forced into a string type value through the abstract ToString. There will be various pits in the forced type conversion process.

The second parameter is the base of the number type. If it is not, it will be coerced into a value of the number type through the abstract ToNumber. The range is 2-36. After the coercion type conversion, if it is other value, it will return NaN. Before ES5, if this parameter is not passed in, the base will be judged based on the beginning of the first parameter, and the string starting with 0 will be judged as an octal base, which is the old yellow calendar pit mentioned by @user. It has been resolved after ES5. If this parameter is not passed, it will default to decimal. But this parameter is easy to be ignored, especially when it is used with a function like map that also easily ignores subsequent optional parameters, such as

`['10', '10', '10', '10'].map(parseInt) // The result is [10, NaN, 2, 3]`

So if you just use parseInt to "round up", a good habit is to always remember to set the second parameter to 10

Then try not to use parseInt to convert some other types of values. If you really encounter a result that needs to be judged (such as some idle interviewers have to investigate this), then first evaluate the two parameters and convert Into the corresponding type, and then judge.

The judgment process can be roughly understood as: the conversion result of the first parameter removes the blanks, and then extracts from left to right the integer part that can be understood in the base specified by the second parameter, and returns the value of this value in decimal base. If conversion fails, return NaN

Except for these situations, parseInt is safe to use within the range allowed by JavaScript values

## 2. Usage and problems of `>>0`

and `<<0`

Before looking at the bit operation, we must first make it clear (personal understanding, not necessarily accurate):

The value of the number type in JavaScript is stored using the 64-bit double-precision floating-point type of the IEEE 754 standard, that is, 1 bit sign bit + 11 bit exponent part + 52 bit mantissa part. When used to represent integers, the safe range is 53 bits. Returning beyond this may cause loss of precision

One thing to note is that bitwise operations will treat NaN and Infinity as 0.

The operands participating in **bit arithmetic** will first perform the abstract ToInt32 operation on it, the most important in Specification The third and fourth steps are:

- Let posInt be sign(number) * floor(abs(number)).
- Let int32bit be posInt modulo 2^32; that is, a finite integer value k of Number type with positive sign and less than 2^32 in magnitude such that the mathematical difference of posInt and> k is mathematically an integer multiple of 2^32.

Simply put, rounding and remainder, there will be two problems here:

The method of rounding is different from Math.floor. ToInt32 rounds the absolute value and then adds a sign, and Math.floor rounds directly down. For example,

`ToInt32(-1.5) == -1`

, and`Math.floor(-1.5) == -2`

The method of seeking surplus is a bit complicated. In short, unexpected things will happen under certain conditions (leave a hole first, and I will interpret it carefully when you have time)

Then the `>>0`

and `<<0`

here do not perform specific displacement operations on the actual value, but the ToInt32 operation will still be performed. Within a certain range, it is simply rounded by the absolute value, beyond this The range will become an unexpected value

## 3. The usage and problems of `~~`

~ Is also a bitwise operator. Like the shift operator above, it also passes ToInt32 first. Its function is to flip the binary form of the operand bit by bit. So two ~~ connected together is equivalent to the following operations:

Perform ToInt32 on the operand

Bit flip

Flip by bit again

In fact, it still uses the absolute value of ToInt32 to round up

In addition, there is a trick about the ~ operator that is more practical:

The value of ~(-1) is 0, and -1 is the only value that returns a false value after the ~ operation (including other special values such as `NaN`

, `{}`

, `[]`

, etc. will not return False value)

The indexOf function of string and array will return -1 if it fails to find it, then you can use it

`if(~str.indexOf('str')) // to indicate found`

It is more elegant than judging >= 0 or != -1, and it is similar to using `!!`

to judge non-false values.