JavaScript에서 많은 수의 과학적 표기법을 피하는 방법은 무엇입니까?
JavaScript는 숫자가 커지면 큰 INT를 과학적 표기법으로 변환합니다. 이 문제가 발생하지 않도록하려면 어떻게해야합니까?
있다 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.repeat
Russian Peasant Multiplication을 사용하여 정의 하고 대신 사용할 수 있습니다.
이 답변은 질문의 맥락에만 적용되어야합니다 : 과학적 표기법을 사용하지 않고 많은 수를 표시합니다. 다른 경우 에는 BigNumber , Leemon 's BigInt 또는 BigInteger 와 같은 BigInt 라이브러리를 사용해야합니다 . 앞으로 제안 된 BigInt (참고 : Leemon의 것이 아님)는 기본적으로 지원되어야합니다 ( Chrome 은 지원하며 Firefox 에서 작동하고 있습니다 ).
나는 이것이 오래된 질문이라는 것을 알고 있지만 최근에 활성화되어 있음을 보여줍니다. 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
의도 한 결과에 정확성이 중요한 경우에는 바람직하지 않습니다.
작은 숫자의 경우 원하는 소수를 알고 있으면 toFixed를 사용하고 정규 표현식을 사용하여 후행 0을 제거 할 수 있습니다.
Number(1e-7).toFixed(8).replace(/\.?0+$/,"") //0.000
하나 더 가능한 해결책 :
function toFix(i){
var str='';
do{
let a = i%10;
i=Math.trunc(i/10);
str = a+str;
}while(i>0)
return str;
}
다음은 Number.prototype.toFixed
임의의 숫자와 작동하는 짧은 변형 방법입니다.
Number.prototype.toFixedSpecial = function(n) {
var str = this.toFixed(n);
if (str.indexOf('e+') < 0)
return str;
// if number is in scientific notation, pick (b)ase and (p)ower
return str.replace('.', '').split('e+').reduce(function(p, b) {
return p + Array(b - p.length + 2).join(0);
}) + '.' + Array(n + 1).join(0);
};
1e21.toFixedSpecial(2); // "1000000000000000000000.00"
2.1e24.toFixedSpecial(0); // "2100000000000000000000000"
1234567..toFixedSpecial(1); // "1234567.0"
1234567.89.toFixedSpecial(3); // "1234567.890"
다음 솔루션은 매우 크고 작은 숫자에 대한 자동 지수 형식을 무시합니다. 이것은 버그 수정 이있는 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));
이것은 입력에서 값을 가져 와서 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;
}
}
다른 사람의 대답은 당신에게 정확한 숫자를 제공하지 않습니다!
이 함수는 원하는 숫자를 정확하게 계산하고 문자열로 반환하여 자바 스크립트에 의해 변경되지 않도록합니다!
수치 결과가 필요한 경우 함수 결과에 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;
}
당신은 숫자를 반복하고 반올림을 달성 할 수 있습니다
// 주어진 인덱스에서 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);
Note: this is only as accurate as the javascript math functions and has problems when using log instead of log10 on the line before the for loop; it will write 1000 in base-10 as 000 so I changed it to log10 because people will mostly be using base-10 anyways.
This may not be a very accurate solution but I'm proud to say it can successfully translate numbers across bases and comes with an option for commas!
Use .toPrecision
, .toFixed
, etc. You can count the number of digits in your number by converting it to a string with .toString
then looking at its .length
.
I know it's many years later, but I had been working on a similar issue recently and I wanted to post my solution. The currently accepted answer pads out the exponent part with 0's, and mine attempts to find the exact answer, although in general it isn't perfectly accurate for very large numbers because of JS's limit in floating point precision.
This does work for Math.pow(2, 100)
, returning the correct value of 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
Your question:
number :0x68656c6c6f206f72656f
display:4.9299704811152646e+23
You can use this: https://github.com/MikeMcl/bignumber.js
A JavaScript library for arbitrary-precision decimal and non-decimal arithmetic.
like this:
let ten =new BigNumber('0x68656c6c6f206f72656f',16);
console.log(ten.toString(10));
display:492997048111526447310191
If you are just doing it for display, you can build an array from the digits before they're rounded.
var num = Math.pow(2, 100);
var reconstruct = [];
while(num > 0) {
reconstruct.unshift(num % 10);
num = Math.floor(num / 10);
}
console.log(reconstruct.join(''));
Currently there is no native function to dissolve scientific notation. However, for this purpose you must write your own functionality.
Here is my:
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("");
}
You can use from-exponential module. It is lightweight and fully tested.
import fromExponential from 'from-exponential';
fromExponential(1.123e-10); // => '0.0000000001123'
You can also use YourJS.fullNumber. For instance YourJS.fullNumber(Number.MAX_VALUE)
results in the following: 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
It also works for really small numbers. YourJS.fullNumber(Number.MIN_VALUE)
returns this: 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
It is important to note that this function will always return finite numbers as strings but will return non-finite numbers (eg. NaN
or Infinity
) as undefined
.
You can test it out in the YourJS Console here.
function printInt(n) { return n.toPrecision(100).replace(/\..*/,""); }
with some issues:
- 0.9 is displayed as "0"
- -0.9 is displayed as "-0"
- 1e100 is displayed as "1"
- works only for numbers up to ~1e99 => use other constant for greater numbers; or smaller for optimization.
You can use number.toString(10.1)
:
console.log(Number.MAX_VALUE.toString(10.1));
Note: This currently works in Chrome, but not in Firefox. The specification says the radix has to be an integer, so this results in unreliable behavior.
I had the same issue with oracle returning scientic notation, but I needed the actual number for a url. I just used a PHP trick by subtracting zero, and I get the correct number.
for example 5.4987E7 is the val.
newval = val - 0;
newval now equals 54987000
'Programing' 카테고리의 다른 글
파이썬에서 정수를 이진수로 변환 (0) | 2020.06.09 |
---|---|
입력 유효성 검사가 실패 할 때 Angularjs가 양식 제출을 방지 (0) | 2020.06.09 |
"로컬 복사"및 프로젝트 참조에 대한 모범 사례는 무엇입니까? (0) | 2020.06.08 |
.py 파일을 구문 분석하고 AST를 읽고 수정 한 다음 수정 된 소스 코드를 다시 작성하십시오. (0) | 2020.06.08 |
"단위 테스트 작성"은 어디에 있습니까? (0) | 2020.06.08 |