Parsing and converting exponential values to decimal in JavaScript

前端 未结 8 1558
梦毁少年i
梦毁少年i 2020-12-05 11:19

I want to parse and convert an exponential value into a decimal using JavaScript. 4.65661287307739E-10 should give 0.000000000465661287307739. What

相关标签:
8条回答
  • 2020-12-05 11:51

    Expanded from @kennebec 's answer, but handles the edge cases his fails at better (Gist, with CoffeeScript):

      String.prototype.noExponents = function(explicitNum) {
        var data, leader, mag, multiplier, num, sign, str, z;
        if (explicitNum == null) {
          explicitNum = true;
        }
    
        /*
         * Remove scientific notation from a number
         *
         * After
         * http://stackoverflow.com/a/18719988/1877527
         */
        data = this.split(/[eE]/);
        if (data.length === 1) {
          return data[0];
        }
        z = "";
        sign = this.slice(0, 1) === "-" ? "-" : "";
        str = data[0].replace(".", "");
        mag = Number(data[1]) + 1;
        if (mag <= 0) {
          z = sign + "0.";
          while (!(mag >= 0)) {
            z += "0";
            ++mag;
          }
          num = z + str.replace(/^\-/, "");
          if (explicitNum) {
            return parseFloat(num);
          } else {
            return num;
          }
        }
        if (str.length <= mag) {
          mag -= str.length;
          while (!(mag <= 0)) {
            z += 0;
            --mag;
          }
          num = str + z;
          if (explicitNum) {
            return parseFloat(num);
          } else {
            return num;
          }
        } else {
          leader = parseFloat(data[0]);
          multiplier = Math.pow(10, parseInt(data[1]));
          return leader * multiplier;
        }
      };
    
      Number.prototype.noExponents = function() {
        var strVal;
        strVal = String(this);
        return strVal.noExponents(true);
      };

    0 讨论(0)
  • 2020-12-05 12:03

    A horribly primitive conversion, written with ES6:

     function convert(n){
            var sign = +n < 0 ? "-" : "",
                toStr = n.toString();
            if (!/e/i.test(toStr)) {
                return n;
            }
            var [lead,decimal,pow] = n.toString()
                .replace(/^-/,"")
                .replace(/^([0-9]+)(e.*)/,"$1.$2")
                .split(/e|\./);
            return +pow < 0 
                ? sign + "0." + "0".repeat(Math.max(Math.abs(pow)-1 || 0, 0)) + lead + decimal
                : sign + lead + (+pow >= decimal.length ? (decimal + "0".repeat(Math.max(+pow-decimal.length || 0, 0))) : (decimal.slice(0,+pow)+"."+decimal.slice(+pow)))
        }
    
    var myvar = 4.951760157141521e+27;
    var myvar2 = 4.951760157141521e-2;
    var myvar3 = 3.3e+3;
    convert(myvar);//"4951760157141521000000000000"
    convert(myvar2);//"0.04951760157141521"
    convert(myvar3);//"3300"
    
    0 讨论(0)
  • 2020-12-05 12:05

    In ExtJS you can use Ext.Number.toFixed(value, precision) method which internally uses toFixed() method,

    E.g.

    console.log(Ext.Number.toFixed(4.65661287307739E-10, 10));  
    // O/p => 0.0000000005
    
    console.log(Ext.Number.toFixed(4.65661287307739E-10, 15));  
    // 0.000000000465661
    
    0 讨论(0)
  • 2020-12-05 12:08

    This variant works well for me to display formatted string values for too small/big numbers:

    const exponentialToDecimal = exponential => {
        let decimal = exponential.toString().toLowerCase();
        if (decimal.includes('e+')) {
            const exponentialSplitted = decimal.split('e+');
            let postfix = '';
            for (
                let i = 0;
                i <
                +exponentialSplitted[1] -
                    (exponentialSplitted[0].includes('.') ? exponentialSplitted[0].split('.')[1].length : 0);
                i++
            ) {
                postfix += '0';
            }
            const addCommas = text => {
                let j = 3;
                let textLength = text.length;
                while (j < textLength) {
                    text = `${text.slice(0, textLength - j)},${text.slice(textLength - j, textLength)}`;
                    textLength++;
                    j += 3 + 1;
                }
                return text;
            };
            decimal = addCommas(exponentialSplitted[0].replace('.', '') + postfix);
        }
        if (decimal.toLowerCase().includes('e-')) {
            const exponentialSplitted = decimal.split('e-');
            let prefix = '0.';
            for (let i = 0; i < +exponentialSplitted[1] - 1; i++) {
                prefix += '0';
            }
            decimal = prefix + exponentialSplitted[0].replace('.', '');
        }
        return decimal;
    };
    
    const result1 = exponentialToDecimal(5.6565e29); // "565,650,000,000,000,000,000,000,000,000"
    const result2 = exponentialToDecimal(5.6565e-29); // "0.000000000000000000000000000056565"
    
    0 讨论(0)
  • 2020-12-05 12:09

    You can display the string value of a large or small decimal:

    Number.prototype.noExponents= function(){
        var data= String(this).split(/[eE]/);
        if(data.length== 1) return data[0]; 
    
        var  z= '', sign= this<0? '-':'',
        str= data[0].replace('.', ''),
        mag= Number(data[1])+ 1;
    
        if(mag<0){
            z= sign + '0.';
            while(mag++) z += '0';
            return z + str.replace(/^\-/,'');
        }
        mag -= str.length;  
        while(mag--) z += '0';
        return str + z;
    }
    var n=4.65661287307739E-10 ;
    n.noExponents()
    
    /*  returned value: (String)
    0.000000000465661287307739
    */
    
    0 讨论(0)
  • 2020-12-05 12:11

    You can use toFixed(), but there is a limit of 20.

    ex:

    (4.65661287307739E-10).toFixed(20)
    "0.00000000046566128731"
    

    But...

    (4.65661287307739E-30).toFixed(20)
    "0.00000000000000000000"
    

    So if you always have fewer than 20 decimal places, you'll be fine. Otherwise, I think you may have to write your own.

    0 讨论(0)
提交回复
热议问题