JSON.parse()的替代方案,以保持小数精度? [英] alternative to JSON.parse() for maintaining decimal precision?

查看:41
本文介绍了JSON.parse()的替代方案,以保持小数精度?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm calling JSON.parse() to parse a JSON string which has small decimals.

解析后不保留小数位数的精度.例如,将返回类似 3.1e-7 的值,而不是实际的小数.

The precision of the decimals is not being maintained after parsing. For example, a value like 3.1e-7 is being returned instead of the actual decimal.

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

How can I deserialize a JSON string in ng2+ while maintaining decimal precision?

更新

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

I was thinking about mapping out the values from the string and then setting the values manually to the object after JSON.parse() but when I set a different small decimal number as a property value, the same number formatting occurs. So is this problem not necessarily unique to JSON.parse() but to Javascript in general? Or does JSON.parse() somehow configure property types in a fixed way?

推荐答案

通过JSON.parse传递JSON字符串后,由于用于存储任意-精度数字,那么您需要先分析字符串本身,然后再对其进行解析.最简单的方法是使用正则表达式.JSON是一种上下文无关的语法,正则表达式适用于常规语法,因此该警告适用:

As soon as you pass your JSON string through JSON.parse, you'll lose precision because of the way floating point math works. You'll need to store the number as an object designed for storing arbitrary-precision numbers, and you'll need to fiddle with the string itself before parsing it. The simplest way is with regexes. JSON is a context free grammar, and regexes work on regular grammars, so the warning applies:

警告:使用正则表达式解析CFG MAY召唤ZALGO

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

This regex should turn the numbers in your JSON into strings:

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

但是我还没有对其进行广泛的测试,如果您拥有诸如 data:42 之类的键,它肯定会搞砸了.

But I haven't tested it extensively and it definitely will screw things up if you have keys that are something like data:42.

假设它正常工作,现在 stringedJSON 应该类似于 {"foo":"uniqueprefix0.00000017","bar":实际字符串"} .您可以使用 JSON.parse 进行解析,而不会失去精度,但是 uniqueprefix0.00000017 并不是您想要的.可以使用额外的 reviver 参数调用 JSON.parse ,该参数会在返回值之前转换传递给它的值.您可以使用它来将数据转换回有用的形式:

Assuming it worked correctly, stringedJSON should now be something like {"foo": "uniqueprefix0.00000017", "bar": "an actual string"}. You can parse this with JSON.parse without losing precision, but uniqueprefix0.00000017 isn't what you want. JSON.parse can be called with an extra reviver argument, which transforms values passed to it before returning them. You can use this to convert your data back into a useful form:

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);
});

这篇关于JSON.parse()的替代方案,以保持小数精度?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆