用于维护小数精度的JSON.parse()的替代方法?

use*_*495 4 javascript typescript

我正在调用JSON.parse()解析一个小小数的JSON字符串.

解析后不保持小数的精度.例如,3.1e-7返回一个值而不是实际的十进制数.

如何在保持小数精度的同时在ng2 +中反序列化JSON字符串?

UPDATE

我正在考虑从字符串中映射出值,然后在JSON.parse()之后手动将值设置为对象,但是当我将不同的小十进制数设置为属性值时,会出现相同的数字格式.那么这个问题不一定是JSON.parse()所特有的,而是一般的Javascript吗?或者JSON.parse()以某种方式以固定的方式配置属性类型?

Aux*_*aco 6

一旦通过JSON.parse传递JSON字符串,由于浮点数学的工作方式,您将失去精度.您需要将数字存储为用于存储任意精度数字对象,并且在解析之前您需要调整字符串本身.最简单的方法是使用正则表达式.JSON是一种无上下文语法,正则表达式适用于常规语法,因此警告适用:

警告:将CFG与REGEX 配对可能会导致ZALGO升级

这个正则表达式应该将JSON中的数字转换为字符串:

let stringedJSON = origJSON.replace(/:\s*([-+Ee0-9.]+)/g, ': "uniqueprefix$1"');
Run Code Online (Sandbox Code Playgroud)

但是我没有对它进行过广泛的测试,如果你有类似的键,它肯定会搞砸了data:42.

假设它工作正常,stringedJSON现在应该是这样的{"foo": "uniqueprefix0.00000017", "bar": "an actual string"}.您可以在JSON.parse不丢失精度的情况下解析它,但uniqueprefix0.00000017不是您想要的.JSON.parse可以使用额外的reviver参数调用,该参数在返回之前转换传递给它的值.您可以使用它将数据转换回有用的形式:

let o = JSON.parse(stringedJSON, (key, value) => {
  // only changing strings
  if (typeof value !== 'string') return value;
  // only changing number strings
  if (!value.startsWith('uniqueprefix')) return value;
  // chop off the prefix
  value = value.slice('uniqueprefix'.length);
  // pick your favorite arbitrary-precision library
  return new Big(value);
});
Run Code Online (Sandbox Code Playgroud)