BigInteger数字未传递到JSON对象中。

huangapple go评论63阅读模式
英文:

BigInteger numbers not passing to JSON object

问题

以下是您要翻译的内容:

"当我像这样添加JSON响应行时,我会收到500错误。

// 将响应数据转发给客户端
res.json({'totalSupply':totalSupply});

res.json(responseObj)

都失败。我在这里漏掉了什么?"

英文:

I have a smart contract I am interacting with but I cannot seem to form a proper JSON object using these variables. I have been able to pull the data and log it, I've even been able to pull other data in other functions without issue but these numbers are returning an error when attempting to respond using these values.

As expected this code works:

app.get('/stats', async (req, res) => {
try {
  res.json({'maxSupply':1});
} catch (error) {
  // Handle any errors that occur during the stats
  res.status(500).send("500 Error:");
}

And this code works:

app.get('/stats', async (req, res) => {
try {
  const totalSupply = await contract.methods.totalSupply().call();
  console.log("Total Supply: ",totalSupply)
  const remainingSupply = await contract.methods.remainingSupply().call();
  console.log("Remaining Supply: ",remainingSupply)

  // Create the high-level response object
  const responseObj = {
    totalSupply: Number(totalSupply),
    remainingSupply: Number(remainingSupply)
  };
  // Forward the response data to the client
  console.log("JSON", responseObj);

and the resulting output is:

Server running on port 8080
Total Supply:  189880000000000000n
Remaining Supply:  810120000000000000n
JSON {
  totalSupply: 189880000000000000,
  remainingSupply: 810120000000000000
}

When I add the json response line in like this I get a 500 error.

// Forward the response data to the client
res.json({'totalSupply':totalSupply}); 

and

res.json(responseObj) 

both fail. What am I missing here?

答案1

得分: 0

在使用JSON序列化大数字时,您可能会遇到问题,特别是当数字超过IEEE754浮点安全十进制数的限制[1]时。

在这种情况下,在JavaScript中:

> 189880000000000000 > Number.MAX_SAFE_INTEGER
true

数字末尾的n表示它是原生的BigInt值[2]。这些是任意大小的整数。

您不能使用JSON本地序列化BigInt。

JSON.stringify({ a: 1n })
Uncaught TypeError: Do not know how to serialize a BigInt

JSON只能使用IEEE标准来序列化数字。

您可以将数字序列化为字符串(String(18988n)),然后使用BigInt(s)将其从字符串强制转换为BigInt。

另一个选择是使用JSON之外的不同编码,例如CBOR [3]。

除了无法序列化之外,使用IEEE浮点数时,您还无法保证金额会执行正确的算术运算,即对于分数(但在使用超过MAX_SAFE_INTEGER的数字时也有整数情况)。

> 0.1 + 0.2
0.30000000000000004

因此,如果确保您的数字是整数,通常可能更喜欢使用BigInt。

英文:

You're going to get issues serializing large numbers like this with JSON, specifically ones that exceed the IEEE754 floating point safe-decimal amount [1].

In this case, in Javascript:

> 189880000000000000 > Number.MAX_SAFE_INTEGER
true

The n at the end of the number indicates that it is a native BigInt value. [2]. These are integer-only numbers of arbitrary size.

You cannot natively serialize BigInt with JSON.

JSON.stringify({ a: 1n })
Uncaught TypeError: Do not know how to serialize a BigInt

JSON can only use the IEEE standard for serializing numbers.

You can serialize the number as a string (String(18988n)) and then coerce it from a string to a BigInt with BigInt(s).

Another option is to use a different encoding from JSON e.g. CBOR [3].

In addition to the inability to serialize, with IEEE floating point numbers you also cannot guarantee that the amounts will perform arithmetic correctly i.e. for fractions (but there are also whole-integer-cases when using numbers above MAX_SAFE_INTEGER)

> 0.1 + 0.2
0.30000000000000004

so you may generally wish to prefer BigInt, if your numbers are indeed guaranteed to be integers.

huangapple
  • 本文由 发表于 2023年6月18日 23:51:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76501359.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定