我正在调用 JSON.parse()
来解析一个包含小数位的 JSON 字符串。
解析后不会保持小数点的精度。例如,返回的值如 3.1e-7
而不是实际的小数。
如何在 ng2+ 中反序列化 JSON 字符串同时保持小数精度?
更新
我正在考虑从字符串中映射出值,然后在 JSON.parse() 之后手动将值设置为对象,但是当我将不同的小十进制数设置为属性值时,会出现相同的数字格式。那么这个问题不一定是 JSON.parse() 所特有的,而是一般的 Javascript 所特有的吗?还是 JSON.parse() 以某种方式以固定方式配置属性类型?
最佳答案
一旦你通过 JSON.parse 传递你的 JSON 字符串,你就会失去精度,因为 the way floating point math works .您需要将该号码存储为 object designed for storing arbitrary-precision numbers ,并且您需要在解析之前摆弄字符串本身。最简单的方法是使用正则表达式。 JSON 是上下文无关语法,正则表达式适用于常规语法,因此警告适用:
WARNING: PARSING CFG WITH REGEX MAY SUMMON ZALGO
此正则表达式应该将 JSON 中的数字转换为字符串:
let stringedJSON = origJSON.replace(/:\s*([-+Ee0-9.]+)/g, ': "uniqueprefix$1"');
但我还没有对它进行广泛的测试,如果你有类似 data:42
的 key ,它肯定会把事情搞砸。
假设它正常工作,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);
});
关于javascript - 替代 JSON.parse() 以保持小数精度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47916160/