JavaScript mengkonversi INT besar ke notasi ilmiah ketika jumlahnya menjadi besar. Bagaimana saya bisa mencegah hal ini terjadi?
translatetransformasi yang berisi koordinat dalam notasi ilmiah.
JavaScript mengkonversi INT besar ke notasi ilmiah ketika jumlahnya menjadi besar. Bagaimana saya bisa mencegah hal ini terjadi?
translatetransformasi yang berisi koordinat dalam notasi ilmiah.
Jawaban:
Ada Number.toFixed , tetapi menggunakan notasi ilmiah jika angkanya> = 1e21 dan memiliki ketepatan maksimum 20. Selain itu, Anda dapat memutar sendiri, tetapi akan berantakan.
function toFixed(x) {
if (Math.abs(x) < 1.0) {
var e = parseInt(x.toString().split('e-')[1]);
if (e) {
x *= Math.pow(10,e-1);
x = '0.' + (new Array(e)).join('0') + x.toString().substring(2);
}
} else {
var e = parseInt(x.toString().split('+')[1]);
if (e > 20) {
e -= 20;
x /= Math.pow(10,e);
x += (new Array(e+1)).join('0');
}
}
return x;
}
Di atas menggunakan pengulangan string murah-'n'-mudah ( (new Array(n+1)).join(str)). Anda bisa mendefinisikanString.prototype.repeat menggunakan Perkalian Petani Rusia dan menggunakannya.
Jawaban ini hanya boleh diterapkan pada konteks pertanyaan: menampilkan sejumlah besar tanpa menggunakan notasi ilmiah. Untuk hal lain, Anda harus menggunakan pustaka BigInt , seperti BigNumber , Leemon's BigInt , atau BigInteger . Ke depan, BigInt asli baru (catatan: bukan Leemon) harus tersedia; Chromium dan peramban yang didasarkan padanya ( Chrome , Edge [v79 +] baru, Brave ) dan Firefox semuanya memiliki dukungan; Dukungan Safari sedang berlangsung.
Begini cara Anda menggunakan BigInt untuk itu: BigInt(n).toString()
Contoh:
Berhati-hatilah , meskipun bilangan bulat apa pun yang Anda hasilkan sebagai angka JavaScript (bukan BigInt) yang lebih dari 15-16 digit (khususnya, lebih besar dari Number.MAX_SAFE_INTEGER + 1[9.007.199.254.740.992]) dapat dibulatkan, karena jenis nomor JavaScript (presisi ganda JavaScript) floating point) tidak dapat secara tepat menampung semua bilangan bulat di luar titik itu. Pada Number.MAX_SAFE_INTEGER + 1saat ini berfungsi dalam kelipatan 2, sehingga tidak dapat menyimpan angka ganjil lagi (dan serupa, pada 18.014.398.509.481.984 itu mulai bekerja dalam kelipatan 4, kemudian 8, lalu 16, ...).
Akibatnya, jika Anda dapat mengandalkan BigIntdukungan, output nomor Anda sebagai string yang Anda berikan ke BigIntfungsi:
const n = BigInt("YourNumberHere");
Contoh:
Math.abs. Terimakasih atas peringatannya.
toFixed(Number.MAX_VALUE) == Number.MAX_VALUEharus kembali benar kalau begitu, tetapi tidak ...
Saya tahu ini adalah pertanyaan yang lebih lama, tetapi baru-baru ini aktif. 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"
Anda dapat menggunakan opsi untuk memformat output.
Number.toLocaleString () putaran setelah 16 tempat desimal, sehingga ...
const myNumb = 586084736227728377283728272309128120398;
console.log( myNumb.toLocaleString('fullwide', { useGrouping: false }) );
... mengembalikan ...
586084736227728400000000000000000000000
Ini mungkin tidak diinginkan jika akurasi penting dalam hasil yang diinginkan.
js console.log( myNumb.toLocaleString('fullwide', { useGrouping: true, maximumSignificantDigits:6}) );
Untuk angka kecil, dan Anda tahu berapa desimal yang Anda inginkan, Anda dapat menggunakan toFixed dan kemudian menggunakan regexp untuk menghapus nol tambahan.
Number(1e-7).toFixed(8).replace(/\.?0+$/,"") //0.000
(1000).toFixed(0).replace(/\.?0+$/,"") // 1, not 1000
satu lagi solusi yang mungkin:
function toFix(i){
var str='';
do{
let a = i%10;
i=Math.trunc(i/10);
str = a+str;
}while(i>0)
return str;
}
Number.MAX_SAFE_INTEGERkemungkinan menderita masalah ini.
Berikut ini adalah varian singkat Number.prototype.toFixedmetode saya yang berfungsi dengan nomor apa pun:
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(p, b) {
return p + Array(b - p.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"
Number. Jika Anda melemparkan yang pertama ke a Number, Anda akan melihat bahwa mereka benar - benar sama: jsfiddle.net/qd6hpnyx/1 . Anda dapat mengambil downvote Anda kembali:P
.0dengan string kosong.
console.log(2.2e307.toFixedSpecial(10)). Maksud saya ... saya mendapatkan beberapa angka nol. Tetap upvoting karena ini tampaknya paling dekat dengan yang saya butuhkan.
Solusi berikut melewati pemformatan eksponensial otomatis untuk angka yang sangat besar dan sangat kecil. Ini adalah solusi outis dengan perbaikan bug: Itu tidak berfungsi untuk angka negatif yang sangat kecil.
function numberToString(num)
{
let numStr = String(num);
if (Math.abs(num) < 1.0)
{
let e = parseInt(num.toString().split('e-')[1]);
if (e)
{
let negative = num < 0;
if (negative) num *= -1
num *= Math.pow(10, e - 1);
numStr = '0.' + (new Array(e)).join('0') + num.toString().substring(2);
if (negative) numStr = "-" + numStr;
}
}
else
{
let e = parseInt(num.toString().split('+')[1]);
if (e > 20)
{
e -= 20;
num /= Math.pow(10, e);
numStr = num.toString() + (new Array(e + 1)).join('0');
}
}
return numStr;
}
// testing ...
console.log(numberToString(+0.0000000000000000001));
console.log(numberToString(-0.0000000000000000001));
console.log(numberToString(+314564649798762418795));
console.log(numberToString(-314564649798762418795));
Jawaban orang lain tidak memberi Anda angka pastinya!
Fungsi ini menghitung angka yang diinginkan secara akurat dan mengembalikannya ke string untuk mencegahnya diubah oleh javascript!
Jika Anda membutuhkan hasil numerik, cukup gandakan hasil fungsi di nomor satu!
function toNonExponential(value) {
// if value is not a number try to convert it to number
if (typeof value !== "number") {
value = parseFloat(value);
// after convert, if value is not a number return empty string
if (isNaN(value)) {
return "";
}
}
var sign;
var e;
// if value is negative, save "-" in sign variable and calculate the absolute value
if (value < 0) {
sign = "-";
value = Math.abs(value);
}
else {
sign = "";
}
// if value is between 0 and 1
if (value < 1.0) {
// get e value
e = parseInt(value.toString().split('e-')[1]);
// if value is exponential convert it to non exponential
if (e) {
value *= Math.pow(10, e - 1);
value = '0.' + (new Array(e)).join('0') + value.toString().substring(2);
}
}
else {
// get e value
e = parseInt(value.toString().split('e+')[1]);
// if value is exponential convert it to non exponential
if (e) {
value /= Math.pow(10, e);
value += (new Array(e + 1)).join('0');
}
}
// if value has negative sign, add to it
return sign + value;
}
Gunakan .toPrecision,, .toFixeddll. Anda dapat menghitung jumlah digit dalam nomor Anda dengan mengonversinya menjadi string dengan .toStringkemudian melihatnya .length.
(2e64).toString()akan kembali "2e+64", jadi .lengthtidak ada gunanya.
Inilah yang akhirnya saya gunakan untuk mengambil nilai dari input, memperluas angka kurang dari 17 digit dan mengubah angka eksponensial menjadi x10 y
// e.g.
// niceNumber("1.24e+4") becomes
// 1.24x10 to the power of 4 [displayed in Superscript]
function niceNumber(num) {
try{
var sOut = num.toString();
if ( sOut.length >=17 || sOut.indexOf("e") > 0){
sOut=parseFloat(num).toPrecision(5)+"";
sOut = sOut.replace("e","x10<sup>")+"</sup>";
}
return sOut;
}
catch ( e) {
return num;
}
}
Anda dapat mengulangi angka dan mencapai pembulatan
// fungsionalitas untuk mengganti char pada indeks yang diberikan
String.prototype.replaceAt=function(index, character) {
return this.substr(0, index) + character + this.substr(index+character.length);
}
// pengulangan nomor dimulai
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--;
}
}
Saya mencoba bekerja dengan bentuk string daripada angka dan ini sepertinya berhasil. Saya hanya menguji ini di Chrome tetapi harus universal:
function removeExponent(s) {
var ie = s.indexOf('e');
if (ie != -1) {
if (s.charAt(ie + 1) == '-') {
// negative exponent, prepend with .0s
var n = s.substr(ie + 2).match(/[0-9]+/);
s = s.substr(2, ie - 2); // remove the leading '0.' and exponent chars
for (var i = 0; i < n; i++) {
s = '0' + s;
}
s = '.' + s;
} else {
// positive exponent, postpend with 0s
var n = s.substr(ie + 1).match(/[0-9]+/);
s = s.substr(0, ie); // strip off exponent chars
for (var i = 0; i < n; i++) {
s += '0';
}
}
}
return s;
}
Saya pikir mungkin ada beberapa jawaban yang sama, tetapi ada satu hal yang saya kemukakan
// If you're gonna tell me not to use 'with' I understand, just,
// it has no other purpose, ;( andthe code actually looks neater
// 'with' it but I will edit the answer if anyone insists
var commas = false;
function digit(number1, index1, base1) {
with (Math) {
return floor(number1/pow(base1, index1))%base1;
}
}
function digits(number1, base1) {
with (Math) {
o = "";
l = floor(log10(number1)/log10(base1));
for (var index1 = 0; index1 < l+1; index1++) {
o = digit(number1, index1, base1) + o;
if (commas && i%3==2 && i<l) {
o = "," + o;
}
}
return o;
}
}
// Test - this is the limit of accurate digits I think
console.log(1234567890123450);
Catatan: ini hanya seakurat fungsi matematika javascript dan memiliki masalah saat menggunakan log, bukan log10 pada baris sebelum for for loop; ia akan menulis 1000 di base-10 sebagai 000 jadi saya mengubahnya ke log10 karena kebanyakan orang akan menggunakan base-10.
Ini mungkin bukan solusi yang sangat akurat tetapi saya bangga mengatakan itu dapat berhasil menerjemahkan angka di pangkalan dan dilengkapi dengan opsi untuk koma!
Pertanyaanmu:
number :0x68656c6c6f206f72656f
display:4.9299704811152646e+23
Anda dapat menggunakan ini: https://github.com/MikeMcl/bignumber.js
Pustaka JavaScript untuk aritmatika desimal dan non-desimal presisi arbitrer.
seperti ini:
let ten =new BigNumber('0x68656c6c6f206f72656f',16);
console.log(ten.toString(10));
display:492997048111526447310191
Saya tahu ini bertahun-tahun kemudian, tetapi saya telah mengerjakan masalah yang sama baru-baru ini dan saya ingin memposting solusi saya. Jawaban yang saat ini diterima melapisi bagian eksponen dengan 0, dan menambang mencoba untuk menemukan jawaban yang tepat, meskipun secara umum itu tidak sepenuhnya akurat untuk angka yang sangat besar karena batas JS dalam presisi titik mengambang.
Ini berhasil Math.pow(2, 100), mengembalikan nilai yang benar dari 1267650600228229401496703205376.
function toFixed(x) {
var result = '';
var xStr = x.toString(10);
var digitCount = xStr.indexOf('e') === -1 ? xStr.length : (parseInt(xStr.substr(xStr.indexOf('e') + 1)) + 1);
for (var i = 1; i <= digitCount; i++) {
var mod = (x % Math.pow(10, i)).toString(10);
var exponent = (mod.indexOf('e') === -1) ? 0 : parseInt(mod.substr(mod.indexOf('e')+1));
if ((exponent === 0 && mod.length !== i) || (exponent > 0 && exponent !== i-1)) {
result = '0' + result;
}
else {
result = mod.charAt(0) + result;
}
}
return result;
}
console.log(toFixed(Math.pow(2,100))); // 1267650600228229401496703205376
toFixed(Number.MAX_VALUE) == Number.MAX_VALUE
function printInt(n) { return n.toPrecision(100).replace(/\..*/,""); }
dengan beberapa masalah:
Menghilangkan ekspresi reguler. Ini tidak memiliki masalah presisi dan tidak banyak kode.
function toPlainString(num) {
return (''+num).replace(/(-?)(\d*)\.?(\d+)e([+-]\d+)/,
function(a,b,c,d,e) {
return e < 0
? b + '0.' + Array(1-e-c.length).join(0) + c + d
: b + c + d + Array(e-d.length+1).join(0);
});
}
console.log(toPlainString(12345e+12));
console.log(toPlainString(12345e+24));
console.log(toPlainString(-12345e+24));
console.log(toPlainString(12345e-12));
console.log(toPlainString(123e-12));
console.log(toPlainString(-123e-12));
console.log(toPlainString(-123.45e-56));
Jika Anda hanya melakukannya untuk tampilan, Anda bisa membuat array dari angka sebelum dibulatkan.
var num = Math.pow(2, 100);
var reconstruct = [];
while(num > 0) {
reconstruct.unshift(num % 10);
num = Math.floor(num / 10);
}
console.log(reconstruct.join(''));
Saat ini tidak ada fungsi asli untuk membubarkan notasi ilmiah. Namun, untuk tujuan ini Anda harus menulis fungsionalitas Anda sendiri.
Ini milik saya:
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("");
}
Anda dapat menggunakan modul dari-eksponensial . Ini ringan dan sepenuhnya teruji.
import fromExponential from 'from-exponential';
fromExponential(1.123e-10); // => '0.0000000001123'
Anda juga dapat menggunakan YourJS.fullNumber. Misalnya YourJS.fullNumber(Number.MAX_VALUE)hasil berikut ini:
179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Ini juga berfungsi untuk jumlah yang sangat kecil. YourJS.fullNumber(Number.MIN_VALUE)mengembalikan ini:
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
Penting untuk dicatat bahwa fungsi ini akan selalu mengembalikan angka hingga sebagai string tetapi akan mengembalikan angka yang tidak terbatas (mis. NaNAtau Infinity) sebagai undefined.
Anda dapat mengujinya di YourJS Console di sini .
Anda bisa menggunakan number.toString(10.1):
console.log(Number.MAX_VALUE.toString(10.1));
Catatan: Saat ini berfungsi di Chrome, tetapi tidak di Firefox. Spesifikasi mengatakan bahwa radix harus berupa bilangan bulat, sehingga ini menghasilkan perilaku yang tidak dapat diandalkan.
10.1 atau 10tidak sama dengan itu.
Saya memiliki masalah yang sama dengan oracle yang mengembalikan notasi ilmiah, tetapi saya membutuhkan nomor aktual untuk url. Saya hanya menggunakan trik PHP dengan mengurangi nol, dan saya mendapatkan nomor yang benar.
misalnya 5.4987E7 adalah val.
newval = val - 0;
newval sekarang sama dengan 54987000