[Javascript] 어떻게 자바 스크립트에서 float을 포맷?


Answers

숫자를 반올림하는 함수가 있습니다. 예 :

var x = 5.0364342423;
print(x.toFixed(2));

5.04가 인쇄됩니다.

편집 : Fiddle

Question

JavaScript에서는 부동 소수점을 문자열로 변환 할 때 소수점 이하 2 자리를 어떻게 얻을 수 있습니까? 예 : 0.3445434 대신 0.34.




/** don't spend 5 minutes, use my code **/
function prettyFloat(x,nbDec) { 
    if (!nbDec) nbDec = 100;
    var a = Math.abs(x);
    var e = Math.floor(a);
    var d = Math.round((a-e)*nbDec); if (d == nbDec) { d=0; e++; }
    var signStr = (x<0) ? "-" : " ";
    var decStr = d.toString(); var tmp = 10; while(tmp<nbDec && d*tmp < nbDec) {decStr = "0"+decStr; tmp*=10;}
    var eStr = e.toString();
    return signStr+eStr+"."+decStr;
}

prettyFloat(0);      //  "0.00"
prettyFloat(-1);     // "-1.00"
prettyFloat(-0.999); // "-1.00"
prettyFloat(0.5);    //  "0.50"



Dony와 ArteQ에서 언급했듯이 반올림은 정밀도의 손실로 영향을받습니다 (즉, 0.5는 0.49999가 될 수 있습니다 ...). 결과적으로 반올림은 반반반반 기도 아니며 다른 일관된 반올림 방법도 아니며 사용하는 방법에 관계없이 일관성없는 결과를 가져옵니다.

실제로 toFixed 도 영향을받습니다.

(0.335).toFixed(2) == 0.34
(0.345).toFixed(2) == 0.34

그래서 어떤 방법을 사용 하든지, 반올림에 일관성이 필요하면 엡실론을 추가 (또는 제거)하는 것이 좋습니다.

예 : toFixed 사용하여 반올림 반올림하기 :

var epsilon = 0.001;
(0.335 + epsilon).toFixed(2) == 0.34;
(0.345 + epsilon).toFixed(2) == 0.35;

자신의 함수를 작성하고, 계산 전에 엡실론을 추가 / 삭제하는 경우도 마찬가지입니다.

업데이트 :

matias가 지적했듯이이 메서드에는 결함이 있습니다. 즉, 엡실론 값인 0.334999999 ...는 항상 0.35 대신 0.34로 반올림됩니다. 그러므로 우리는 일관성이 있지만 "표준 반올림"은 아닙니다.




여기서 내가 생각하는 핵심은 정확하게 먼저 반올림 한 다음 String으로 변환 할 수 있다는 것입니다.

function roundOf(n, p) {
    const n1 = n * Math.pow(10, p + 1);
    const n2 = Math.floor(n1 / 10);
    if (n1 >= (n2 * 10 + 5)) {
        return (n2 + 1) / Math.pow(10, p);
    }
    return n2 / Math.pow(10, p);
}

// All edge cases listed in this thread
roundOf(95.345, 2); // 95.35
roundOf(95.344, 2); // 95.34
roundOf(5.0364342423, 2); // 5.04
roundOf(0.595, 2); // 0.60
roundOf(0.335, 2); // 0.34
roundOf(0.345, 2); // 0.35
roundOf(551.175, 2); // 551.18
roundOf(0.3445434, 2); // 0.34

이제 toFixed (p)를 사용하여이 값을 안전하게 포맷 할 수 있습니다. 그래서 귀하의 구체적인 경우 :

roundOf(0.3445434, 2).toFixed(2); // 0.34



알고 있어야 할 또 하나의 문제는 toFixed() 가 숫자 끝에 불필요한 0을 생성 할 수 있다는 것입니다. 예 :

var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"

아이디어는 RegExp 사용하여 출력을 정리하는 것입니다.

function humanize(x){
  return x.toFixed(6).replace(/\.?0*$/,'');
}

RegExp 는 후행 0 (및 선택적으로 소수점)과 일치하여 정수도 잘 보이는지 확인합니다.

humanize(23-7.37)
"15.63"
humanize(1200)
"1200"
humanize(1200.03)
"1200.03"
humanize(3/4)
"0.75"
humanize(4/3)
"1.333333"



    You can try this if you want don't want to use rounding
 function myFunction() {
            var str = 12.234556; 
            str = str.toString().split('.');
            var res = str[1].slice(0, 2);
            document.getElementById("demo").innerHTML = str[0]+'.'+res;
        }
output:12.23

str.toString().split('.') 은 부동 소수점 숫자를 문자열로 변환 한 다음 '.'로 분리합니다.

결과 변수는 두 개의 문자열 유형 요소가있는 배열입니다. 첫 번째 요소는 12이고 두 번째 요소는 234556입니다.

str[1].slice(0, 2) 는 두 번째 (234556) 문자열을 처음 두 개의 char

그런 다음 str[0]+'.'+res 통해 첫 번째 결과 문자열을 연결합니다 str[0]+'.'+res

희망이 도움이 될 것입니다




어쩌면 소수 구분 기호를 원할 것입니까? 여기에 방금 만든 함수가 있습니다.

function formatFloat(num,casasDec,sepDecimal,sepMilhar) {
    if (num < 0)
    {
        num = -num;
        sinal = -1;
    } else
        sinal = 1;
    var resposta = "";
    var part = "";
    if (num != Math.floor(num)) // decimal values present
    {
        part = Math.round((num-Math.floor(num))*Math.pow(10,casasDec)).toString(); // transforms decimal part into integer (rounded)
        while (part.length < casasDec)
            part = '0'+part;
        if (casasDec > 0)
        {
            resposta = sepDecimal+part;
            num = Math.floor(num);
        } else
            num = Math.round(num);
    } // end of decimal part
    while (num > 0) // integer part
    {
        part = (num - Math.floor(num/1000)*1000).toString(); // part = three less significant digits
        num = Math.floor(num/1000);
        if (num > 0)
            while (part.length < 3) // 123.023.123  if sepMilhar = '.'
                part = '0'+part; // 023
        resposta = part+resposta;
        if (num > 0)
            resposta = sepMilhar+resposta;
    }
    if (sinal < 0)
        resposta = '-'+resposta;
    return resposta;
}