js中科学计数法转数字的问题

2018-03-23 04:39:33javascript问题

再处理数字的时候,遇到了一个坑爹的问题。

数字类型自动显示成了科学计数法。

之所以说坑爹,不是说无法解决这个问题,是没办法完全处理。

来看几个数据:一下方法来源网络

new Number(9e4).toLocaleString();//90000 没问题
new Number(9e-4).toLocaleString();// 0 有问题了 =======已解决
new Number(9e-4).valueOf();// 0.0009 没问题
new Number(9e4).valueOf();// 90000 没问题
new Number(9e-7).valueOf();// 9e-7 有问题了==========

比如:9e-7这种小数,该怎么转成数字0.0000009显示呢

网友回答:

  • jsoncode jsoncode 2018-3-23 5:00 回复:
    已被采纳

应急方案:已解决

function getFullNum(num){
    //处理非数字
    if(isNaN(num)){return num};
//处理不需要转换的数字
var str = ''+num;
if(!/e/i.test(str)){return num;};

//先获取到精确的小数位
var fixed = (''+num).match(/\d+$/)[0];

//拿到保留指定的小数
return new Number(num).toFixed(fixed);

}

getFullNum(9e-7);//0.0000009
//这里还是有个问题 getFullNum(9.1e-7);//0.0000009,而不是0.0000091

以下是最终方案:根据@代码宇宙的方案优化

function getFullNum(num){
    //处理非数字
    if(isNaN(num)){return num};
//处理不需要转换的数字
var str = ''+num;
if(!/e/i.test(str)){return num;};

return (num).toFixed(18).replace(/\.?0+$/, "");

}

getFullNum(9.1e-7);// 0.00000091

0.00000091 你会发现是8位小数,对你没看错.比如:0.1e-3就是0.0001;这是正确的结果。

最后总结:
浏览器中,小于1e-7的数字都会自动转成科学记数法,比如控制台输入0.0000001会自动显示1e-7.
所以,这也是new Number(9e-7).valueOf();为什么没有转换成功的原因。

  • a122676890 a122676890 2018-3-23 5:01 回复:jsoncode

    ...感觉还不如用现成的科学计算的库 还能丰富计算。。你这个转换。。

  • jsoncode jsoncode 2018-3-23 5:06 回复:jsoncode
    一切方法要跟需求走,我知道引入一个计算库,更方便,更丰富,这里只用这一个功能,并且要求的计算量很苛刻,所以,经验和理论还是有差距的。


  • 代码宇宙 代码宇宙 2018-3-23 5:07 回复:

    (9e-7).toFixed(18).replace(/\.0+$/, "").replace(/(\.\d+[1-9])0+$/, "$1")

    • jsoncode jsoncode 2018-3-23 6:49 回复:代码宇宙
      你的思路很好,根据你你的思路,我优化了一下:(9.1e-7).toFixed(18).replace(/.?0+$/, "");这样就是一个万能的转换了,不管是9e7,9e-7,还是9.1e-7,9.1e7都可以了。

    • jsoncode jsoncode 2018-3-23 6:57 回复:代码宇宙
      正则被sf给转码了,为了不误人子弟,我这里补充一下:(9.1e-7).toFixed(18).replace(/\.?0+$/, "")

    • 代码宇宙 代码宇宙 2018-3-23 9:55 回复:代码宇宙

      你的不行吧,点号可有可无那不是会吧末尾的零全部去掉了?

    • 代码宇宙 代码宇宙 2018-3-23 10:46 回复:代码宇宙

      这一点是我没考虑到,哈哈


  • a122676890 a122676890 2018-3-23 4:49 回复:

    可以考虑一些专门的库来处理类似的问题 具体库的名称请google

或者自己转成字符串处理

  • jsoncode jsoncode 2018-3-23 4:53 回复:a122676890
    自己处理时没有问题的,但是这个数据处理量实在庞大,每秒要处理几十万次,甚至跟多。所以我想找一个系统就支持的方法解决。不知道有没有

  • jsonLi jsonLi 2018-3-23 5:01 回复:

    提供一个思路 ,用正则

var reg=/^(\d)e-(\d)/
var matchArr='1e-7'.match(reg);
var firstNum=matchArr[1];
var exponential=matchArr[2];

有几位数就前面补几个0。


  • CRIMX CRIMX 2018-3-23 5:04 回复:

    要展示的地方转字符串即可,例子最后几个 new number 加 valueOf 是多此一举的

9e-7.toFixed(7)

  • 阎笑 阎笑 2019-4-3 11:09 回复:

    之前的回答测试不可用(除去用插件,事实上插件肯定是风险最低的)...

/**
 * @description 科学计数法转为string
 * @param {string, number} param
 */
function scientificNotationToString(param) {
  let strParam = String(param)
  let flag = /e/.test(strParam)
  if (!flag) return param

  // 指数符号 true: 正,false: 负
  let sysbol = true
  if (/e-/.test(strParam)) {
    sysbol = false
  }
  // 指数
  let index = Number(strParam.match(/\d+$/)[0])
  // 基数
  let basis = strParam.match(/^[\d\.]+/)[0].replace(/\./, '')

  if (sysbol) {
    return basis.padEnd(index + 1, 0)
  } else {
    return basis.padStart(index + basis.length, 0).replace(/^0/, '0.')
  }
}

clipboard.png

clipboard.png