当在字符串上下文中使用时,JavaScript将超过21位的整数转换为科学符号。我打印了一个整数作为URL的一部分。我怎样才能阻止这种转变的发生?
当前回答
您可以循环该数字并实现舍入
//函数替换给定索引的char
String.prototype.replaceAt=function(index, character) {
return this.substr(0, index) + character + this.substr(index+character.length);
}
//开始循环该数字
var str = "123456789123456799.55";
var arr = str.split('.');
str = arr[0];
i = (str.length-1);
if(arr[1].length && Math.round(arr[1]/100)){
while(i>0){
var intVal = parseInt(str.charAt(i));
if(intVal == 9){
str = str.replaceAt(i,'0');
console.log(1,str)
}else{
str = str.replaceAt(i,(intVal+1).toString());
console.log(2,i,(intVal+1).toString(),str)
break;
}
i--;
}
}
其他回答
这篇文章的问题是避免用e表示数字,而将数字作为普通数字。
因此,如果所需要的只是将e(科学)表示法数字转换为普通数字(包括小数的情况)而不损失精度,那么必须避免使用Math对象和其他javascript数字方法,以便在处理大数字和大分数时不会发生舍入(由于内部存储为二进制格式,这总是发生)。
下面的函数将e(科学)表示法数字转换为处理大数和大分数的普通数字(包括分数),而不损失准确性,因为它没有使用内置的数学和数字函数来处理或操作数字。
该函数还处理普通数字,因此可以将怀疑是'e'符号的数字传递给该函数进行修正。
该函数应该适用于不同的地区小数点。
提供了94个测试用例。
对于较大的电子表示法数字,将数字作为字符串传递。
例子:
eToNumber("123456789123456789.111122223333444455556666777788889999e+50");
// output:
"12345678912345678911112222333344445555666677778888999900000000000000"
eToNumber("123.456123456789123456895e-80");
// output:
"0.00000000000000000000000000000000000000000000000000000000000000000000000000000123456123456789123456895"
eToNumber("123456789123456789.111122223333444455556666777788889999e-50");
// output:
"0.00000000000000000000000000000000123456789123456789111122223333444455556666777788889999"
Javascript中有效的电子符号数字包括:
123e1 ==> 1230
123E1 ==> 1230
123e+1 ==> 1230
123.e+1 ==> 1230
123e-1 ==> 12.3
0.1e-1 ==> 0.01
.1e-1 ==> 0.01
-123e1 ==> -1230
/****************************************************************** * Converts e-Notation Numbers to Plain Numbers ****************************************************************** * @function eToNumber(number) * @version 1.00 * @param {e nottation Number} valid Number in exponent format. * pass number as a string for very large 'e' numbers or with large fractions * (none 'e' number returned as is). * @return {string} a decimal number string. * @author Mohsen Alyafei * @date 17 Jan 2020 * Note: No check is made for NaN or undefined input numbers. * *****************************************************************/ function eToNumber(num) { let sign = ""; (num += "").charAt(0) == "-" && (num = num.substring(1), sign = "-"); let arr = num.split(/[e]/ig); if (arr.length < 2) return sign + num; let dot = (.1).toLocaleString().substr(1, 1), n = arr[0], exp = +arr[1], w = (n = n.replace(/^0+/, '')).replace(dot, ''), pos = n.split(dot)[1] ? n.indexOf(dot) + exp : w.length + exp, L = pos - w.length, s = "" + BigInt(w); w = exp >= 0 ? (L >= 0 ? s + "0".repeat(L) : r()) : (pos <= 0 ? "0" + dot + "0".repeat(Math.abs(pos)) + s : r()); L= w.split(dot); if (L[0]==0 && L[1]==0 || (+w==0 && +s==0) ) w = 0; //** added 9/10/2021 return sign + w; function r() {return w.replace(new RegExp(`^(.{${pos}})(.)`), `$1${dot}$2`)} } //***************************************************************** //================================================ // Test Cases //================================================ let r = 0; // test tracker r |= test(1, "123456789123456789.111122223333444455556666777788889999e+50", "12345678912345678911112222333344445555666677778888999900000000000000"); r |= test(2, "123456789123456789.111122223333444455556666777788889999e-50", "0.00000000000000000000000000000000123456789123456789111122223333444455556666777788889999"); r |= test(3, "123456789e3", "123456789000"); r |= test(4, "123456789e1", "1234567890"); r |= test(5, "1.123e3", "1123"); r |= test(6, "12.123e3", "12123"); r |= test(7, "1.1234e1", "11.234"); r |= test(8, "1.1234e4", "11234"); r |= test(9, "1.1234e5", "112340"); r |= test(10, "123e+0", "123"); r |= test(11, "123E0", "123"); // //============================ r |= test(12, "123e-1", "12.3"); r |= test(13, "123e-2", "1.23"); r |= test(14, "123e-3", "0.123"); r |= test(15, "123e-4", "0.0123"); r |= test(16, "123e-2", "1.23"); r |= test(17, "12345.678e-1", "1234.5678"); r |= test(18, "12345.678e-5", "0.12345678"); r |= test(19, "12345.678e-6", "0.012345678"); r |= test(20, "123.4e-2", "1.234"); r |= test(21, "123.4e-3", "0.1234"); r |= test(22, "123.4e-4", "0.01234"); r |= test(23, "-123e+0", "-123"); r |= test(24, "123e1", "1230"); r |= test(25, "123e3", "123000"); r |= test(26, -1e33, "-1000000000000000000000000000000000"); r |= test(27, "123e+3", "123000"); r |= test(28, "123E+7", "1230000000"); r |= test(29, "-123.456e+1", "-1234.56"); r |= test(30, "-1.0e+1", "-10"); r |= test(31, "-1.e+1", "-10"); r |= test(32, "-1e+1", "-10"); r |= test(34, "-0", "-0"); r |= test(37, "0e0", "0"); r |= test(38, "123.456e+4", "1234560"); r |= test(39, "123E-0", "123"); r |= test(40, "123.456e+50", "12345600000000000000000000000000000000000000000000000"); r |= test(41, "123e-0", "123"); r |= test(42, "123e-1", "12.3"); r |= test(43, "123e-3", "0.123"); r |= test(44, "123.456E-1", "12.3456"); r |= test(45, "123.456123456789123456895e-80", "0.00000000000000000000000000000000000000000000000000000000000000000000000000000123456123456789123456895"); r |= test(46, "-123.456e-50", "-0.00000000000000000000000000000000000000000000000123456"); r |= test(47, "-0e+1", "-0"); r |= test(48, "0e+1", "0"); r |= test(49, "0.1e+1", "1"); r |= test(50, "-0.01e+1", "-0.1"); r |= test(51, "0.01e+1", "0.1"); r |= test(52, "-123e-7", "-0.0000123"); r |= test(53, "123.456e-4", "0.0123456"); r |= test(54, "1.e-5", "0.00001"); // handle missing base fractional part r |= test(55, ".123e3", "123"); // handle missing base whole part // The Electron's Mass: r |= test(56, "9.10938356e-31", "0.000000000000000000000000000000910938356"); // The Earth's Mass: r |= test(57, "5.9724e+24", "5972400000000000000000000"); // Planck constant: r |= test(58, "6.62607015e-34", "0.000000000000000000000000000000000662607015"); r |= test(59, "0.000e3", "0"); r |= test(60, "0.000000000000000e3", "0"); r |= test(61, "-0.0001e+9", "-100000"); r |= test(62, "-0.0e1", "-0"); r |= test(63, "-0.0000e1", "-0"); r |= test(64, "1.2000e0", "1.2000"); r |= test(65, "1.2000e-0", "1.2000"); r |= test(66, "1.2000e+0", "1.2000"); r |= test(67, "1.2000e+10", "12000000000"); r |= test(68, "1.12356789445566771234e2", "112.356789445566771234"); // ------------- testing for Non e-Notation Numbers ------------- r |= test(69, "12345.7898", "12345.7898") // no exponent r |= test(70, 12345.7898, "12345.7898") // no exponent r |= test(71, 0.00000000000001, "0.00000000000001") // from 1e-14 r |= test(72, 0.0000000000001, "0.0000000000001") // from 1e-13 r |= test(73, 0.000000000001, "0.000000000001") // from 1e-12 r |= test(74, 0.00000000001, "0.00000000001") // from 1e-11 r |= test(75, 0.0000000001, "0.0000000001") // from 1e-10 r |= test(76, 0.000000001, "0.000000001") // from 1e-9 r |= test(77, 0.00000001, "0.00000001") // from 1e-8 r |= test(78, 0.0000001, "0.0000001") // from 1e-7 r |= test(79, 1e-7, "0.0000001") // from 1e-7 r |= test(80, -0.0000001, "-0.0000001") // from 1e-7 r |= test(81, 0.0000005, "0.0000005") // from 1e-7 r |= test(82, 0.1000005, "0.1000005") // from 1e-7 r |= test(83, 1e-6, "0.000001") // from 1e-6 r |= test(84, 0.000001, "0.000001"); // from 1e-6 r |= test(85, 0.00001, "0.00001"); // from 1e-5 r |= test(86, 0.0001, "0.0001"); // from 1e-4 r |= test(87, 0.001, "0.001"); // from 1e-3 r |= test(88, 0.01, "0.01"); // from 1e-2 r |= test(89, 0.1, "0.1") // from 1e-1 r |= test(90, -0.0000000000000345, "-0.0000000000000345"); // from -3.45e-14 r |= test(91, -0, "0"); r |= test(92, "-0", "-0"); r |= test(93,2e64,"20000000000000000000000000000000000000000000000000000000000000000"); r |= test(94,"2830869077153280552556547081187254342445169156730","2830869077153280552556547081187254342445169156730"); if (r == 0) console.log("All 94 tests passed."); //================================================ // Test function //================================================ function test(testNumber, n1, should) { let result = eToNumber(n1); if (result !== should) { console.log(`Test ${testNumber} Failed. Output: ${result}\n Should be: ${should}`); return 1; } }
下面是我的短变体的number .prototype. tofixed方法,适用于任何数字:
Number.prototype.toFixedSpecial = function(n) { var str = this.toFixed(n); if (str.indexOf('e+') === -1) return str; // if number is in scientific notation, pick (b)ase and (p)ower str = str.replace('.', '').split('e+').reduce(function(b, p) { return b + Array(p - b.length + 2).join(0); }); if (n > 0) str += '.' + Array(n + 1).join(0); return str; }; console.log( 1e21.toFixedSpecial(2) ); // "1000000000000000000000.00" console.log( 2.1e24.toFixedSpecial(0) ); // "2100000000000000000000000" console.log( 1234567..toFixedSpecial(1) ); // "1234567.0" console.log( 1234567.89.toFixedSpecial(3) ); // "1234567.890"
目前还没有原生的功能来消解科学记数法。但是,出于这个目的,您必须编写自己的功能。
这是我的:
function dissolveExponentialNotation(number)
{
if(!Number.isFinite(number)) { return undefined; }
let text = number.toString();
let items = text.split('e');
if(items.length == 1) { return text; }
let significandText = items[0];
let exponent = parseInt(items[1]);
let characters = Array.from(significandText);
let minus = characters[0] == '-';
if(minus) { characters.splice(0, 1); }
let indexDot = characters.reduce((accumulator, character, index) =>
{
if(!accumulator.found) { if(character == '.') { accumulator.found = true; } else { accumulator.index++; } }
return accumulator;
}, { index: 0, found: false }).index;
characters.splice(indexDot, 1);
indexDot += exponent;
if(indexDot >= 0 && indexDot < characters.length - 1)
{
characters.splice(indexDot, 0, '.');
}
else if(indexDot < 0)
{
characters.unshift("0.", "0".repeat(-indexDot));
}
else
{
characters.push("0".repeat(indexDot - characters.length));
}
return (minus ? "-" : "") + characters.join("");
}
使用。toprecprecision, . tofixed等。您可以通过将数字转换为. tostring的字符串,然后查看其.length来计算数字中的位数。
我知道这是一个老问题,但最近很活跃。MDN toLocaleString
const myNumb = 1000000000000000000000;
console.log( myNumb ); // 1e+21
console.log( myNumb.toLocaleString() ); // "1,000,000,000,000,000,000,000"
console.log( myNumb.toLocaleString('fullwide', {useGrouping:false}) ); // "1000000000000000000000"
您可以使用选项格式化输出。
注意:
Number.toLocaleString()四舍五入到小数点后16位,因此…
const myNumb = 586084736227728377283728272309128120398;
console.log( myNumb.toLocaleString('fullwide', { useGrouping: false }) );
返回…
586084736227728400000000000000000000000
如果准确性在预期结果中很重要,这可能是不可取的。