1、JS超过Number最大值如何处理?
在 JavaScript 中,Number 类型的最大值是 1.7976931348623157e+308,这个值可以通过 Number.MAX_VALUE 获取。这个最大值是由 JavaScript 的 Number 类型使用的 IEEE 754 双精度浮点数格式 决定的。
为什么 Number 的最大值是 1.7976931348623157e+308?
-
IEEE 754 双精度浮点数格式:
- JavaScript 的
Number类型使用 IEEE 754 标准的 64 位双精度浮点数格式来表示数字。 - 这 64 位被分为以下三部分:
- 1 位符号位:表示数字的正负(0 表示正数,1 表示负数)。
- 11 位指数位:表示数字的指数部分。
- 52 位尾数位:表示数字的有效精度部分。
- JavaScript 的
-
指数位的范围:
- 11 位指数位可以表示的范围是
0到2047(即2^11 - 1)。 - 为了支持正负指数,IEEE 754 使用 偏移值(bias),偏移值为
1023。因此,实际指数范围是-1022到+1023。 - 最大指数值是
1023。
- 11 位指数位可以表示的范围是
-
最大值的计算:
- 当指数位为最大值
1023时,表示的数字是:1.1111111111111111111111111111111111111111111111111111(二进制) × 2^1023 - 转换为十进制后,这个值约为
1.7976931348623157e+308。
- 当指数位为最大值
-
为什么不是更大的值?:
- 如果指数位超过
1023,IEEE 754 会将其解释为 特殊值,例如Infinity(无穷大)。 - 因此,
1.7976931348623157e+308是Number类型能够表示的最大有限值。
- 如果指数位超过
Number 的最大安全整数:9007199254740991
虽然 Number 的最大值是 1.7976931348623157e+308,但 Number 类型能够精确表示的最大整数是 9007199254740991,这个值可以通过 Number.MAX_SAFE_INTEGER 获取。
为什么最大安全整数是 9007199254740991?
- IEEE 754 双精度浮点数的尾数部分有 52 位,因此可以精确表示的整数范围是:
-2^53 + 1 到 +2^53 - 1 2^53 - 1的值是9007199254740991。- 超过这个范围的整数可能会丢失精度,因为尾数部分不足以精确表示这些整数。
总结:
Number的最大值是1.7976931348623157e+308,这是由 IEEE 754 双精度浮点数的指数范围决定的。Number的最大安全整数是9007199254740991,这是由尾数部分的位数决定的。- 如果需要处理更大的整数或需要更高的精度,可以使用
BigInt类型。
大数产生背景
- 1、金融行业
- 2、科学计算:计算机生成的数据可能会生成比较大的数
- 3、数据分析: 公司在做大数据计算时可能会生成比较大的数
解决方案
- 1、ES6的
Bigint数据类型const a = BigInt("111111111111111111111111111111111111111111111111111111111111"); // 或 const a = 111111111111111111111111111111111111111111111111111111111111n const b = BigInt("111111111111111111111111111111111111111111111111111111111111"); const c = a + b; // 222222222222222222222222222222222222222222222222222222222222n注意:以下这种写法是错误的;
BigInt里参数如果还是数字,那将会导致数字超过最大值,导致生成的Bigint值不准确const a = BigInt(111111111111111111111111111111111111111111111111111111111111); // 111111111111111115398901787910723492567390900178539566333952n 错误写法 - 2、第三方库
decimal.js库等 - 3、字符串计算
function addLargeNumbers(num1, num2) {
// 将两个数字转换为字符串,方便逐位操作
let str1 = num1.toString();
let str2 = num2.toString();
// 补齐较短的数字,前面补零
const maxLength = Math.max(str1.length, str2.length);
str1 = str1.padStart(maxLength, '0');
str2 = str2.padStart(maxLength, '0');
let carry = 0; // 进位
let result = ''; // 最终结果
// 从最低位(字符串的末尾)开始逐位相加
for (let i = maxLength - 1; i >= 0; i--) {
const digit1 = parseInt(str1[i], 10); // 获取当前位的数字
const digit2 = parseInt(str2[i], 10); // 获取当前位的数字
// 计算当前位的和(包括进位)
const sum = digit1 + digit2 + carry;
const digitSum = sum % 10; // 当前位的值
carry = Math.floor(sum / 10); // 计算进位
// 将当前位的值拼接到结果中
result = digitSum.toString() + result;
}
// 如果最后还有进位,拼接到结果前面
if (carry > 0) {
result = carry.toString() + result;
}
return result;
}
// 示例用法
const num1 = '123456789012345678901234567890';
const num2 = '987654321098765432109876543210';
const sum = addLargeNumbers(num1, num2);
console.log(sum); // 输出: 1111111110111111111011111111100
- 4、限制用户输入比较大的值
2、如何解决页面请求接口大规模并发问题
2.1、请求队列
在这里队列分为两种。1、全部定义好队列后再发送请求. 2、定义一个空队列,每当想队列添加值的时候再发送请求
2.1.1 全部定义好队列后再发送请求
实现细节:
- 1、定义好一个请求队列
- 2、循环最大并发数,每循环一次就从队列头部shift出一条数据。拿到数据并执行发送请求
sendAjax - 3、在
sendAjax有结果时(finally),如果队列中还有数据,则继续从队列头部shift出一条数据。拿到数据并执行发送请求sendAjax - …
2.1.2 定义一个空队列,每当想队列添加值的时候再发送请求实现细节:
- 1、定义一个空队列、定义当前正在执行的并发数
- 2、每执行
addQueue则将数据push到队列;并执行队列函数 - 3、在执行队列函数中判断队列是否还有数据?当前正在执行的并发数 是否 小于 最大并发数?
- 是: 队列头部shift出一条数据。拿到数据并执行发送请求
sendAjax
- 是: 队列头部shift出一条数据。拿到数据并执行发送请求
- 4、在
sendAjax有结果时(finally),执行步骤 3 - …
class ReqestQueue {
queues = [] // 请求队列 (队列中放入返回Promise函数)
maxConcurrent = 1 // 最大并发数
currentConcurrent = 0 // 当前并发数
constructor (maxConcurrent) {
this.maxConcurrent = maxConcurrent
}
// 增加队列
addQueue ({
request, data }) {
return new Promise((resolve, reject) => {
this.queues.push({
request, data, resolve, reject })
this.processQueue()
})
}
// 执行队列
processQueue () {
if (this.currentConcurrent >= this.maxConcurrent || this.queues.length <= 0) return false
const queue = this.queues.shift()
this.sendAjax(queue)
}
// 发送ajax
sendAjax ({
request, data, resolve, reject }) {
this.currentConcurrent++
request(data)
.then((res) => {
resolve(res)
})
.catch((err) => {
reject(err)
})
.finally(() => {
this.currentConcurrent--
this.processQueue()
})
}
}
// 请求实例
const reqestQueue = new ReqestQueue(3)
for (let i = 0; i < 10; i++) {
reqestQueue.addQueue

最低0.47元/天 解锁文章
3万+

被折叠的 条评论
为什么被折叠?



