I want to parse and convert an exponential value into a decimal using JavaScript. 4.65661287307739E-10
should give 0.000000000465661287307739
. What
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);
};
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"
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
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"
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
*/
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.