JavaScript中科学计数法转化为数值字符串形式

摘要:
//Www.css88.com/archives/9318(很多好处)JavaScript经常遇到数值计算问题。JavaScript将自动将数值转换为科学符号,这意味着(1)小数点后小于1且大于6个零的浮点值:大于21位的整数已超出JavaScript精确整数范围−9007199254740992至9007199254720992(即正负2的53次方)。

原文地址:https://www.css88.com/archives/9318 (受益匪浅)

JavaScript 中经常会碰到数值计算问题,偶尔会在不经意间报一个不是bug的bug。今天来说说一个特殊的例子。我以0.0011BTC 价格买入 0.0002CZR 计算出了的金额是 0.00000022BTC,而 JavaScript 计算出来的金额是 2.2e-7 。值是对的,只是用了科学计数法,也是数值类型。但是问题来了,一般用户用户看不懂 2.2e-7,那么就把它转换成 0.00000022 吧。然而问题了,我用尽办法,怎么样都无法将 2.2e-7 转换成直观的 0.00000022。或许你会嘲笑我,告诉我直接用 .toFixed() 方法。但是新问题又来了, .toFixed() 会保留足够的小数位,比如:2e-7.toFixed(8) 得到的值是 0.000000202e2.toFixed(8)得到的值是 200.00000000。最后的 0 让我感到多余…

问题分析

问题还是要解决,只能深入了解 JavaScript 中科学计数法相关的知识。对于极大或者极小的数,可以用科学计数法 e来表示的浮点数值来表示。科学计数法允许字母e 或 E 的后面,跟着一个整数,表示这个数值的指数部分。

以下两种情况,JavaScript 会自动将数值转为科学计数法表示

(1) 小于1且小数点后面带有6个0以上的浮点数值:

JavaScript代码:
  1. 0.0000003// 3e-7
  2. 0.00000033// 3.3e-7
  3. 0.000003// 0.000003

(2) 整数位数字多于21位:

JavaScript代码:
  1. 1234567890123456789012//1.2345678901234568e+21
  2. 1234567890123456789012.1//1.2345678901234568e+21
  3. 123456789012345678901//123456789012345680000

解决思路

首先看看整数位数字多于21位的情况,其实这个一般不会碰到,整数位数字多于21位已经超出了 JavaScript 精确整数范围 −9007199254740992 至 9007199254740992 (即正负2的53次方)。如果你需要可以是使用 bignumber.js。一般情况你可以使用.toString() 将科学计数法的数字转化为直观的数字表示,例如:

JavaScript代码:
  1. ""+1.401e10// "14010000000"
  2. 1.401e10.toString(10)// "14010000000"

小于1且小数点后面带有6个0以上的浮点数值自动转化为科学计数法,要想转换成直观的数字表示就没那么容易了,我尝试了几种办法:

JavaScript代码:
  1. ""+3.3e-7//"3.3e-7"
  2. 3.3e-7.toString(10)//"3.3e-7"

都没达到我的预期。

解决问题

精度计算的时候我们通常会使用 .toFixed() 方法,Number.toFixed(digits) 方法使用定点表示法来格式化一个数,会对结果进行四舍五入。参数 digits 表示小数点后数字的个数,一般介于 0 到 20 (包括)之间。例如:

JavaScript代码:
  1. 3.3e-7.toFixed(8);// "0.00000033"
  2. 3e-7.toFixed(8);// "0.00000030"

一般情况下,我们的需求小数位数是固定的,所以这个基本可以满足我们的需求。但是有些人可能不喜欢 0.00000030 这种形式,认为最后的 0 是多余的。所以索性就改进了一下:

JavaScript代码:
  1. function toNumberStr(num,digits){
  2. // 正则匹配小数科学记数法
  3. if(/^(d+(?:.d+)?)(e)([-]?d+)$/.test(num)){
  4. // 正则匹配小数点最末尾的0
  5. var temp=/^(d{1,}(?:,d{3})*.(?:0*[1-9]+)?)(0*)?$/.exec(num.toFixed(digits));
  6. if(temp){
  7. return temp[1];
  8. }else{
  9. return num.toFixed(digits)
  10. }
  11. }else{
  12. return""+num
  13. }
  14. }
  15. toNumberStr(3.3e-7,8)// "0.00000033"
  16. toNumberStr(3e-7,8)// "0.0000003"
  17. toNumberStr(1.401e10,8)// "14010000000"
  18. toNumberStr(0.0004,8)// "0.0004"

这个方法基本满足了我的需求,但是总是觉得一点累赘,后面那个参数意思也不够明确,所以发到微信群请大家帮忙优化。特别感谢网友 @caikan 提供的方法:

JavaScript代码:
  1. function toNonExponential(num){
  2. var m = num.toExponential().match(/d(?:.(d*))?e([+-]d+)/);
  3. return num.toFixed(Math.max(0,(m[1]||'').length - m[2]));
  4. }
  5. toNonExponential(3.3e-7)// "0.00000033"
  6. toNonExponential(3e-7)// "0.0000003"
  7. toNonExponential(1.401e10)// "14010000000"
  8. toNonExponential(0.0004)// "0.0004"

解析一下:

.toExponential()将数字转化为科学记数法表示,匹配正则表达式/d(?:.(d*))?e([+-]d+)/,获取科学记数法中小数点后的字符及幂指数(e 后面的值),这样可以确定数字是几位小数。再用toFixed() 转换成数值表示。

免责声明:文章转载自《JavaScript中科学计数法转化为数值字符串形式》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇统计学习方法 | 第2章 感知机 | 补充适配 iOS尺寸下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python+opencv笔记(2)——边缘填充

python+opencv之边缘填充 一、边缘填充 相信很多喜欢玩电脑的小伙伴,遇到过这种情况:有时候换电脑壁纸的时候,原本一张很好看完整的图片,换成电脑壁纸就是一个不完整或者由很多重复的图片组成的壁纸。其实这里就有填充的出现。 边缘填充:因为对于图像的卷积操作,最边缘的像素一般无法处理,所以卷积核中心到不了最边缘像素。这就需要先将图像的边界填充,再根据不...

Eclipse配置C++11环境详细介绍

转:https://blog.csdn.net/wgxh05/article/details/54021049 本文记录Eclipse配置C++11开发所有作者遇到的情况,包括跨工程文件编译,内联文件编译等。 1.菜单“Project”——“Properties”——“C++ General”,如图所示:   2.“C++ Build”——“Setting...

web 大文件分片上传处理

这里只写后端的代码,基本的思想就是,前端将文件分片,然后每次访问上传接口的时候,向后端传入参数:当前为第几块文件,和分片总数 下面直接贴代码吧,一些难懂的我大部分都加上注释了: 上传文件实体类: 看得出来,实体类中已经有很多我们需要的功能了,还有实用的属性。如MD5秒传的信息。 首先是文件数据接收逻辑,负责接收控件上传的文件块数据,然后写到服务器的文件中...

WPF中元素拖拽的两个实例

  今天结合之前做过的一些拖拽的例子来对这个方面进行一些总结,这里主要用两个例子来说明在WPF中如何使用拖拽进行操作,元素拖拽是一个常见的操作,第一个拖拽的例子是将ListBox中的子元素拖拽到ListView的某一个节点,从而将该子元素作为当前节点的子节点。第二个例子就是将ListView的某一项拖拽到另外一项上从而使两个子项位置互换,这两个例子的原理类...

scss之&的用法

今天看到一段用scss写的工作代码: .el-checkbox__inner {   &:hover {     border-color: #42b983;   } } 其中,&的作用是什么呢?我查阅了以下资料,&是父选择器标识符。 即可把以上代码编译成 .el-checkbox__inner:hover { border...

ligerUI框架

一、介绍 ligerUI是一个轻量级的前端开发框架。简单的说,就是能够帮助开发快速搭建网页,并且不需要更多的写前端代码,能够在最短的时间内开发出一套美观,优雅的前端界面。 需要掌握的技术有html,css,js,jquery,json,还有一些后端代码能力,不然就不能开发出自己想要的功能咯。 首先进入官网下载一个ligerUI的demo,下载好之后的效果...