javascript处理int64

2,864 阅读5分钟

javaScript在处理大整数时面临着挑战。特别是,JavaScript 原生不支持 64 位整数 (int64)。在许多情境下,这可能不是问题,但当我们需要表示超过 image.png 的数字,例如在处理数据库主键或大数据集时,这个局限性就显得尤为明显。

JavaScript 的数字限制

所有 JavaScript 中的数字都是 IEEE-754 双精度浮点数,这意味着它们有一个固定的大小和精度。因此,JavaScript 可以准确表示的整数范围是 image.png 。超出这个范围,整数可能会丢失精度。

常见的情境

在日常开发中,您可能会遇到需要处理大整数的几种情况:

  • 数据库ID: 很多数据库系统,尤其是分布式数据库,使用64位整数作为唯一标识符或ID。当这些ID被返回给前端或通过API进行交互时,JavaScript需要能够准确地处理这些大整数。
  • 游戏开发: 在某些类型的游戏,如策略游戏或经济模拟游戏中,玩家可能会积累大量的资源或货币。这些数字可能会迅速增长,超过普通整数的表示范围。
  • 第三方API: 当与第三方服务或API进行交互时,这些服务可能会返回64位或更大的整数。为了确保数据的准确性,前端和后端都需要能够处理这些大整数。
  • 金融计算: 在金融行业,尤其是与货币和投资相关的应用,需要进行高精度的计算。即使一个数值在正常范围内,其计算结果可能会超过JavaScript能够准确表示的范围。

解决方案

使用字符串

将大整数作为字符串处理是最简单的方法。许多数据库和 API 已经提供了这种选择,因为它们知道 JavaScript 客户端的这一局限性。

例如,数据库 ID 可以作为字符串而不是数字返回:

{
    "id": "12345678901234567890",
    "name": "Example"
}

这样,您可以安全地在 JavaScript 中处理此 ID,而不必担心数字精度的问题。

优点

  • 兼容所有 JavaScript 环境和 JSON 解析器。
  • 不需要额外的库或工具。

缺点

  • 不能直接进行算数操作。
  • 需要在客户端和服务器之间进行转换。

使用 BigInt

幸运的是,为了解决这个问题,ECMAScript 2020引入了一个新的原生数据类型——BigInt。它可以表示任意大小的整数,并提供了一套完整的算术运算符。使用BigInt非常简单,只需要在整数后面加一个n即可。

示例

const bigInt1 = 1234567890123456789012345678901234567890n;
const bigInt2 = BigInt("1234567890123456789012345678901234567890");

console.log(bigInt1 === bigInt2); // true

运算

BigInt支持所有常规的数学运算。

let a = 1234567890123456789012345678901234567890n;
let b = 9876543210987654321098765432109876543210n;

let sum = a + b;
let diff = a - b;

console.log(sum);
console.log(diff);

转换

要将BigInt转换为字符串,可以使用toString()方法。

let bigInt = 1234567890123456789012345678901234567890n;
let str = bigInt.toString();

console.log(str);  // "1234567890123456789012345678901234567890"

优点

  • 原生支持,不需要额外的库。
  • 可以进行算数操作。

缺点

  • 不是所有的浏览器和 JavaScript 运行时都支持。
  • 不能与常规数字混合使用。
  • JSON 规范不支持,需要进行转换。
  • 不能与常规的Number类型混合使用。

使用第三方库

对于不能使用ES2020特性或需要更多功能的项目,可以考虑使用第三方库。

BigInteger.js

BigInteger.js是一个强大的JavaScript大整数库。它提供了大整数的算术、比较、位操作等功能。

示例

var bigInt = require("big-integer");

let a = bigInt("1234567890123456789012345678901234567890");
let b = bigInt("9876543210987654321098765432109876543210");

let sum = a.add(b);
let diff = a.subtract(b);

console.log(sum.toString());
console.log(diff.toString());

long.js

long.js是另一个JavaScript库,专门用于处理64位整数。它非常适合处理数据库和系统中的64位ID。 示例

var Long = require("long");

let a = Long.fromString("1234567890123456789");
let b = Long.fromString("9876543210987654321");

let sum = a.add(b);
let diff = a.subtract(b);

console.log(sum.toString());
console.log(diff.toString());

优点

  • 在不支持 BigInt 的旧环境中提供了解决方案。
  • 提供了许多方便的功能,例如格式化和数学运算。

缺点

  • 需要额外的依赖。
  • 可能不如原生的 BigInt 高效。

注意事项

  • 当在浏览器中使用BigInt或第三方库时,确保目标浏览器支持所需的特性。
  • 对于需要交互的大整数(例如在API中),通常建议使用字符串格式进行传输,以避免在不同的系统和语言之间的不兼容性。
  • 在使用BigInt进行计算时,需要注意性能问题,尤其是在进行大量计算时。