JavaScript chuyển đổi một INT lớn thành ký hiệu khoa học khi số lượng trở nên lớn. Làm thế nào tôi có thể ngăn chặn điều này xảy ra?
translatephép biến đổi có chứa tọa độ trong ký hiệu khoa học.
JavaScript chuyển đổi một INT lớn thành ký hiệu khoa học khi số lượng trở nên lớn. Làm thế nào tôi có thể ngăn chặn điều này xảy ra?
translatephép biến đổi có chứa tọa độ trong ký hiệu khoa học.
Câu trả lời:
Có Number.toFixed , nhưng nó sử dụng ký hiệu khoa học nếu số đó> = 1e21 và có độ chính xác tối đa là 20. Khác với điều đó, bạn có thể tự cuộn, nhưng nó sẽ lộn xộn.
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;
}
Ở trên sử dụng sự lặp lại chuỗi giá rẻ '' dễ dàng ( (new Array(n+1)).join(str)). Bạn có thể định nghĩaString.prototype.repeat bằng cách sử dụng phép nhân nông dân Nga và sử dụng thay thế.
Câu trả lời này chỉ nên được áp dụng cho bối cảnh của câu hỏi: hiển thị một số lượng lớn mà không sử dụng ký hiệu khoa học. Đối với bất cứ điều gì khác, bạn nên sử dụng một bigint thư viện, chẳng hạn như BigNumber , Leemon của bigint , hoặc BigInteger . Đi về phía trước, BigInt bản địa mới (lưu ý: không phải của Leemon) nên có sẵn; Chromium và các trình duyệt dựa trên nó ( Chrome , Edge mới [v79 +], Brave ) và Firefox đều có hỗ trợ; Hỗ trợ của Safari đang được tiến hành.
Đây là cách bạn sử dụng BigInt cho nó: BigInt(n).toString()
Thí dụ:
Mặc dù vậy, hãy coi chừng rằng bất kỳ số nguyên nào bạn xuất ra dưới dạng số JavaScript (không phải BigInt) có nhiều hơn 15-16 chữ số (cụ thể, lớn hơn Number.MAX_SAFE_INTEGER + 1[9,007,199,254,740,992]) có thể được làm tròn, bởi vì loại số của JavaScript (độ chính xác kép của JavaScript-754 dấu phẩy động) không thể giữ chính xác tất cả các số nguyên ngoài điểm đó. Vì Number.MAX_SAFE_INTEGER + 1nó hoạt động theo bội số của 2, vì vậy nó không thể giữ các số lẻ nữa (và tương tự, ở 18,014,398,509,481,984, nó bắt đầu hoạt động theo bội số của 4, rồi 8, rồi 16, ...).
Do đó, nếu bạn có thể dựa vào BigInthỗ trợ, hãy xuất số của bạn dưới dạng chuỗi bạn truyền cho BigInthàm:
const n = BigInt("YourNumberHere");
Thí dụ:
Math.abs. Cảm ơn cho những người đứng đầu lên.
toFixed(Number.MAX_VALUE) == Number.MAX_VALUEnên trả về đúng sau đó, nhưng nó không ...
Tôi biết đây là một câu hỏi cũ hơn, nhưng cho thấy hoạt động gần đây. 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"
bạn có thể sử dụng các tùy chọn để định dạng đầu ra.
Số.toLocaleString () làm tròn sau 16 chữ số thập phân, sao cho ...
const myNumb = 586084736227728377283728272309128120398;
console.log( myNumb.toLocaleString('fullwide', { useGrouping: false }) );
... trở về ...
586084736227728400000000000000000000000
Điều này có lẽ là không mong muốn nếu độ chính xác là quan trọng trong kết quả dự định.
js console.log( myNumb.toLocaleString('fullwide', { useGrouping: true, maximumSignificantDigits:6}) );
Đối với số lượng nhỏ và bạn biết có bao nhiêu số thập phân bạn muốn, bạn có thể sử dụng toFixed và sau đó sử dụng biểu thức chính quy để loại bỏ các số 0 ở cuối.
Number(1e-7).toFixed(8).replace(/\.?0+$/,"") //0.000
(1000).toFixed(0).replace(/\.?0+$/,"") // 1, not 1000
thêm một giải pháp khả thi:
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_INTEGERcó khả năng gặp phải vấn đề này.
Đây là biến thể ngắn của Number.prototype.toFixedphương thức hoạt động với bất kỳ số nào:
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. Nếu bạn bỏ cái đầu tiên thành a Number, bạn sẽ thấy rằng chúng hoàn toàn bằng nhau: jsfiddle.net/qd6hpnyx/1 . Bạn có thể lấy lại downvote của mình:P
.0với chuỗi trống.
console.log(2.2e307.toFixedSpecial(10)). Ý tôi là ... tôi nhận được một số không. Nâng cao bằng mọi giá vì điều này có vẻ gần nhất với những gì tôi cần.
Giải pháp sau đây bỏ qua định dạng lũy thừa tự động cho các số rất lớn và rất nhỏ. Đây là giải pháp của outis với một lỗi: Nó không hoạt động đối với các số âm rất nhỏ.
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));
Câu trả lời của người khác không cung cấp cho bạn con số chính xác!
Hàm này tính toán số lượng mong muốn một cách chính xác và trả về nó trong chuỗi để ngăn nó bị thay đổi bởi javascript!
Nếu bạn cần một kết quả bằng số, chỉ cần nhân kết quả của hàm trong số một!
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;
}
Sử dụng .toPrecision, .toFixedv.v. Bạn có thể đếm số chữ số trong số của mình bằng cách chuyển đổi nó thành một chuỗi .toStringsau đó nhìn vào số đó .length.
(2e64).toString()sẽ trở lại "2e+64", như vậy .lengthlà vô ích.
Đây là những gì tôi đã kết thúc bằng cách sử dụng để lấy giá trị từ đầu vào, mở rộng số nhỏ hơn 17 chữ số và chuyển đổi số mũ thành 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;
}
}
Bạn có thể lặp qua số và đạt được làm tròn
// chức năng thay thế char tại chỉ mục đã cho
String.prototype.replaceAt=function(index, character) {
return this.substr(0, index) + character + this.substr(index+character.length);
}
// lặp qua số bắt đầu
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--;
}
}
Tôi đã thử làm việc với dạng chuỗi hơn là số và điều này dường như hoạt động. Tôi mới chỉ thử nghiệm điều này trên Chrome nhưng nó phải là phổ quát:
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;
}
Tôi nghĩ rằng có thể có một số câu trả lời tương tự, nhưng đây là một điều tôi nghĩ ra
// 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);
Lưu ý: điều này chỉ chính xác như các hàm toán học javascript và có vấn đề khi sử dụng log thay vì log10 trên dòng trước vòng lặp for; nó sẽ ghi 1000 trong cơ sở 10 là 000 vì vậy tôi đã đổi nó thành log10 bởi vì mọi người chủ yếu sẽ sử dụng cơ sở 10 dù sao đi nữa.
Đây có thể không phải là một giải pháp rất chính xác nhưng tôi tự hào nói rằng nó có thể dịch thành công các số trên các cơ sở và đi kèm với một tùy chọn cho dấu phẩy!
Câu hỏi của bạn:
number :0x68656c6c6f206f72656f
display:4.9299704811152646e+23
Bạn có thể sử dụng cái này: https://github.com/MikeMcl/bignumber.js
Một thư viện JavaScript cho số học thập phân và không thập phân chính xác tùy ý.
như thế này:
let ten =new BigNumber('0x68656c6c6f206f72656f',16);
console.log(ten.toString(10));
display:492997048111526447310191
Tôi biết đó là nhiều năm sau đó, nhưng tôi đã làm việc về một vấn đề tương tự gần đây và tôi muốn đăng giải pháp của mình. Câu trả lời hiện được chấp nhận nằm ngoài phần số mũ với 0 và tôi cố gắng tìm câu trả lời chính xác, mặc dù nói chung nó không hoàn toàn chính xác đối với các số rất lớn do giới hạn của độ chính xác của dấu phẩy động.
Điều này không hoạt động Math.pow(2, 100), trả về giá trị chính xác của 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(/\..*/,""); }
với một số vấn đề:
Bộc lộ những biểu cảm đều đặn. Điều này không có vấn đề chính xác và không có nhiều mã.
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));
Nếu bạn chỉ làm việc đó để hiển thị, bạn có thể tạo một mảng từ các chữ số trước khi chúng được làm tròn.
var num = Math.pow(2, 100);
var reconstruct = [];
while(num > 0) {
reconstruct.unshift(num % 10);
num = Math.floor(num / 10);
}
console.log(reconstruct.join(''));
Hiện tại không có chức năng bản địa để giải thể ký hiệu khoa học. Tuy nhiên, với mục đích này, bạn phải viết chức năng của riêng bạn.
Đây là:
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("");
}
Bạn có thể sử dụng mô-đun theo cấp số nhân . Nó rất nhẹ và được kiểm tra đầy đủ.
import fromExponential from 'from-exponential';
fromExponential(1.123e-10); // => '0.0000000001123'
Bạn cũng có thể sử dụng YourJS.fullNumber. Ví dụ YourJS.fullNumber(Number.MAX_VALUE)kết quả như sau:
179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Nó cũng hoạt động cho số lượng thực sự nhỏ. YourJS.fullNumber(Number.MIN_VALUE)trả lại cái này
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
Điều quan trọng cần lưu ý là hàm này sẽ luôn trả về số hữu hạn dưới dạng chuỗi nhưng sẽ trả về số không hữu hạn (ví dụ: NaNhoặc Infinity) là undefined.
Bạn có thể kiểm tra nó trong Bảng điều khiển YourJS tại đây .
Bạn có thể sử dụng number.toString(10.1):
console.log(Number.MAX_VALUE.toString(10.1));
Lưu ý: Điều này hiện đang hoạt động trong Chrome, nhưng không phải trong Firefox. Đặc tả cho biết cơ số phải là một số nguyên, do đó, điều này dẫn đến hành vi không đáng tin cậy.
10.1 hoặc 10không có gì là tương đương.
Tôi đã có cùng một vấn đề với ký hiệu khoa học trở lại, nhưng tôi cần số thực tế cho một url. Tôi chỉ sử dụng một thủ thuật PHP bằng cách trừ 0 và tôi nhận được số chính xác.
ví dụ 5,4987E7 là val.
newval = val - 0;
giá trị hiện tại bằng 54987000