# 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 `0`s 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
``````

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(); // 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.