Numerical value

Overview

Integers and floating point numbers

Inside JavaScript, all numbers are stored as 64-bit floating point numbers, even integers. Therefore, 1 is the same as 1.0, and is the same number.

1 === 1.0; // true

This means that there are no integers at the bottom of the JavaScript language, and all numbers are decimals (64-bit floating point numbers). It is easy to cause confusion that certain operations can only be done with integers. At this time, JavaScript will automatically convert 64-bit floating-point numbers into 32-bit integers, and then perform operations. Refer to the "Bit Operations" section of the "Operators" chapter.

Since floating-point numbers are not exact values, comparisons and operations involving decimals must be particularly careful.

0.1 + 0.2 === 0.3;
// false

0.3 /
  0.1(
    // 2.9999999999999996

    0.3 - 0.2
  ) ===
  0.2 - 0.1;
// false

Numerical precision

According to the international standard IEEE 754, the 64 binary bits of JavaScript floating point numbers, starting from the leftmost side, are composed like this.

-Bit 1: Sign bit, 0 means positive number, 1 means negative number -From 2nd to 12th (11 in total): Exponential part -From the 13th to the 64th (52 digits in total): decimal part (ie significant digits)

The sign bit determines the sign of a number, the exponent part determines the magnitude of the value, and the decimal part determines the accuracy of the value.

The exponent part has a total of 11 binary bits, so the size range is 0 to 2047. IEEE 754 stipulates that if the value of the exponent part is between 0 and 2047 (without two endpoints), then the first digit of the significant digit is always 1 by default, and is not stored in a 64-bit floating point number. In other words, the significant number is always in the form of 1.xx...xx, where the part of xx..xx is stored in a 64-bit floating point number, and the longest may be 52 bits. Therefore, the maximum number of significant digits provided by JavaScript is 53 binary digits.

(-1)^Sign bit* 1.xx...xx * 2^Exponent part

The above formula is the actual representation of a number in JavaScript under normal circumstances (the exponent part is between 0 and 2047).

The precision can only be up to 53 binary digits, which means that the absolute value is less than an integer of the 53th power of 2, that is, -253 to 253, all can be accurate Said.

Math.pow(2, 53);
// 9007199254740992

Math.pow(2, 53) + 1;
// 9007199254740992

Math.pow(2, 53) + 2;
// 9007199254740994

Math.pow(2, 53) + 3;
// 9007199254740996

Math.pow(2, 53) + 4;
// 9007199254740996

In the above code, after being greater than 2 to the 53th power, the result of integer operation starts to show errors. Therefore, values ​​greater than 2 to the 53th power cannot maintain accuracy. Since the 53th power of 2 is a 16-digit decimal value, the simple rule is that JavaScript can handle 15-digit decimal numbers accurately.

Math.pow(2, 53);
// 9007199254740992

// The three more valid numbers will not be saved
9007199254740992111;
// 9007199254740992000

The above example shows that after being greater than 2 to the 53th power, the extra significant digits (the last three digits 111) will not be saved and become 0.

Numerical Range

According to the standard, the length of the exponent part of a 64-bit floating point number is 11 binary digits, which means that the maximum exponent part is 2047 (2 to the 11th power minus 1). In other words, the maximum value of the exponent part of a 64-bit floating point number is 2047, and half of it represents a negative number. The value range that JavaScript can represent is 21024 to 2-1023 (Open interval), numbers beyond this range cannot be represented.

If a number is greater than or equal to the 1024th power of 2, then "positive overflow" will occur, that is, JavaScript cannot represent such a large number, and then Infinity will be returned.

Math.pow(2, 1024); // Infinity

If a number is less than or equal to 2 to the power of -1075 (the minimum exponent part is -1023, plus 52 digits in the decimal part), then "negative overflow" will occur, that is, JavaScript cannot represent such a small number. It will return 0 directly.

Math.pow(2, -1075); // 0

The following is a practical example.

var x = 0.5;

for (var i = 0; i < 25; i++) {
  x = x * x;
}

x; // 0

In the above code, squaring 0.5 consecutively 25 times, because the final result is too close to 0 and beyond the expressible range, JavaScript directly converts it to 0.

JavaScript provides the MAX_VALUE and MIN_VALUE properties of the Number object, which return the specific maximum and minimum values ​​that can be represented.

Number.MAX_VALUE; // 1.7976931348623157e+308
Number.MIN_VALUE; // 5e-324

Numerical representation

There are many ways to express JavaScript values, which can be directly expressed in literal form, such as 35 (decimal) and 0xFF (hexadecimal).

Numerical values ​​can also be expressed in scientific notation. Here are a few examples of scientific notation.

123e3; // 123000
123e-3 - // 0.123
  3.1e12;
0.1e-23;

Scientific notation allows the letter e or E followed by an integer to indicate the exponential part of the value.

In the following two cases, JavaScript will automatically convert the value to scientific notation. In other cases, it will be directly expressed in literal form.

**(1) There are more than 21 digits before the decimal point. **

1234567890123456789012;
// 1.2345678901234568e+21

123456789012345678901;
// 123456789012345680000

**(2) There are more than 5 zeros after the decimal point. **

// There are more than 5 zeros immediately after the decimal point,
// It will automatically switch to scientific notation
0.0000003; // 3e-7

// Otherwise, keep the original literal form
0.000003; // 0.000003

Numerical base

When using a literal to directly represent a value, JavaScript provides four representation methods for integers: decimal, hexadecimal, octal, and binary.

  • Decimal: Value without leading 0.
  • Octal: Values ​​with prefix 0o or 0O, or values ​​with leading 0 and only eight Arabic numerals from 0-7.
  • Hexadecimal: Values ​​with prefix 0x or 0X.
  • Binary: Values ​​with prefix 0b or 0B.

By default, JavaScript will automatically convert octal, hexadecimal, and binary to decimal. Here are some examples.

0xff; // 255
0o377; // 255
0b11; // 3

If octal, hexadecimal, or binary numbers contain numbers that do not belong to the hexadecimal system, an error will be reported.

0xzz // report an error
0o88 // report an error
0b22 // report an error

In the above code, the letter z appears in the hexadecimal system, the number 8 in the octal system, and the number 2 in the binary system, so an error is reported.

Generally speaking, a value with a leading 0 is regarded as octal, but if there are numbers 8 and 9 after the leading 0, the value is regarded as decimal.

0888; // 888
0777; // 511

The leading 0 represents octal, which can easily cause confusion when processing. ES5's strict mode and ES6 have abolished this notation, but browsers continue to support this notation for compatibility with previous codes.

Special value

JavaScript provides several special values.

Positive zero and negative zero

As mentioned earlier, in JavaScript's 64-bit floating point numbers, one binary bit is the sign bit. This means that any number has a corresponding negative value, even 0 is no exception.

There are actually two 0s in JavaScript: one is +0 and the other is -0. The difference is that the sign bit of the 64-bit floating-point number representation is different. They are equivalent.

-0 === +0; // true
0 === -0; // true
0 === +0; // true

In almost all cases, positive zero and negative zero will be treated as normal 0.

+0 - // 0
  0(
    // 0
    -0
  )
    .toString()(
      // '0'
      +0
    )
    .toString(); // '0'

The only difference is that when +0 or -0 is used as the denominator, the returned values ​​are not equal.

1 / +0 === 1 / -0; // false

The result of the above code is that dividing by positive zero gets +Infinity, and dividing by negative zero gets -Infinity, the two are not equal (see below for details on Infinity).

NaN

(1) Meaning

NaN is a special value of JavaScript, which means "Not a Number", which mainly occurs when there is an error in parsing a string into a number.

5 - "x"; // NaN

When the above code runs, it will automatically convert the string x to a number, but because x is not a number, the final result is NaN, which means it is "not a number" (NaN).

In addition, the result of some mathematical functions will appear NaN.

Math.acos(2); // NaN
Math.log(-1); // NaN
Math.sqrt(-1); // NaN

Dividing 0 by 0 will also get NaN.

0 / 0; // NaN

It should be noted that NaN is not an independent data type, but a special value. Its data type still belongs to Number, which can be seen clearly by using the typeof operator.

typeof NaN; //'number'

(2) Operation rules

NaN is not equal to any value, including itself.

NaN === NaN; // false

The indexOf method of the array uses the strict equality operator internally, so this method does not hold for NaN.

[NaN].indexOf(NaN); // -1

NaN is treated as false in Boolean operations.

Boolean(NaN); // false

The operation of NaN with any number (including itself) results in NaN.

NaN + 32; // NaN
NaN - 32; // NaN
NaN * 32; // NaN
NaN / 32; // NaN

Infinity

(1) Meaning

Infinity means "infinity" and is used to indicate two scenarios. One is that a positive value is too large, or a negative value is too small to be represented; the other is that a non-zero value is divided by 0 to get Infinity.

// scene one
Math.pow(2, 1024);
// Infinity

// Scene two
0 / 0; // NaN
1 / 0; // Infinity

In the above code, the first scenario is that the calculation result of an expression is too large, beyond the range that can be expressed, so Infinity is returned. The second scenario is that dividing 0 by 0 will get NaN, instead of dividing a value of 0 by 0, it will return Infinity.

Infinity has positive and negative points, Infinity means positive infinity, and -Infinity means negative infinity.

Infinity === -Infinity; // false

1 / -0 - // -Infinity
  1 / -0; // Infinity

In the above code, if a non-zero positive number is divided by -0, you will get -Infinity, and if a negative number is divided by -0, you will get Infinity.

Due to positive overflow, underflow and division by 0, JavaScript does not report errors, so it is almost impossible for pure mathematical operations to throw errors.

Infinity is greater than all numbers (except NaN), and -Infinity is less than all numbers (except NaN).

Infinity >
  1000 - // true
    Infinity <
  -1000; // true

Infinity is compared with NaN and always returns false.

Infinity >
  NaN - // false
    Infinity >
  NaN; // false

Infinity <
  NaN - // false
    Infinity <
  NaN; // false

(2) Operation rules

The four arithmetic operations of Infinity conform to the infinite mathematical calculation rules.

5 * Infinity; // Infinity
5 - Infinity; // -Infinity
Infinity / 5; // Infinity
5 / Infinity; // 0

Multiplying 0 by Infinity returns NaN; dividing 0 by Infinity returns 0; dividing Infinity by 0 returns Infinity.

0 * Infinity; // NaN
0 / Infinity; // 0
Infinity / 0; // Infinity

Adding or multiplying Infinity by Infinity will return Infinity.

Infinity + Infinity; // Infinity
Infinity * Infinity; // Infinity

Subtract or divide Infinity by Infinity to get NaN.

Infinity - Infinity; // NaN
Infinity / Infinity; // NaN

When calculating Infinity and null, null will be converted to 0, which is equivalent to calculating with 0.

null * Infinity; // NaN
null / Infinity; // 0
Infinity / null; // Infinity

For Infinity and undefined calculations, all returned are NaN.

undefined + Infinity; // NaN
undefined - Infinity; // NaN
undefined * Infinity; // NaN
undefined / Infinity; // NaN
Infinity / undefined; // NaN

parseInt()

(1) Basic usage

The parseInt method is used to convert a string to an integer.

parseInt("123"); // 123

If there is a space at the beginning of the string, the space will be automatically removed.

parseInt(" 81"); // 81

If the parameter of parseInt is not a string, it will first be converted to a string and then converted.

parseInt(1.23); // 1
// Equivalent to
parseInt("1.23"); // 1

When a character string is converted to an integer, it is converted one by one. If it encounters a character that cannot be converted into a number, it will not proceed any more and return to the converted part.

parseInt("8a"); // 8
parseInt("12**"); // 12
parseInt("12.34"); // 12
parseInt("15e2"); // 15
parseInt("15px"); // 15

In the above code, the parameters of parseInt are all strings, and the result only returns the part of the string head that can be converted into a number.

If the first character of the string cannot be converted to a number (except for the sign followed by a number), NaN is returned.

parseInt("abc"); // NaN
parseInt(".3"); // NaN
parseInt(""); // NaN
parseInt("+"); // NaN
parseInt("+1"); // 1

Therefore, the return value of parseInt has only two possibilities, either a decimal integer or NaN.

If the string starts with 0x or 0X, parseInt will parse it as a hexadecimal number.

parseInt("0x10"); // 16

If the string starts with 0, it will be parsed in decimal.

parseInt("011"); // 11

For those numbers that are automatically converted to scientific notation, parseInt treats the representation method of scientific notation as a string, which leads to some strange results.

parseInt(1000000000000000000000.5); // 1
// Equivalent to
parseInt("1e+21"); // 1

parseInt(0.0000008); // 8
// Equivalent to
parseInt("8e-7"); // 8

(2) hexadecimal conversion

The parseInt method can also accept a second parameter (between 2 and 36), which represents the base of the value being parsed, and returns the decimal number corresponding to the value. By default, the second parameter of parseInt is 10, which means that the default is decimal to decimal.

parseInt("1000"); // 1000
// Equivalent to
parseInt("1000", 10); // 1000

The following is an example of converting a number in a specified base.

parseInt("1000", 2); // 8
parseInt("1000", 6); // 216
parseInt("1000", 8); // 512

In the above code, 1000 in binary, hexadecimal and octal is equal to 8, 216 and 512 in decimal, respectively. This means that you can use the parseInt method to perform hexadecimal conversion.

If the second parameter is not a numeric value, it will be automatically converted to an integer. Only when this integer is between 2 and 36 can you get a meaningful result. If it exceeds this range, it will return NaN. If the second parameter is 0, undefined and null, it is ignored.

parseInt("10", 37); // NaN
parseInt("10", 1); // NaN
parseInt("10", 0); // 10
parseInt("10", null); // 10
parseInt("10", undefined); // 10

If the string contains characters that are meaningless for the specified base, starting from the highest bit, only the numeric value that can be converted is returned. If the highest bit cannot be converted, it will directly return to NaN.

parseInt("1546", 2); // 1
parseInt("546", 2); // NaN

In the above code, for binary, 1 is a meaningful character, and 5, 4, and 6 are all meaningless characters, so the first line returns 1 and the second line returns NaN .

As mentioned earlier, if the first parameter of parseInt is not a string, it will be converted to a string first. This can lead to some surprising results.

parseInt(0x11, 36); // 43
parseInt(0x11, 2); // 1

// Equivalent to
parseInt(String(0x11), 36);
parseInt(String(0x11), 2);

// Equivalent to
parseInt("17", 36);
parseInt("17", 2);

In the above code, the hexadecimal 0x11 will first be converted to decimal 17 and then into a string. Then, interpret the string 17 with 36 base or binary, and finally return the results 43 and 1.

This processing method requires special attention for the octal prefix 0.

parseInt(011, 2); // NaN

// Equivalent to
parseInt(String(011), 2);

// Equivalent to
parseInt(String(9), 2);

In the above code, the 011 in the first line will be converted to the string 9 first, because 9 is not a valid binary character, so NaN is returned. If you directly calculate parseInt('011', 2), 011 will be treated as binary and 3 will be returned.

JavaScript no longer allows numbers with a prefix of 0 to be treated as octal numbers, but requires that this 0 be ignored. However, in order to ensure compatibility, most browsers do not deploy this provision.

parseFloat()

The parseFloat method is used to convert a string to a floating point number.

parseFloat("3.14"); // 3.14

If the string conforms to scientific notation, it will be converted accordingly.

parseFloat("314e-2"); // 3.14
parseFloat("0.0314E+2"); // 3.14

If the string contains characters that cannot be converted into floating-point numbers, no further conversion is performed, and the converted part is returned.

parseFloat("3.14more non-digit characters"); // 3.14

The parseFloat method will automatically filter the leading spaces of the string.

parseFloat("\t\v\r12.34\n"); // 12.34

If the argument is not a string, or the first character of the string cannot be converted into a floating point number, NaN is returned.

parseFloat([]); // NaN
parseFloat("FF2"); // NaN
parseFloat(""); // NaN

In the above code, it is especially worth noting that parseFloat will convert an empty string to NaN.

These features make the conversion result of parseFloat different from the Number function.

parseFloat(true); // NaN
Number(true); // 1

parseFloat(null); // NaN
Number(null); // 0

parseFloat(""); // NaN
Number(""); // 0

parseFloat("123.45#"); // 123.45
Number("123.45#"); // NaN

isNaN()

The isNaN method can be used to determine whether a value is NaN.

isNaN(NaN); // true
isNaN(123); // false

However, isNaN is only valid for numeric values. If other values ​​are passed in, they will be converted to numeric values ​​first. For example, when a string is passed in, the string will be converted to NaN first, so it will return true at the end. This point requires special attention. In other words, the value of isNaN as true may not be NaN, but a string.

isNaN("Hello"); // true
// equivalent to
isNaN(Number("Hello")); // true

For the same reason, for objects and arrays, isNaN also returns true.

isNaN({}); // true
// Equivalent to
isNaN(Number({})); // true

isNaN(["xzy"]); // true
// Equivalent to
isNaN(Number(["xzy"])); // true

However, for empty arrays and arrays with only one numeric member, isNaN returns false.

isNaN([]); // false
isNaN([123]); // false
isNaN(["123"]); // false

The above code returns false because these arrays can be converted into numbers by the Number function. Please refer to the chapter "Data Type Conversion".

Therefore, before using isNaN, it is best to judge the data type.

function myIsNaN(value) {
  return typeof value === "number" && isNaN(value);
}

A more reliable way to judge NaN is to make use of the characteristic that NaN is the only value that is not equal to itself.

function myIsNaN(value) {
  return value !== value;
}

isFinite()

The isFinite method returns a boolean value indicating whether a value is a normal value.

isFinite(Infinity); // false
isFinite(-Infinity); // false
isFinite(NaN); // false
isFinite(undefined); // false
isFinite(null); // true
isFinite(-1); // true

Except for Infinity, -Infinity, NaN and undefined these values ​​will return false, and isFinite will return true for other values.