자바 스크립트에서 float 형식을 지정하는 방법은 무엇입니까?


427

JavaScript에서 부동 소수점을 문자열로 변환 할 때 소수점 이하 두 자리 만 얻는 방법은 무엇입니까? 예를 들어 0.3445434 대신 0.34입니다.


16
일부 따기 : 첫 두 자리를 제외한 모든 자리를 '잘라내시겠습니까?'또는 두 자리로 반올림 하시겠습니까?
xtofl

답변:


232
var result = Math.round(original*100)/100;

코드가 자명하지 않은 경우 의 specifics .

편집 : ... 또는 Tim Büthe가toFixed 제안한대로 사용 하십시오 . 그 하나를 잊어 버렸습니다. 알려 줘서 고마워요.


1
나는 그것이 따라서에서는 toFixed이 나를 위해 일하지 않은 문자열 값을 허용하지 않는 라이브러리 "Highchart"이 사용하던, Math.round 내 문제, 덕분에 해결
Swapnil Chincholkar

4
toFixed()뭔가처럼 모방 할 것이다 printf()그러나 C.에서와, toFixed()Math.round()다르게 반올림 처리합니다. 이 경우, toFixed()같은 종류의 효과 Math.floor()가있을 것입니다 (원래에 10 ^ n을 곱한 후 toFixed()n 자리로 전화하는 것을 허용 함). 답변의 "정확도"는 OP가 원하는 것에 매우 의존하며, 둘 다 자체 방식으로 "정확합니다".
DDPWNAGE

838

숫자를 반올림하는 기능이 있습니다. 예를 들면 다음과 같습니다.

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

5.04를 인쇄합니다.

편집 : 바이올린


7
브라우저에서 print ()를 사용하지 않는 것이 좋습니다.
cobbal

70
이것에주의하십시오. toFixed ()는 문자열을 반환합니다 : var x = 5.036432346; var y = x.toFixed(2) + 100; y동일합니다"5.03100"
Vlad

5
(1e100) .toFixed (2) === "1e + 100"
qbolec

7
또한, 일관성 반올림 조심 : (0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)...
스키 피 르 그랜드 Gourou

3
toFixed와 동일하지만 일관된 반올림을 검색하는 경우 toLocaleString : (0.345) .toLocaleString ( 'en-EN', {minimumFractionDigits : 2, maximumFractionDigits : 2})
fred727

185

다음을 사용할 때주의하십시오 toFixed():

첫째, 숫자의 반올림은 숫자의 이진 표현을 사용하여 이루어 지므로 예기치 않은 동작이 발생할 수 있습니다. 예를 들어

(0.595).toFixed(2) === '0.59'

대신에 '0.6'.

둘째,에 IE 버그가 toFixed()있습니다. IE (적어도 버전 7까지는 IE8을 확인하지 않음)에서 다음 사항이 적용됩니다.

(0.9).toFixed(0) === '0'

kkyy의 제안을 따르거나 사용자 정의 toFixed()기능 을 사용하는 것이 좋습니다.

function toFixed(value, precision) {
    var power = Math.pow(10, precision || 0);
    return String(Math.round(value * power) / power);
}

예, 가격을 예측하는 코드를 만들 때 매우 중요합니다. 감사! +1
Fabio Milheiro

10
.toFixed()반환 값에 기본 메소드를 추가하는 것이 좋습니다 . 필요한 정밀도를 추가합니다. 예를 들어 다음 return (Math.round(value * power) / power).toFixed(precision);과 같이 값을 문자열로 반환합니다. 그렇지 않으면, (20)의 정밀도는 작은 소수 무시됩니다
윌리엄 조스 Crowcroft

3
한 가지 참고 사항 toFixed: 정밀도를 높이면 예기치 않은 결과가 발생할 수 있습니다. (1.2).toFixed(16) === "1.2000000000000000", 반면 (1.2).toFixed(17) === "1.19999999999999996"Firefox / Chrome; IE8에서는 IE8이 내부적으로 제공 할 수있는 정밀도가 낮아지지 않습니다.
jakub.g

2
(0.598).toFixed(2)생산 조차 하지 않으므로 양해 바랍니다 0.6. 그것은 생산한다 0.60:)
qbolec

1
또한 일치하지 않는 반올림에주의하십시오 (0.335).toFixed(2) == 0.34 == (0.345).toFixed(2).
Skippy le Grand Gourou

36

알아야 할 또 하나의 문제 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"

Number.prototype.minFixed = function (decimals) {return this.toFixed (decimals) .replace (/ \.? 0 * $ /, ""); }
Luc Bloom

이것은 받아 들여야하며 후행 0은 성가시다. 나는이 솔루션을 정확하게 찾고 있었다.
exoslav

1
후행 0은 성가시다. 그러나 이것은 "toFixed"메소드 이름이 약속 한
바이다

11
var x = 0.3445434
x = Math.round (x*100) / 100 // this will make nice rounding

Math.round (1.015 * 100) / 100은 1.01을 제공하지만 1.02?
gaurav5430

6

승수를 사용하여 떠 다니는 모든 솔루션에 문제가 있습니다. kkyy와 Christoph의 솔루션은 모두 불행히도 잘못되었습니다.

번호 코드를 테스트하십시오 551.175 2 소수 자릿수가 - 그것은 반올림됩니다 551.17 그것이 있어야하는 동안 551.18을 ! 그러나 당신이 전을 테스트한다면. 451.175 괜찮습니다-451.18. 따라서이 오류를 한 눈에 파악하기는 어렵습니다.

곱하기 문제가 있습니다 : 551.175 * 100 = 55117.49999999999 (ups!)

그래서 내 생각은 Math.round ()를 사용하기 전에 toFixed ()로 처리하는 것입니다.

function roundFix(number, precision)
{
    var multi = Math.pow(10, precision);
    return Math.round( (number * multi).toFixed(precision + 1) ) / multi;
}

1
그것은 js의 산술 문제입니다 : (551.175 * 10 * 10)! == (551.175 * 100). 실제 소수가 아닌 결과에 대해 쉼표를 이동하려면 소수 증분을 사용해야합니다.
Kir Kanos

그러나이를 인식하면 +1 toFixed에도 영향을받습니다. (0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)… 어떤 방법을 사용하든 반올림 전에 엡실론을 더 잘 추가하십시오.
Skippy le Grand Gourou 15:56에

5

여기서 핵심은 올바르게 올림 한 다음 문자열로 변환하는 것입니다.

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

3

라운드가없는 문자열을 원한다면이 RegEx를 사용할 수 있습니다 (아마도 가장 효율적인 방법은 아니지만 실제로는 쉽습니다)

(2.34567778).toString().match(/\d+\.\d{2}/)[0]
// '2.34'

1
function trimNumber(num, len) {
  const modulu_one = 1;
  const start_numbers_float=2;
  var int_part = Math.trunc(num);
  var float_part = String(num % modulu_one);
      float_part = float_part.slice(start_numbers_float, start_numbers_float+len);
  return int_part+'.'+float_part;
}

세미콜론이 없다는 것을 제외하고는 큰 대답입니다. 나는에 편집 마지막 행을도에 있었다 : return float_part ? int_part+'.'+float_part : int_part;당신이 정수를 통과, 그렇지 않은 경우는 마지막에 점으로 수를 반환 (예 입력 : 2100출력을 : 2100.)
쿠바 시모 노브 스키

0

아마도 소수점 구분 기호를 원할까요? 방금 만든 기능은 다음과 같습니다.

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;
}

0

곱셈이나 나눗셈을 사용하여 실제 값으로 x.xx5가있는 가격의 반올림을 피할 수있는 방법은 없습니다. 고객 측에서 정확한 가격을 계산해야하는 경우 모든 금액을 센트 단위로 유지해야합니다. 이는 JavaScript에서 숫자 값의 내부 표현의 특성 때문입니다. Excel은 동일한 문제를 겪으므로 대부분의 사람들은이 현상으로 인한 작은 오류를 알지 못합니다. 그러나 계산 된 값을 많이 추가 할 때마다 오류가 누적 될 수 있지만, 계산 순서 및 최종 결과의 오류를 최소화하기위한 다른 방법과 관련된 전체 이론이 있습니다. 십진수 값의 문제를 강조하기 위해 JavaScript에서 0.1 + 0.2는 정확히 0.3과 같지 않지만 1 + 2는 3과 같습니다.


해결책은 전체 부분과 소수 부분을 분리하고 float를 사용하는 대신 base 10에서 정수로 표현하는 것입니다. 여기서는 prettyPrint에 문제없이 작동하지만 일반적으로 base와 다른 것을 선택해야합니다. 실수와 다른 각각의 문제가 있습니다
18 분 54 초

"엑셀은 같은 문제를 겪고있다". 소스?
gaurav5430

0
/** 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"

0

이 코드를 사용하여 수레를 형식화합니다. 그것은 기반 toPrecision()이지만 불필요한 0을 제거합니다. 정규식을 단순화하는 방법에 대한 제안을 환영합니다.

function round(x, n) {
    var exp = Math.pow(10, n);
    return Math.floor(x*exp + 0.5)/exp;
}

사용 예 :

function test(x, n, d) {
    var rounded = rnd(x, d);
    var result = rounded.toPrecision(n);
    result = result.replace(/\.?0*$/, '');
    result = result.replace(/\.?0*e/, 'e');
    result = result.replace('e+', 'e');
    return result;  
}

document.write(test(1.2000e45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2000e+45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2340e45, 3, 2) + '=' + '1.23e45' + '<br>');
document.write(test(1.2350e45, 3, 2) + '=' + '1.24e45' + '<br>');
document.write(test(1.0000, 3, 2) + '=' + '1' + '<br>');
document.write(test(1.0100, 3, 2) + '=' + '1.01' + '<br>');
document.write(test(1.2340, 4, 2) + '=' + '1.23' + '<br>');
document.write(test(1.2350, 4, 2) + '=' + '1.24' + '<br>');
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.