ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

JS bigint 数据类型的学习

2020-09-28 18:32:32  阅读:315  来源: 互联网

标签:const 数据类型 bigint Number JS BigInt max 10n 2n


BigInt 可能会成为自 ES2015 引入 Symbol 之后,增加的第一个新的内置类型。并且 BigInt 类型在 TypeScript3.2 版本被内置。。。本篇将简单记录下BigInt

js的第七种基本数据类型BigInt

js 采用双精度浮点数,这也导致了精度有限的问题。在 js 中,Number 基本类型可以精确表示的最大整数是 2^53。因此早期会有这如下的“bug”:

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

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

max1 === max2 //true

 

为了解决这个限制,BigInt出现在了ECMAScript标准中。

let max = BigInt(Number.MAX_SAFE_INTEGER);

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

max1 === max2 // false

 

介绍

BigInt 可以表示任意大的整数。

创建

语法:

BigInt(value);

其中参数:

  value: 创建对象的数值。可以是字符串或者整数。

注意, BigInt() 不是构造函数,因此不能使用 new 操作符。

除了通过BigInt构造函数,我们还可以通过在一个整数字面量后面加 n 的方式定义一个 BigInt ,如:10n

例:

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

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

类型判断

我们可以通过typeof操作符来判断是否为BigInt类型(返回字符串"bigint"),如

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

同样的,我们也可以用最通用的Object.prototype.toString方法(返回字符串"[object BigInt]"

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

运算

以下操作符可以和 BigInt 一起使用: +*-**% 。除 >>> (无符号右移)之外的 位操作 也可以支持。(因为 BigInt 都是有符号的 >>> (无符号右移)不能用于 BigInt)。

为了兼容 asm.js ,.BigInt 不支持单目 (+) 运算符。

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

当使用 BigInt 时,带小数的运算会被取整。

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

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

方法

BigInt.asIntN()

将 BigInt 值转换为一个 -2^width - 1 与 2^(width-1) - 1 之间的有符号整数。

语法:

BigInt.asIntN(width, bigint);

如:

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

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

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

BigInt.asUintN()

将一个 BigInt 值转换为 0 与 2^width-1 之间的无符号整数。

语法:

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和Number

BigInt 和 Number 不是严格相等的,但是宽松相等的。

10n === 10
// false

10n == 10
// true

Number 和 BigInt 可以进行比较。

1n < 2;        // true

2n > 1;        // true

2 > 2;        // false

2n > 2;        // false

2n >= 2;    // true

两者也可以混在一个数组内并排序。

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 在需要转换成 Boolean 的时表现跟 Number 类似:如通过 Boolean 函数转换;用于 Logical Operators ||, &&, 和 ! 的操作数;或者用于在像 if statement 这样的条件语句中。

它在某些方面类似于 Number ,但是也有几个关键的不同点:不能用与 Math 对象中的方法;不能和任何 Number 实例混合运算,两者必须转换成同一种类型。在两种类型来回转换时要小心,因为 BigInt 变量在转换成 Number 变量时可能会丢失精度。

不允许隐式类型转换

因为隐式类型转换可能丢失信息,所以不允许在bigint和 Number 之间进行混合操作。当混合使用大整数和浮点数时,结果值可能无法由BigInt或Number精确表示。

如:

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

BigInt和String

难免会遇到数字和字符串的转换,BigInt也不例外,不过可惜的是BigInt转为String时,其标志性的n会被省略,如

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

因此也导致以下情况:

// 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

零值

BigInt 没有 Number 的正零(+0)和负零(-0)之分。因为 BigInt 表示的是整数

无穷和NaN判断

很有趣的现象

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

由此我们可以看出isFinite()和Number.isFinite()、isNaN()和Number.isNaN()的区别:isFinite(val)/isNaN(val)的工作机制都是讲参数值val转为数值后再进行比较判断,而Number.isFinite(val)/Number.isNaN(val)则可以理解为直接简单粗暴的变量全等判断(val === Infinity/val === NaN

兼容

如图,兼容情况并不是很好。并且转换BigInt是一个极其复杂的过程,这会导致严重的运行时性能损失。直接polyfill BigInt也是不可能的,因为该提议改变了几个现有操作符的行为。目前,更好的选择是使用JSBI库,它是BigInt提案的纯JS实现,访问地址>>

使用如下:

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

BigInt 类型在 TypeScript3.2 版本被内置,

在TypeScript中,BigInt 和 Number 都是有表示数字的意思,但是实际上两者类型是不同的:

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'.

除了类型定义,TypeScript 中 BigInt 其他使用方法同 ES。

 

标签:const,数据类型,bigint,Number,JS,BigInt,max,10n,2n
来源: https://www.cnblogs.com/MrZhujl/p/13746232.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有