JavaScript 如何将大整数转换为字符串?

17
我试图在JavaScript中将以下大整数转换为字符串,但没有成功。我的目标是最终得到'582235852866076672'。
var foo = 582235852866076672;
console.log(foo); // 582235852866076700

var baz = "'" + 582235852866076672 + "'";
console.log(baz); // '582235852866076700'

var emptyString = 582235852866076672+'';
console.log(emptyString); // 582235852866076700

var n = foo.toString();
console.log(n); // 582235852866076700

我认为这个数字太大了,结果失去了精度。 我尝试使用bigint库,但没有成功:

var bigint = require('bigint');
var bigintLibrary = bigint(582235852866076672).toString();
console.log(bigintLibrary); //582235852866076700

bigint库中的toSting方法说明:

“按照请求的进制将bigint实例打印为字符串。”

感谢所有的帮助和评论。谢谢。


数字从哪里来?你所说的数字不能作为普通的JavaScript数字存在,因此源很重要。 - Aaron Dufour
@AaronDufour,这个数字是通过POST请求的参数传递过来的。我已经尝试了var jsonString = JSON.stringify(582235852866076672);但是结果是一样的console.log(jsonString); // 582235852866076700。 - srm
你需要手动解析这些参数。除非客户端能够将其作为字符串而不是数字传递?一旦库将其解析为数字,精度就会丢失,所以当它到达你的代码时已经太晚了。 - Aaron Dufour
4个回答

12

从2019年开始,您可以使用内置的BigInt和BigInt字面量,首先执行如下操作:

// Cast to BigInt:
var result = BigInt("1234567801234567890");
result = BigInt(1234567801234567890);

// Or use BigInt literal directly (with n suffix).
result = 1234567801234567890n

然后使用内置的toString方法:

console.log('my BigInt is', result.toString());

请查看MDN上的文档


10

这是一个精度问题 - 你所得到的数字 (582235852866076672) 超过了 JavaScript 可以表示的最大数字,即 2^53 或 9007199254740992


1
你需要像我一样在它周围加上引号。在JavaScript中,你不能直接表示比最大尺寸更大的数字——它会被截断(就像你现在看到的那样)。 - Jeff Hubbard
1
谢谢。我看到了。我的疑问更多的是如何将整数582235852866076672转换为字符串'582235852866076672',数据以整数形式输入,我必须将其转换为字符串,不能仅仅添加引号。 - srm
实际上,这似乎是一个精度问题——也就是说,JavaScript 无法准确地表示该数字。该数字大于2^53,这是 JavaScript 可表示的最大数字。 - Jeff Hubbard
看起来在数据到达 JavaScript 端之前,我需要将其转换为字符串进行操作。 - srm
1
澄清一下,在JavaScript中,2^53是可表示的最大整数。在JavaScript中可表示的最大数字为2^1024 - Aaron Dufour
显示剩余3条评论

3

2
似乎虽然有三个答案,但只有一个答案实际上回答了这个问题,但它并不是被接受的答案...

这是我的答案:

首先,您不需要导入BigInt库... BigInt已内置于JavaScript中(至少现在是这样),您可以通过调用函数BigInt(...)或在数字末尾添加'n'来访问它:45625625443n

BigInt可以保存非常大的数字,据我所知,限制为10亿位 1。这意味着您可以保存约1×10109的整数,在大多数情况下,您可能不需要如此大的整数。

如上所示,您可以使用构造函数(BigInt(...))或在末尾添加'n'(45625625443n)来构建BigInt 2

当使用构造函数时,参数可以是以下任何一种(但是正如评论中jmrk所说,将数字放入构造函数中时,它仍然会失去精度,因此不要使用数字):

// String
   BigInt("1234567890987654321234567890")
   // -> 1234567890987654321234567890n

// Number
   BigInt(1234567890987654321234567890)
   // -> 1234567890987654297979715584n
   /* As said above, using a number in the constructor may lose precision,
      as seen here just input a string or use the n */

// BigInt
   BigInt(1234567890987654321234567890n)
   // -> 1234567890987654321234567890n

// Boolean
   BigInt(false) // 0n
   BigInt(true)  // 1n

在操作中不能混合类型。您无法使用普通的JavaScript数字执行任何普通操作,必须首先将它们转换为BigInts。

let big_int_number = BigInt(135445264365246564)

// Incorrect
big_int_number + 1365

// Correct (either one)
big_int_number + 1365n
big_int_number + BigInt(1365)

最后来回答这个实际问题:要将 BigInt 转换为字符串,您只需要使用内置的方法3
let big_int_number = BigInt("135445264365246564")
// or
let big_int_number = 135445264365246564n

// Using BigInt.prototype.toString()
let string_version = big_int_number.toString()


/* You probably don't need this method,
   but I just put it here just because */

// Using BigInt.prototype.toLocaleString()
let string_version = big_int_number.toLocaleString()

这适用于两种构建方式...

let n_constructed = 1234567890987654321234567890n
    n_constructed.toString()       // 1234567890987654321234567890n
    n_constructed.toLocaleString() // 1234567890987654321234567890n

let constructered = BigInt("1234567890987654321234567890")
    constructered.toString()       // 1234567890987654321234567890n
    constructered.toLocaleString() // 1234567890987654321234567890n

如果您对 BigInt 有任何疑问,请访问 MDN 的 BigInt 参考页面

2
你的例子实际上是错误的。BigInt(1234567890987654321234567890)会得到1234567890987654297979715584n,而BigInt(135445264365246564)会得到135445264365246560n(注意末尾的...60n)。这正是预期的工作方式,因为你使用的数字无法保持那么高的精度。通常不建议使用BigInt(123)表示法,因为存在可扩展性问题;请使用123n - jmrk
谢谢你让我知道!当我测试我给出的例子时,我猜我没有看到它们不起作用(或者没有看到输出与输入不同)...我会编辑我的答案,包括你说的内容。 - Jacob Hornbeck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接