《Nodejs开发加密货币》之十四:Js处理数据计算的缺陷和解决方案

前言

Js原本是前端浏览器中使用的语言,对于算术运算并不擅长,估计很多小伙伴遇到过下面列举的情况。现在,我们要通过Nodejs在前后端都用Js开发,这个缺陷显然就很严重,因为加密货币承载的是大量交易,涉及到大量计算。

为彻底解决这个问题,我特意收集了相关问题,并从开源社区找到一种好用的解决办法。

Js的缺陷

(1)parseInt()小心使用

结论:不要将 parseInt 当做转换 Number 和 Integer 的工具,能不用就不用吧。

问题:默认,对小于 0.0000001 (1e-7) 的数字转换成 String 时,js会将其变成 科学记号法 ,再对这个数进行 parseInt 操作就会导致问题发生。即:

parseInt(0.0000008) === 8

解析

常见的问题有浮点数比较:

console.log((0.1 + 0.2) == 0.3);  // false
console.log((0.1 + 0.2) === 0.3); // false
console.log(0.1 + 0.2); // 0.30000000000000004

再有:

parseInt(1000000000000000000000.5, 10); // 1

parseInt 的第一个类型是字符串,所以会将传入的参数转换成字符串,也就是 String(1000000000000000000000.5) 的结果为 ‘1e+21’ 。 parseInt 并没有将 ‘e’ 视为一个数字,所以在转换到后就停止了。

这也就可以解释 parseInt(0.0000008) === 8 :

String(0.000008);  // '0.000008'
String(0.0000008); // '8e-7'

(2)注意处理的数据范围

结论:使用第三方包。

问题

假如,我们调用第三方api提供的数据,如下:

{"content": "Hi", "created_at": 1340863646, "type": "text", "message_id": 5758965507965321234, "from_user": "userC"}

其中message_id是19位number类型的数据。我用JSON.parse解析成JSON对象获取其中的信息,方法如下:

var jsonStr = '{"content": "Hi", "created_at": 1340863646, "type": "text", "message_id": 5758965507965321234, "from_user": "userC"}';
var jsonObj = JSON.parse(jsonStr);
console.log(jsonObj.message_id);//得到结果是:5758965507965321000

仔细看结果最后三位,变成000了。超过16位的数据,被解析后,其他数位均会变为0

解析

  • 浮点数范围:
最大范围 ±1.7976931348623157 × 10的308次方
最小范围 ±5 × 10的−324次方
  • 精确整数范围:
9007199254740992  and 9007199254740992 (即正负253次方)
  • 数组索引及位操作:
正负2的31次方

终极解决办法

使用 node-bignum ,地址:https://github.com/Ebookcoin/node-bignum

社区出现了很多bignumber包,但只有node-bignum可以完美解决上述问题。诸如 bignumber.js 等无法解决小数问题(问题1)。

链接

本源文地址: https://github.com/imfly/bitcoin-on-nodejs

电子书阅读: http://bitcoin-on-nodejs.ebookchain.org

参考

https://cnodejs.org/topic/4ff679c84764b7290214460a

https://cnodejs.org/topic/4fb3722c1975fe1e132b5a9a

官方网站: http://ebookchain.org

亿书在聚合和打造国内最好的区块链人才社区,欢迎加入区块链俱乐部: http://chainclub.org

开发交流群: 185046161

你可能感兴趣的:(node,项目,实践,区块链,加密货币)