BigInt, the seventh basic data type of js

BigInt may become the first new built-in type added since the introduction of Symbol in ES2015. And the BigInt type is built-in in TypeScript 3.2 version. . . This article will briefly record BigInt

BigInt, the seventh basic data type of js

js uses 64-bit double-precision floating point numbers , which also leads to the problem of limited precision. In js, the largest integer that the Number primitive type can accurately represent is 2^53. Therefore, there will be the following "bugs" in the early days:

const max = Number.MAX_SAFE_INTEGER;	// 最大安全整数

let max1 = max + 1
let max2 = max + 2

max1 === max2 //true

To address this limitation, BigInt appeared in the ECMAScript standard.

const max = BigInt(Number.MAX_SAFE_INTEGER);

let max1 = max + 1n
let max2 = max + 2n

max1 === max2 // false

introduce

BigInt can represent arbitrarily large integers.

create

grammar:

BigInt(value);

Among the parameters:

  • value: The value of the created object. Can be a string or an integer.

Note that BigInt() is not a constructor, so the new operator cannot be used, similar to Symbol().

In addition to the BigInt constructor, we can also define a BigInt by adding n after an integer literal, such as: 10n.

example:

const valA = 10n;
const valB = BigInt(10);

console.log(valA === valB);	 // true

Type judgment

We can use the typeof operator to determine whether it is a BigInt type (returning a string "bigint"), such as

typeof 1n === 'bigint'; // true
typeof BigInt('1') === 'bigint'; // true

Similarly, we can also use the most common Object.prototype.toString method (returning a string "[object BigInt]")

Object.prototype.toString.call(10n) === '[object BigInt]';	// true

Operation

The following operators can be used with BigInt: +, *, -, **, %. Bit operations other than >>> (unsigned right shift) are also supported. (Because BigInt is signed >>> (unsigned right shift) cannot be used for BigInt).

In order to be compatible with asm.js, BigInt does not support the unary ( +) operator. If so, +1nan error will be reported: VM151:1 Uncaught TypeError: Cannot convert a BigInt value to a number. But self-increasing and self-decreasing can be used, such as let num = 1n; num++.

const previousMaxSafe = BigInt(Number.MAX_SAFE_INTEGER);
// 9007199254740991n

const maxPlusOne = previousMaxSafe + 1n;
// 9007199254740992n
 
const theFuture = previousMaxSafe + 2n;
// 9007199254740993n, this works now!

const multi = previousMaxSafe * 2n;
// 18014398509481982n

const subtr = multi – 10n;
// 18014398509481972n

const mod = multi % 10n;
// 2n

const bigN = 2n ** 54n;
// 18014398509481984n

bigN * -1n
// –18014398509481984n

When using BigInt, operations with decimals are rounded.

const expected = 4n / 2n;
// 2n

const rounded = 5n / 2n;
// 2n, not 2.5n

method

BigInt.asIntN()

Converts a BigInt value to a signed integer between -2^width - 1 and 2^(width-1) - 1.

grammar:

BigInt.asIntN(width, bigint);

like:

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

BigInt.asIntN(64, max);	// 9223372036854775807n

BigInt.asIntN(64, max + 1n);	// -9223372036854775807n
// negative because of overflow
BigInt.asUintN()

Converts a BigInt value to an unsigned integer between 0 and 2^width-1.

grammar:

BigInt.asUintN(width, bigint);
const max = 2n ** 64n - 1n;

BigInt.asUintN(64, max);
// 18446744073709551615n

BigInt.asUintN(64, max + 1n);
// 0n
// zero because of overflow

BigInt and Number

BigInt and Number are not strictly equal, but are loosely equal.

10n === 10
// false

10n == 10
// true

Number and BigInt can be compared.

1n < 2;		// true

2n > 1;		// true

2 > 2;		// false

2n > 2;		// false

2n >= 2;	// true

Both can also be mixed in an array and sorted.

const mixed = [4n, 6, -12n, 10, 4, 0, 0n];	// [4n, 6, -12n, 10, 4, 0, 0n]

mixed.sort();	// [-12n, 0, 0n, 10, 4n, 4, 6]

BigInt behaves like Number when it needs to be converted to Boolean: such as conversion through Boolean functions; used as operands in Logical Operators ||, &&, and ; or used in conditional statements like this.!if statement

It is similar to Number in some ways, but there are several key differences: it cannot be used with methods in the Math object; it cannot be mixed with any Number instance, and both must be converted to the same type. Be careful when converting back and forth between the two types because BigInt variables may lose precision when converted to Number variables.

Implicit type conversions are not allowed

Mixing operations between BigInt and Number are not allowed because implicit type conversions may lose information. When mixing large integers and floating point numbers, the resulting value may not be accurately represented by a BigInt or Number.

like:

10n + 1;	// Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
Math.max(2n, 4n, 6n);    // TypeError...

BigInt and String

It is inevitable to encounter the conversion of numbers and strings, and BigInt is no exception. However, it is a pity that when BigInt is converted to String, its iconic characters will nbe omitted, such as

String(10n);	// '10'
'' + 11n;	// '11'

This also leads to the following situations:

// array
let arr = [1, 2, 3, 4, 5];

arr[2] === arr[2n];	// true

// object
let obj = {
    
    
  '1': '1',
  '2': '2',
  '3': '3',
  '4': '4'
};

obj['1'] === obj[1n];		// true

zero value

BigInt does not have Number's positive zero ( +0) and negative zero ( -0). Because BigInt represents an integer

Infinity and NaN judgment

Very interesting phenomenon

isFinite(10n);	// Uncaught TypeError: Cannot convert a BigInt value to a number
Number.isFinite(10n);	// false

isNaN(10n);	// Uncaught TypeError: Cannot convert a BigInt value to a number
Number.isNaN(10n);	// false

From this we can see the difference between isFinite()and Number.isFinite()and : The working mechanism isNaN()of / is to convert the parameter value val into a numerical value before comparison and judgment, while / can be understood as a direct, simple and crude variable congruence judgment ( / )Number.isNaN()isFinite(val)isNaN(val)Number.isFinite(val)Number.isNaN(val)val === Infinityval === NaN

compatible

https://caniuse.com/?search=BigInt
(Compatible until 2022.05.11)
bigint compatible

As shown in the picture, the compatibility is not very good (Chrome and Android are okay). And converting BigInt is an extremely complex process, which can cause serious runtime performance losses. Direct polyfilling of BigInt is also not possible, as the proposal changes the behavior of several existing operators. Currently, a better option is to use the JSBI library, which is a pure JS implementation of the BigInt proposal and can be accessed at >> .

Use as follows:

import JSBI from './jsbi.mjs';

const max = JSBI.BigInt(Number.MAX_SAFE_INTEGER);
console.log(String(max));
// → '9007199254740991'
const other = JSBI.BigInt('2');
const result = JSBI.add(max, other);
console.log(String(result));
// → '9007199254740993'

TypeScript

The BigInt type is built-in in TypeScript 3.2 version,

In TypeScript, BigInt and Number both mean to represent numbers, but in fact the two types are different:

declare let valA: number;
declare let valB: bigint;

valA = valB; // error: Type 'bigint' is not assignable to type 'number'.
valB = valA; // error: Type 'number' is not assignable to type 'bigint'.

Except for type definition, other usage methods of BigInt in TypeScript are the same as those in ES.


Related Links

Guess you like

Origin blog.csdn.net/qq_24357165/article/details/103058141