26

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

parseFloat(4.65661287307739E-10) returns 4.65661287307739e-10.

parseInt(4.65661287307739E-10) returns 4.

Penny Liu
  • 15,447
  • 5
  • 79
  • 98
SharpCoder
  • 18,279
  • 43
  • 153
  • 249
  • Set it as a `num` variable and the use `toFixed()` http://www.codingforums.com/showthread.php?t=184468 – Reinstate Monica Cellio Sep 10 '13 at 13:09
  • possible duplicate of [Javascript parseFloat '1.23e-7' gives 1.23e-7 when need 0.000000123](http://stackoverflow.com/questions/4126206/javascript-parsefloat-1-23e-7-gives-1-23e-7-when-need-0-000000123) – Bibhu Sep 10 '13 at 13:10

10 Answers10

33

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.

Gray
  • 7,050
  • 2
  • 29
  • 52
22

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;
console.log(n.noExponents()) /*  returned value: (String)    0.000000000465661287307739  */
n = 9.935818877444285e+23
console.log(n.noExponents()) /*  returned value: (String)    993581887744428500000000  */
mplungjan
  • 169,008
  • 28
  • 173
  • 236
kennebec
  • 102,654
  • 32
  • 106
  • 127
6

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;
console.log(convert(myvar)); //"4951760157141521000000000000"
console.log(convert(myvar2)); //"0.04951760157141521"
console.log(convert(myvar3)); //"3300"
mplungjan
  • 169,008
  • 28
  • 173
  • 236
ibrahim tanyalcin
  • 5,643
  • 3
  • 16
  • 22
5

Here is my short function code that converts Exponential (e-Notation) Numbers to Decimals, allowing the output of large number of decimal places.

It handles all the e-notation syntax permitted by Javascript which include the following:

Valid e-notation numbers in Javascript:
   123e1    ==>  1230
   123E1    ==>  1230
   123e+1   ==>  1230
   123.e+1  ==>  1230   (with missing fractional part)
   123e-1   ==>  12.3
   0.1e-1   ==>  0.01
   .1e-1    ==>  0.01   (with missing whole part)
  -123e1    ==> -1230
   0.0e1    ==>  0
  -0.0e4    ==> -0

The function does not attempt to trap NaN or undefined inputs but does attempt to cater for normal (non-e-notation) numbers; such numbers are returned "as is".

I have tried to provide enough comments on each line and tried to avoid (as far as possible!) the use of short-circuiting and conditional (ternary) operators for better clarity.

I have used the toLocaleString() method to automatically detect the decimal separator sign, but this, of course, assumes that the input string representing the number follows the machine's locale (especially when manually passed to the function).

/********************************************************
* Converts Exponential (e-Notation) Numbers to Decimals
********************************************************
* @function numberExponentToLarge()
* @version  1.00
* @param   {string}  Number in exponent format.
*                   (other formats returned as is).
* @return  {string}  Returns a decimal number string.
* @author  Mohsen Alyafei
* @date    12 Jan 2020
*
* Notes: No check is made for NaN or undefined inputs
*
*******************************************************/

function numberExponentToLarge(numIn) {
 numIn +="";                                            // To cater to numric entries
 var sign="";                                           // To remember the number sign
 numIn.charAt(0)=="-" && (numIn =numIn.substring(1),sign ="-"); // remove - sign & remember it
 var str = numIn.split(/[eE]/g);                        // Split numberic string at e or E
 if (str.length<2) return sign+numIn;                   // Not an Exponent Number? Exit with orginal Num back
 var power = str[1];                                    // Get Exponent (Power) (could be + or -)

 var deciSp = 1.1.toLocaleString().substring(1,2);  // Get Deciaml Separator
 str = str[0].split(deciSp);                        // Split the Base Number into LH and RH at the decimal point
 var baseRH = str[1] || "",                         // RH Base part. Make sure we have a RH fraction else ""
     baseLH = str[0];                               // LH base part.

  if (power>=0) {   // ------- Positive Exponents (Process the RH Base Part)
     if (power> baseRH.length) baseRH +="0".repeat(power-baseRH.length); // Pad with "0" at RH
     baseRH = baseRH.slice(0,power) + deciSp + baseRH.slice(power);      // Insert decSep at the correct place into RH base
      if (baseRH.charAt(baseRH.length-1) ==deciSp) baseRH =baseRH.slice(0,-1); // If decSep at RH end? => remove it

  } else {         // ------- Negative exponents (Process the LH Base Part)
     num= Math.abs(power) - baseLH.length;                               // Delta necessary 0's
     if (num>0) baseLH = "0".repeat(num) + baseLH;                       // Pad with "0" at LH
     baseLH = baseLH.slice(0, power) + deciSp + baseLH.slice(power);     // Insert "." at the correct place into LH base
     if (baseLH.charAt(0) == deciSp) baseLH="0" + baseLH;                // If decSep at LH most? => add "0"

  }
  // Rremove leading and trailing 0's and Return the long number (with sign)
  return sign + (baseLH + baseRH).replace(/^0*(\d+|\d+\.\d+?)\.?0*$/,"$1");
}

//============ test codes ==================
function test(test,input,should){
var  out=numberExponentToLarge(input);
var r = (out===should) ? true : false;
if (!r) console.log(test+" Failed: "+out+" should be: "+should);
  else console.log("Passed");
}
// ------------- tests for e-notation numbers ---------------------

test(1,"123E0","123")
test(2,"123E0","123")
test(3,"-123e+0","-123")
test(4,"123e1","1230")
test(5,"123e3","123000")
test(6,"123e+3","123000")
test(7,"123E+7","1230000000")
test(8,"-123.456e+1","-1234.56")
test(9,"123.456e+4","1234560")
test(10,"123E-0","123")
test(11,"123.456e+50","12345600000000000000000000000000000000000000000000000")

test(12,"123e-0","123")
test(13,"123e-1","12.3")
test(14,"123e-3","0.123")
test(15,"-123e-7","-0.0000123")
test(16,"123.456E-1","12.3456")
test(17,"123.456e-4","0.0123456")
test(18,"123.456e-50","0.00000000000000000000000000000000000000000000000123456")
test(18-1,"-123.456e-50","-0.00000000000000000000000000000000000000000000000123456")

test(19,"1.e-5","0.00001")  // handle missing base fractional part
test(20,".123e3","123")     // handle missing base whole part

// The Electron's Mass: 
test(21,"9.10938356e-31","0.000000000000000000000000000000910938356")
// The Earth's Mass:
test(22,"5.9724e+24","5972400000000000000000000")
// Planck constant:
test(23,"6.62607015e-34","0.000000000000000000000000000000000662607015")

test(24,"0.000e3","0")
test(25,"0.000000000000000e3","0")
test(26,"-0.0001e+9","-100000")
test(27,"-0.0e1","-0")
test(28,"-0.0000e1","-0")
test(28,"-000.0000e1","-0")    // this is an invalid Javascript number
test(28,"-000.0000e-1","-0")   // this is an invalid Javascript number
test(28,"-000.0000e+10","-0")  // this is an invalid Javascript number
test(28,"-000.0000e+2","-0")   // this is an invalid Javascript number

// ------------- testing for Non e-Notation Numbers -------------
test(29,"12345.7898","12345.7898") // no exponent
test(30,12345.7898,"12345.7898")   // no exponent
test(31,0.00000000000001,"0.00000000000001")    // from 1e-14
test(32,-0.0000000000000345,"-0.0000000000000345") // from -3.45e-14
test(33,-0,"0")
test(34,"1.2000e0","1.2")
test(35,"1.2000e-0","1.2")
test(35,"1.2000e+0","1.2")
test(35,"1.2000e+10","12000000000")
Mohsen Alyafei
  • 4,765
  • 3
  • 30
  • 42
4

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"
console.log(result1)
const result2 = exponentialToDecimal(5.6565e-29); // "0.000000000000000000000000000056565"
console.log(result2)
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Alex Gongadze
  • 191
  • 1
  • 5
1

Use toFixed(number)

eg :

(+exponentialnumber).toFixed(8)


2e-7 ===> 0.00000020
mybrave
  • 1,662
  • 3
  • 20
  • 37
Vishnu Gopinath
  • 55
  • 1
  • 10
1

i do Number("123e1").toFixed(100).replace(/0*$/);

basically, I'm using native toFixed to get decimal string, then i trim trailing 0's

Zalaboza
  • 8,899
  • 16
  • 77
  • 142
1

You could use BigInt which is supported in most browsers nowadays, yet not IE. Of course this is not useful for floats.

console.log(BigInt(4.951760157141521e+27).toString(10))

Out: 4951760157141521099596496896

jfunk
  • 7,176
  • 4
  • 37
  • 38
0

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);
  };
Philip Kahn
  • 614
  • 1
  • 5
  • 22
-2

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

The toFixed method used by the library can be extracted and ran in plain JS (without the use of the ExtJS library):

function toFixed( value, precision = 0 ){
    if ( (0.9).toFixed() !== '1' ){
        return value.toFixed(precision);
    }
    let pow = Math.pow( 10, precision );
    return (Math.round( value * pow ) / pow).toFixed(precision);
} 

toFixed(4.65661287307739E-30, 44);
//=> '0.00000000000000000000000000000465661287307739'
Kostas Minaidis
  • 4,681
  • 3
  • 17
  • 25
Nandkumar Tekale
  • 16,024
  • 8
  • 58
  • 85