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

原文地址: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() 转换成数值表示。

原文地址:https://www.cnblogs.com/xianfengzhike/p/9939029.html

时间: 2024-10-11 10:35:24

JavaScript中科学计数法转化为数值字符串形式的相关文章

C#科学计数法转化为正常数值

1.字符串值中包含E等科学计数法,比如12E-2,需要进行转化为普通数值0.12, 2.转化函数如下: private Decimal ChangeDataToD(string strData) { Decimal dData = 0.0M; if (strData.Contains("E")) { dData = Convert.ToDecimal(Decimal.Parse(strData.ToString(), System.Globalization.NumberStyles.

Excel中科学计数法如何转正常显示

当数值型数据达到12位的时候,将以科学计数法的方式显示在单元格内,但是编辑栏仍然正常显示.   右键单击12位数字所在单元格,在弹出的菜单栏中选择设置单元格格式.   在单元格格式中点数字选项卡,点自定义,在类型中输入一个“#”,然后点击确定,设置完之后原来的科学计数法消失,显示为实际的12位数字.   数值型数据最多能存储15位有效数字,如果超过15位,可以事先将单元格格式数字设置成文本. 原文地址:https://www.cnblogs.com/Sunshine-bing/p/1264273

java中科学计数法数字转字符串

开发过程中有可能会遇到很小的数字,在显示过程中就转换成了科学计数法,这种不利于人的观看,于是就有必要转成字符串形式的.so. 将科学计数法的数字转换成字符串: 使用的是java.math的BigDecimal: BigDecimal bd = new BigDecimal("1.1920928955078125e-7"); String str = bd.toPlainString(); 显示结果: 0.00000011920928955078125 亲测好使..

JAVA中科学计数法转换普通计数法

今天发现数据库里汇总的数据有点大,一输出就被自动转化成科学计数法了.后来发现是转换字符串的方法有问题.如下: String a = "11234567.89"; BigDecimal db = new BigDecimal(a); System.out.println("科学计数:" + db.toString()); System.out.println("普通计数:" + db.toPlainString()); 输出: 科学计数:1.123

C# 中科学计数法转成正常值

抓取数据的时候碰到科学技术法,查了一些资料,直接贴代码 /// <summary> /// 数字科学计数法处理 /// </summary> /// <param name="strData"></param> /// <returns></returns> private Decimal ChangeToDecimal(string strData) { Decimal dData = 0.0M; if (str

PHP的两个科学计数法转换为字符串的方法

不常用,所以整理在这里,分享给同行使用 方法一:取尾数法 public function NumToStr($num) { if (stripos($num, 'e') === false) return $num; $num = trim(preg_replace('/[=\'"]/', '', $num, 1), '"'); //出现科学计数法,还原成字符串 $result = ""; while ($num > 0) { $v = $num - floo

科学计数法转换成正常数值

1.字符串值中包含E等科学计数法,比如12E-2,需要进行转化为普通数值0.12, 2.转化函数如下: private Decimal ChangeDataToD(string strData)        {            Decimal dData = 0.0M;            if (strData.Contains("E"))            {                dData = Convert.ToDecimal(Decimal.Parse

C#实现把科学计数法(E)转化为正常数字值 (转)

1.字符串值中包含E等科学计数法,比如12E-2,需要进行转化为普通数值0.12, 2.转化函数如下: private Decimal ChangeDataToD(string strData)         {             Decimal dData = 0.0M;             if (strData.Contains("E"))             {                 dData = Decimal.Parse(strData.ToSt

java使用poi解析或处理excel的时候,如何防止数字变成科学计数法的形式和其他常见Excel中数据转换问题

当使用POI处理excel的时候,遇到了比较长的数字,虽然excel里面设置该单元格是文本类型的,但是POI的cell的类型就会变成数字类型. 而且无论数字是否小数,使用cell.getNumbericCellValue() 去获取值的时候,会得到一个double,而且当长度大一点的时候会变成科学计数法形式. 那么获取这个单元格的原始的数据,就其实是一个double怎么转换成整数的问题了. 使用DecimalFormat对这个double进行了格式话,随后使用format方法获得的String就