This is the 10th day of my participation in the August Text Challenge.More challenges in August

Binary and octal representation

ES6 provides a new way to write binary and octal values, represented by prefixes 0b (or 0b) and 0O (or 0O), respectively.

0b111110111= = =503 // true
0o767= = =503 // true
Copy the code

If you want to decimal string values prefixed with 0b and 0o, use the Number method.

Number('0b111')  / / 7
Number('0o10')  / / 8
Copy the code

Second, Number. IsFinite (), Number. The isNaN ()

ES6 provides two new methods on Number objects, number.isfinite () and number.isnan ().

Number.isfinite () is used to check whether a Number isFinite, i.e., not Infinity.

Number.isFinite(15); // true
Number.isFinite(0.8); // true
Number.isFinite(NaN); // false
Number.isFinite(Infinity); // false
Number.isFinite(-Infinity); // false
Number.isFinite('foo'); // false
Number.isFinite('15'); // false
Number.isFinite(true); // false
Copy the code

Note that number. isFinite returns false if the parameter type is not a Number.

Number.isnan () is used to check whether a value isNaN.

Number.isNaN(NaN) // true
Number.isNaN(15) // false
Number.isNaN('15') // false
Number.isNaN(true) // false
Number.isNaN(9/NaN) // true
Number.isNaN('true' / 0) // true
Number.isNaN('true' / 'true') // true
Copy the code

If the parameter type is not NaN, number. isNaN always returns false.

They differ from the traditional global methods isFinite() and isNaN(), which call Number() to convert a non-numerical value to a numerical value and then judge, but these two new methods are only valid for numerical values. Number.isfinite () returns false for non-numeric values, number.isnan () returns true only for nans, false for non-nans.

isFinite(25) // true
isFinite("25") // true
Number.isFinite(25) // true
Number.isFinite("25") // false

isNaN(NaN) // true
isNaN("NaN") // true
Number.isNaN(NaN) // true
Number.isNaN("NaN") // false
Number.isNaN(1) // false
Copy the code

Three, Number. The parseInt (), Number. The parseFloat ()

ES6 migrates the global methods parseInt() and parseFloat() onto the Number object, leaving the behavior exactly the same.

// ES5
parseInt('12.34') / / 12
parseFloat('123.45 #') / / 123.45

// ES6
Number.parseInt('12.34') / / 12
Number.parseFloat('123.45 #') / / 123.45
Copy the code

The goal is to gradually reduce the global approach and make the language more modular.

Number.parseInt === parseInt // true
Number.parseFloat === parseFloat // true
Copy the code

Four, Number. IsInteger ()

Number.isinteger () is used to determine whether a value is an integer.

Number.isInteger(25) // true
Number.isInteger(25.1) // false
Copy the code

Inside JavaScript, integers and floating point numbers are stored the same way, so 25 and 25.0 are treated as the same value.

Number.isInteger(25) // true
Number.isInteger(25.0) // true
Copy the code

If the argument is not a numeric value, number. isInteger returns false.

Number.isInteger() // false
Number.isInteger(null) // false
Number.isInteger('15') // false
Number.isInteger(true) // false
Copy the code

Note that due to the IEEE 754 standard in JavaScript, values are stored in a 64-bit double precision format with up to 53 binary bits (1 hidden bit and 52 significant bits). If the precision of the value exceeds this limit, the 54th and subsequent bits are discarded, in which case number. isInteger may misjudge.

Number.isInteger(3.0000000000000002) // true
Copy the code

In the code above, the Number. IsInteger argument is not an integer, but it returns true. The reason was that the decimal was 16 decimal places to the decimal point and converted to more than 53 binary places, resulting in the final 2 being discarded.

Similarly, if the absolute value of a value is less than number.min_value (5E-324), which is less than the minimum value that JavaScript can resolve, it is automatically converted to 0. In this case, number. isInteger will also misjudge.

Number.isInteger(5E-324) // false
Number.isInteger(5E-325) // true
Copy the code

In the code above, 5E-325 is automatically converted to 0 because the value is too small, so it returns true.

In general, if high data accuracy is required, it is not recommended to use number.isINTEGER () to determine whether a value is an integer.

Number. IsSafeInteger ()

The range of integers that JavaScript can accurately represent is between -2^53 and 2^53 (excluding the two endpoints), beyond which this value cannot be accurately represented.

Math.pow(2.53) / / 9007199254740992

9007199254740992  / / 9007199254740992
9007199254740993  / / 9007199254740992

Math.pow(2.53) = = =Math.pow(2.53) + 1
// true
Copy the code

In the code above, a number becomes imprecise beyond 2 to the power of 53.

ES6 introduces two constants, number. MAX_SAFE_INTEGER and number. MIN_SAFE_INTEGER, to indicate the upper and lower limits of this range.

Number.MAX_SAFE_INTEGER === Math.pow(2.53) - 1
// true
Number.MAX_SAFE_INTEGER === 9007199254740991
// true

Number.MIN_SAFE_INTEGER === -Number.MAX_SAFE_INTEGER
// true
Number.MIN_SAFE_INTEGER === -9007199254740991
// true
Copy the code

In the code above, you can see the limits of what JavaScript can accurately represent.

Number.issafeinteger () is used to determine whether an integer falls within this range.

Number.isSafeInteger('a') // false
Number.isSafeInteger(null) // false
Number.isSafeInteger(NaN) // false
Number.isSafeInteger(Infinity) // false
Number.isSafeInteger(-Infinity) // false

Number.isSafeInteger(3) // true
Number.isSafeInteger(1.2) // false
Number.isSafeInteger(9007199254740990) // true
Number.isSafeInteger(9007199254740992) // false

Number.isSafeInteger(Number.MIN_SAFE_INTEGER - 1) // false
Number.isSafeInteger(Number.MIN_SAFE_INTEGER) // true
Number.isSafeInteger(Number.MAX_SAFE_INTEGER) // true
Number.isSafeInteger(Number.MAX_SAFE_INTEGER + 1) // false
Copy the code

The implementation of this function is as simple as comparing the two boundary values of the safe integer.

Number.isSafeInteger = function (n) {
  return (typeof n === 'number' &&
    Math.round(n) === n &&
    Number.MIN_SAFE_INTEGER <= n &&
    n <= Number.MAX_SAFE_INTEGER);
}
Copy the code

Be careful when actually using this function. Verify that the result of an operation falls within the range of safe integers, not just the result of the operation, but each value participating in the operation.

Number.isSafeInteger(9007199254740993)
// false
Number.isSafeInteger(990)
// true
Number.isSafeInteger(9007199254740993 - 990)
// true
9007199254740993 - 990
9007199254740002 is displayed
// The correct answer is 9007199254740003
Copy the code

In the code above, 9007199254740993 is not a safe integer, but number. isSafeInteger returns a result indicating that the calculation is safe. This is because the number is out of precision and is stored inside the computer as 9007199254740992.

9007199254740993= = =9007199254740992
// true
Copy the code

So, if you only verify that the result is a safe integer, you are likely to get an incorrect result. The following function validates both operands and results.

function trusty (left, right, result) {
  if (
    Number.isSafeInteger(left) &&
    Number.isSafeInteger(right) &&
    Number.isSafeInteger(result)
  ) {
    return result;
  }
  throw new RangeError('Operation cannot be trusted! ');
}

trusty(9007199254740993.990.9007199254740993 - 990)
// RangeError: Operation cannot be trusted!

trusty(1.2.3)
/ / 3
Copy the code

Extension of the Math object

ES6 adds 17 new math-related methods to the Math object. All of these methods are static and can only be called on Math objects. Here are some common methods.

1. Math.trunc()

The math. trunc method is used to remove the fractional part of a number and return the integer part.

Math.trunc(4.1) / / 4
Math.trunc(4.9) / / 4
Math.trunc(-4.1) / / - 4
Math.trunc(-4.9) / / - 4
Math.trunc(-0.1234) / / - 0
Copy the code

For non-numeric values, math.trunc internally converts them to numeric values using the Number method.

Math.trunc('123.456') / / 123
Math.trunc(true) / / 1
Math.trunc(false) / / 0
Math.trunc(null) / / 0
Copy the code

NaN is returned for null values and values that cannot intercept integers.

Math.trunc(NaN);      // NaN
Math.trunc('foo');    // NaN
Math.trunc();         // NaN
Math.trunc(undefined) // NaN
Copy the code

For environments where this method is not deployed, you can simulate it with the following code.

Math.trunc = Math.trunc || function(x) {
  return x < 0 ? Math.ceil(x) : Math.floor(x);
};
Copy the code

2. Math.sign()

The math. sign method is used to determine whether a number is positive, negative, or zero. For non-numeric values, they are converted to numeric values first.

It returns five values.

  • Returns if the argument is a positive number+ 1;
  • If argument is negative, return- 1;
  • Parameters for0To return to0;
  • Parameters for0To return to0;
  • Other values, returnNaN.
Math.sign(-5) // -1
Math.sign(5) / / + 1
Math.sign(0) / / + 0
Math.sign(-0) / / - 0
Math.sign(NaN) // NaN
Copy the code

If the parameter is not a value, it is automatically converted to a value. NaN is returned for values that cannot be converted to numeric values.

Math.sign(' ')  / / 0
Math.sign(true)  / / + 1
Math.sign(false)  / / 0
Math.sign(null)  / / 0
Math.sign('9')  / / + 1
Math.sign('foo')  // NaN
Math.sign()  // NaN
Math.sign(undefined)  // NaN
Copy the code

For environments where this method is not deployed, you can simulate it with the following code.

Math.sign = Math.sign || function(x) {
  x = +x; // convert to a number
  if (x === 0 || isNaN(x)) {
    return x;
  }
  return x > 0 ? 1 : -1;
};
Copy the code

3. Math.cbrt()

Math.cbrt() is used to calculate the cube root of a number.

Math.cbrt(-1) // -1
Math.cbrt(0)  / / 0
Math.cbrt(1)  / / 1
Math.cbrt(2)  / / 1.2599210498948732
Copy the code

For non-numeric values, math.cbrt () also uses the Number() method first inside the method.

Math.cbrt('8') / / 2
Math.cbrt('hello') // NaN
Copy the code

For environments where this method is not deployed, you can simulate it with the following code.

Math.cbrt = Math.cbrt || function(x) {
  var y = Math.pow(Math.abs(x), 1/3);
  return x < 0 ? -y : y;
};
Copy the code

4. Other

  • Math.clz32()Method converts the argument to a 32-bit unsigned integer and returns how many leads there are in the 32-bit value0.
  • Math.imulThe signed integer () method returns the product of two 32-bit signed integers, which also returns a 32-bit signed integer
  • Math.froundMethod returns the 32-bit single-precision floating-point form of a number
  • Math.hypotMethod returns the square root of the sum of squares of all arguments
  • Math.expm1(x)returnex - 1, i.e.,Math.exp(x) - 1
  • Math.log1p(x)Method returns1 + xThe natural logarithm of, i.eMath.log(1 + x). ifxLess than- 1To return toNaN.
  • Math.log10(x)Return to10At the bottom of thexThe logarithm. ifxLess than0, the returnNaN.
  • Math.log2(x)Return to2Log base of x. If x is less than0, the returnNaN
  • Math.sinh(x)Hyperbolic sine of x
  • Math.cosh(x)Return x hyperbolic cosines
  • Math.tanh(x)Return hyperbolic tangent of X
  • Math.asinh(x)Inverse Hyperbolic Sine of X
  • Math.acosh(x)Return the inverse hyperbolic cosine of X
  • Math.atanh(x)Return inverse hyperbolic tangent of X

7. Exponential operators

ES2016 has a new index operator (**).

2六四风波2 / / 4
2六四风波3 / / 8
Copy the code

One of the characteristics of this operator is the right join, rather than the usual left join. When multiple exponential operators are used together, they are evaluated from the far right.

// Equivalent to 2 ** (3 ** 2)
2六四风波3六四风波2
/ / 512
Copy the code

In the above code, the second exponential operator is evaluated first, not the first.

The exponential operator can be combined with the equal sign to form a new assignment operator (**=).

let a = 1.5;
a **= 2;
// a = a * a;

let b = 4;
b **= 3;
// the same as b = b * b * b;
Copy the code

BigInt data type

1. Introduction

JavaScript saves all numbers as 64-bit floating-point numbers, which imposes two major limitations on the representation of values.

One is that values are only accurate to 53 binary bits (equivalent to 16 decimal bits), integers beyond which JavaScript cannot accurately represent them, making JavaScript unsuitable for precise scientific and financial calculations.

The second value is greater than or equal to 2 to the power of 1024, which JavaScript cannot represent, and will return Infinity.

// If the value exceeds 53 bits, the accuracy cannot be maintained
Math.pow(2.53) = = =Math.pow(2.53) + 1 // true

// A value greater than 2 to the power of 1024 cannot be expressed
Math.pow(2.1024) // Infinity
Copy the code

ES2020 addresses this problem by introducing a new data type, BigInt (large integer), which is ECMAScript’s eighth data type. BigInt is only used to represent integers. There is no limit on the number of digits.

const a = 2172141653n;
const b = 15346349309n;

// BigInt can keep accuracy
a * b // 33334444555566667777n

// Ordinary integers cannot maintain accuracy
Number(a) * Number(b) / / 33334444555566670000
Copy the code

To distinguish BigInt from Number, data of type BigInt must be suffixed with n.

1234 // An ordinary integer
1234n // BigInt

// The BigInt operation
1n + 2n // 3n
Copy the code

BigInt can also be represented in a variety of bases, all with the suffix n.

0b1101n / / binary
0o777n / / octal
0xFFn // Hexadecimal
Copy the code

BigInt and plain integers are two different values, and they are not equal.

42n= = =42 // false
Copy the code

Typeof operator returns BigInt for data of type BigInt.

typeof 123n // 'bigint'
Copy the code

BigInt can use a negative sign (-), but not a positive sign (+) because it conflicts with ASM.js.

-42n / / right
+42n / / an error
Copy the code

JavaScript previously could not compute the factorial of 70 (i.e., 70!). , because it exceeds the precision that can be expressed.

let p = 1;
for (let i = 1; i <= 70; i++) {
  p *= i;
}
console.log(p); / / 1.197857166996989 e+100
Copy the code

Now that we support large integers, we can calculate. Browser developer tools run the following code, OK.

let p = 1n;
for (let i = 1n; i <= 70n; i++) {
  p *= i;
}
console.log(p); / / 11978571... 00000000n
Copy the code

2. BigInt object

JavaScript natively provides BigInt objects that can be used as constructors to generate values of type BigInt. The conversion rules are basically the same as for Number(), which converts other types of values to BigInt.

BigInt(123) // 123n
BigInt('123') // 123n
BigInt(false) // 0n
BigInt(true) // 1n
Copy the code

The BigInt() constructor must have arguments that can normally be converted to numeric values.

new BigInt(a)// TypeError
BigInt(undefined) //TypeError
BigInt(null) // TypeError
BigInt('123n') // SyntaxError
BigInt('abc') // SyntaxError
Copy the code

In particular, notice that the string 123n cannot be parsed to Number, so an error is reported.

An error is also reported if the argument is a decimal.

BigInt(1.5) // RangeError
BigInt('1.5') // SyntaxError
Copy the code

The BigInt Object inherits two instance methods of Object.

  • BigInt.prototype.toString()
  • BigInt.prototype.valueOf()

The BigInt pair also inherits an instance method of the Number object.

  • BigInt.prototype.toLocaleString()

In addition, three static methods are provided.

  • BigInt.asUintN(width, BigInt)Given theBigIntto0Between 2 to the width to the minus 1.
  • BigInt.asIntN(width, BigInt)Given theBigIntConvert to the corresponding value between -2^width-1^ and 2^width-1^ -1.
  • BigInt.parseInt(string[, radix]): similar toNumber.parseInt()Convert a string to a specified baseBigInt.
const max = 2n* * (64n - 1n) - 1n;

BigInt.asIntN(64, max)
// 9223372036854775807n
BigInt.asIntN(64, max + 1n)
// -9223372036854775808n
BigInt.asUintN(64, max + 1n)
// 9223372036854775808n
Copy the code

In the code above, Max is the maximum that a 64-bit signed BigInt can represent. If you add 1n to this value, bigint.asintn () will return a negative value because the new bit will be interpreted as a sign bit. The bigint.asuintn () method returns the result correctly because it has no sign bits.

If the number of bits specified by bigint.asintn () and bigint.asuintn () is smaller than the number itself, then the bits in the header are discarded.

const max = 2n* * (64n - 1n) - 1n;

BigInt.asIntN(32, max) // -1n
BigInt.asUintN(32, max) // 4294967295n
Copy the code

In the above code, Max is a 64-bit BigInt. If converted to 32 bits, the first 32 bits will be discarded.

Here is an example of bigint.parseint ().

// number.parseint () vs. bigint.parseint ()
Number.parseInt('9007199254740993'.10)
/ / 9007199254740992
BigInt.parseInt('9007199254740993'.10)
// 9007199254740993n
Copy the code

In the code above, the Number. ParseInt method returns an inaccurate result because the significant Number exceeds the maximum value, while bigint. parseInt correctly returns the corresponding BigInt.

For binary arrays, BigInt has two new types: BigUint64Array and BigInt64Array, both of which return 64-bit BigInt. DataView object instance methods DataView. Prototype. GetBigInt64 () and DataView. Prototype. GetBigUint64 (), returns is BigInt.

3. Conversion rules

BigInt can be converted to booleans, numbers, and strings using Boolean(), Number(), and String() methods.

Boolean(0n) // false
Boolean(1n) // true
Number(1n)  / / 1
String(1n)  / / "1"
Copy the code

In the code above, notice the last example where the suffix n disappears when converted to a string.

Also, take the inverse operator (!) BigInt can also be converted to a Boolean.

!0n // true
!1n // false
Copy the code

4. Math

In mathematics, the binary operators +, -, *, and ** of BigInt behave the same as Number. The division operation/removes the decimal part and returns an integer.

9n / 5n
// 1n
Copy the code

Almost all numeric operators can be used in BigInt, with two exceptions.

  • Unsigned right shift operator>>>
  • Unary positive operator+

The above two operators will return an error when used with BigInt. The former is because the >>> operator is unsigned, but BigInt is always signed, making the operation meaningless and exactly equivalent to the right shift operator >>. The latter is because the unary + operator always returns Number in asm.js, and in order not to break asM.js +1n will return an error.

BigInt cannot be mixed with ordinary values.

1n + 1.3 / / an error
Copy the code

Error: Error: Error: Error: Error: error: error: error: error: error: error: error: error: error: error: error For example, if (2n**53n + 1n) + 0.5 returns BigInt, the 0.5 fraction will be lost. If the Number type is returned, the effective accuracy is only 53 bits, resulting in a decrease in accuracy.

For the same reason, if a library function takes a parameter of type Number and returns a BigInt, an error is reported.

// This is not the case
Math.sqrt(4n) / / an error

// The correct way to write
Math.sqrt(Number(4n)) / / 2
Copy the code

SQRT (BigInt, Number); SQRT (BigInt, Number); SQRT (BigInt, Number);

Asm, js, | 0 behind a numerical returns a 32-bit integer. According to cannot be mixed with Number type operation rules, BigInt if operation complains with | 0.

1n | 0 / / an error
Copy the code

5. Other operations

The Boolean value of BigInt is the same as that of Number, that is, 0n is returned to false and other values are returned to true.

if (0n) {
  console.log('if');
} else {
  console.log('else');
}
// else
Copy the code

In the above code, 0n corresponds to false, so else clause is entered.

Comparison operators (such as >) and equality operators (==) allow BigInt to be mixed with other types of values because there is no loss of accuracy.

0n < 1 // true
0n < true // true
0n= =0 // true
0n= =false // true
0n= = =0 // false
Copy the code

When BigInt is mixed with a string, it is converted to a string before being evaluated.

' ' + 123n / / "123"
Copy the code