JavaScript는 숫자가 커지면 큰 INT 를 과학적 표기법으로 변환합니다 . 이 문제가 발생하지 않도록하려면 어떻게해야합니까?
translate과학적 표기법으로 좌표가 포함 된 변환이 발생하면 D3에서 예외가 발생합니다 .
JavaScript는 숫자가 커지면 큰 INT 를 과학적 표기법으로 변환합니다 . 이 문제가 발생하지 않도록하려면 어떻게해야합니까?
translate과학적 표기법으로 좌표가 포함 된 변환이 발생하면 D3에서 예외가 발생합니다 .
답변:
있다 Number.toFixed는 하지만, 수> = 1E21이며, 그 외 (20)의 최대 정밀도를 가지고 있다면, 당신은 자신의 롤 수있는 과학적 표기법을 사용하지만 지저분한 될 것입니다.
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;
}
위의 저렴하고 쉬운 문자열 반복 ( (new Array(n+1)).join(str))을 사용합니다. String.prototype.repeatRussian Peasant Multiplication을 사용하여 정의 하고 대신 사용할 수 있습니다.
이 답변은 질문의 맥락에만 적용되어야합니다 : 과학적 표기법을 사용하지 않고 많은 수를 표시합니다. 다른 경우 에는 BigNumber , Leemon 's BigInt 또는 BigInteger 와 같은 BigInt 라이브러리를 사용해야합니다 . 앞으로는 새로운 기본 BigInt (참고 : Leemon이 아닌)를 사용할 수 있어야합니다. Chrome 및 Chrome 기반 브라우저 ( Chrome , 새로운 Edge [v79 +], Brave ) 및 Firefox는 모두 지원합니다. Safari의 지원이 진행 중입니다.
BigInt를 사용하는 방법은 다음과 같습니다. BigInt(n).toString()
예:
조심 이상의 15 ~ 16 자리의 자바 스크립트 번호 (안에서 BigInt) 등의 정수을 출력 (특히,보다 큰 것을,하지만, Number.MAX_SAFE_INTEGER + 1[9,007,199,254,740,992가), 자바 스크립트의 숫자 형 때문에 (IEEE-754 배정 밀도 둥근 될 수 있습니다 부동 소수점)은 해당 지점 이상의 모든 정수를 정확하게 보유 할 수 없습니다. 현재 Number.MAX_SAFE_INTEGER + 12의 배수로 작동하므로 더 이상 홀수를 가질 수 없습니다 (그리고 유사하게 18,014,398,509,481,984에서는 4, 8, 16, ...의 배수로 작동하기 시작합니다).
따라서 BigInt지원에 의존 할 수 있으면 BigInt함수에 전달하는 문자열로 숫자를 출력하십시오 .
const n = BigInt("YourNumberHere");
예:
Math.abs. 헤드 업 주셔서 감사합니다.
toFixed(Number.MAX_VALUE) == Number.MAX_VALUE그때 사실을 반환해야하지만, 그렇지 않습니다 ...
나는 이것이 오래된 질문이라는 것을 알고 있지만 최근에 활성화되어 있음을 보여줍니다. MDN에서 LocaleString
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
의도 한 결과에 정확성이 중요한 경우에는 바람직하지 않습니다.
js console.log( myNumb.toLocaleString('fullwide', { useGrouping: true, maximumSignificantDigits:6}) );
하나 더 가능한 해결책 :
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_INTEGER는이 문제가 발생할 수 있습니다.
다음은 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(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. 첫 번째 것을 a로 캐스팅하면 jsfiddle.net/qd6hpnyx/1 과 완전히 동일한 Number것을 알 수 있습니다 . downvote를 되 찾을 수 있습니다:P
.0을 빈 문자열로 바꾸는 것이 좋습니다.
console.log(2.2e307.toFixedSpecial(10))있습니다. 내 말은 ... 몇 개의 후행 0을 얻습니다. 어쨌든 이것은 내가 필요한 것에 가장 가깝게 보이기 때문에 상향 조정합니다.
다음 솔루션은 매우 크고 작은 숫자에 대한 자동 지수 형식을 무시합니다. 이것은 버그 수정 이있는 outis의 솔루션 입니다. 매우 작은 음수에는 작동하지 않았습니다.
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));
다른 사람들의 대답은 당신에게 정확한 숫자를 제공하지 않습니다!
이 함수는 원하는 숫자를 정확하게 계산하고 문자열로 반환하여 자바 스크립트에 의해 변경되지 않도록합니다!
수치 결과가 필요한 경우 함수 결과에 1을 곱하십시오!
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;
}
사용 .toPrecision, .toFixed등 당신과 함께 문자열로 변환하여 전화 번호의 자릿수를 믿을 수있는 .toString다음의보고 .length.
(2e64).toString()반환 "2e+64"하므로 .length쓸모가 없습니다.
이것은 입력에서 값을 가져 와서 17 자리 미만의 숫자를 확장하고 지수를 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;
}
}
당신은 숫자를 반복하고 반올림을 달성 할 수 있습니다
// 주어진 인덱스에서 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--;
}
}
숫자가 아닌 문자열 형식으로 작업을 시도했지만 작동하는 것 같습니다. Chrome에서만 테스트했지만 보편적이어야합니다.
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;
}
비슷한 대답이 몇 가지있을 수 있지만 여기에 내가 생각해 낸 것이 있습니다.
// 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);
참고 : 이것은 자바 스크립트 수학 함수만큼 정확하며 for 루프 앞 줄에 log10 대신 log를 사용할 때 문제가 있습니다. 사람들은 어쨌든 대부분 10을 사용하기 때문에 10을 1000으로 기록합니다.
이것은 매우 정확한 해결책은 아니지만 기본적으로 숫자를 성공적으로 번역 할 수 있으며 쉼표 옵션이 제공된다고 자랑스럽게 생각합니다!
당신의 질문 :
number :0x68656c6c6f206f72656f
display:4.9299704811152646e+23
이것을 사용할 수 있습니다 : https://github.com/MikeMcl/bignumber.js
임의 정밀도 10 진수 및 비소수 산술을위한 JavaScript 라이브러리.
이처럼 :
let ten =new BigNumber('0x68656c6c6f206f72656f',16);
console.log(ten.toString(10));
display:492997048111526447310191
몇 년 후인 것을 알고 있지만 최근에 비슷한 문제를 해결하고 있었고 솔루션을 게시하고 싶었습니다. 현재 허용되는 답변은 지수 부분을 0으로 채우고 정확한 답변을 찾으려고 시도하지만 일반적으로 부동 소수점 정밀도의 JS 한계 때문에 매우 큰 숫자에는 완벽하게 정확하지는 않습니다.
이것은 Math.pow(2, 100)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(/\..*/,""); }
몇 가지 문제가 있습니다.
정규식 파열. 이것은 정밀도 문제가 없으며 많은 코드가 아닙니다.
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));
현재 과학적 표기법을 녹이는 기본 기능은 없습니다. 그러나이 목적을 위해서는 고유 한 기능을 작성해야합니다.
여기, 내 것이요:
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("");
}
YourJS.fullNumber를 사용할 수도 있습니다. 예를 들어 YourJS.fullNumber(Number.MAX_VALUE)다음과 같은 결과가 나타납니다.
179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
정말 작은 숫자에도 적용됩니다. YourJS.fullNumber(Number.MIN_VALUE)이것을 돌려줍니다 :
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
이 함수는 항상 유한 숫자를 문자열로 반환하지만 무한 수가 아닌 숫자 (예 : NaN또는 Infinity) 는로 반환 undefined합니다.
YourJS Console 에서 테스트 할 수 있습니다 .
당신은 사용할 수 있습니다 number.toString(10.1):
console.log(Number.MAX_VALUE.toString(10.1));
참고 : 현재 Chrome에서는 작동하지만 Firefox에서는 작동하지 않습니다. 사양에 따르면 기수가 정수 여야하므로 신뢰할 수없는 동작이 발생합니다.
10.1 하거나 10동등한 것은 없습니다.