Javascript : 반올림 된 숫자를 N 소수로 포맷


104

JavaScript에서 숫자를 소수점 이하 N 자리로 반올림하는 일반적인 방법은 다음과 같습니다.

function roundNumber(num, dec) {
  return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
}

그러나이 방법은 항상 N 소수점 이하 자릿수로 반올림하는 동안 최대 N 소수점 이하 자릿수로 반올림합니다. 예를 들어 "2.0"은 "2"로 반올림됩니다.

어떤 아이디어?


9
일반적으로 toFixed()( developer.mozilla.org/En/Core_JavaScript_1.5_Reference/… ) 사용할 수 있지만 IE에서는 버그가 있습니다. stackoverflow.com/questions/661562/… ; 자신 만의 버전을 작성해야합니다 ...
Christoph

1
@hoju-아마도 수락 된 답변 변경-David의 답변은 IE8 +에 대해 정확하지만 수락 된 답변에는 모든 브라우저에서 심각한 버그가 있습니다.
robocat

@robocat : 진심이야?
Guffa

답변:


25

그것은 반올림 ploblem이 아니라 디스플레이 문제입니다. 숫자는 유효 숫자에 대한 정보를 포함하지 않습니다. 값 2는 2.0000000000000과 같습니다. 반올림 된 값을 문자열로 바꾸면 특정 자릿수를 표시하게됩니다.

다음과 같이 숫자 뒤에 0을 추가 할 수 있습니다.

var s = number.toString();
if (s.indexOf('.') == -1) s += '.';
while (s.length < s.indexOf('.') + 4) s += '0';

(이는 클라이언트의 지역 설정에서 마침표를 소수점 구분 기호로 사용한다고 가정하고 코드가 다른 설정에 대해 작동하려면 더 많은 작업이 필요합니다.)


3
toFixed는 버그가 있습니다. 예를 들어 십진수 : 1.02449999998 if u do dec.toFixed (4) => 1.0244. 대신 1.0245 여야합니다.
Bat_Programmer 2011 년

2
@deepeshk 그러나 toFixed()반올림 후 마지막에 소수를 채우는 데 사용하는 문제는 무엇 입니까?
pauloya

10
어떤 브라우저에서 @deepeshk? Chrome 17에서 시도하고 1.02449999998.toFixed(4)올바르게 반환합니다 1.0245.
Matt Ball

3
@MarkTomlin : 그러면 숫자 대신 문자열이있는 것 같습니다.
Guffa 2013 년

1
.toFixed ()는 최신 브라우저에서 훌륭하게 작동합니다 (Chrome, Firefox, IE11, IE8 테스트). @Bat_Programmer- 버그가 있다고 생각 하는 브라우저 를 명확히하십시오 .
robocat

243

여기에 주어진 모든 것에 대해 더 간단한 접근법이 있다고 생각하며 Number.toFixed()이미 JavaScript로 구현 된 방법 입니다.

간단히 작성하십시오.

var myNumber = 2;

myNumber.toFixed(2); //returns "2.00"
myNumber.toFixed(1); //returns "2.0"

기타...


호주, 어디서 언급 되었나요? 다른 답변을 검토했지만 toFixed 기능이 버그가 있다고보고하는 사람을 찾지 못했습니다. 감사합니다
David

@David : 예를 들어 답변에 대한 의견에 언급되어 있습니다.
Guffa 2015-06-05

13
주의 : toFixed()문자열을 반환합니다.
Jordan Arseno

2
@JordanArseno 이것은 parseInt (myNumber.toFixed (intVar)); 정수 값을 반환하거나 parseFloat (myNumber.toFixed (floatVar)); 사용자에게 소수 자리가있는 경우 부동 소수점을 반환합니다.
Stephen Romero

50

방법을 찾았습니다. 다음은 수정 된 Christoph의 코드입니다.

function toFixed(value, precision) {
    var precision = precision || 0,
        power = Math.pow(10, precision),
        absValue = Math.abs(Math.round(value * power)),
        result = (value < 0 ? '-' : '') + String(Math.floor(absValue / power));

    if (precision > 0) {
        var fraction = String(absValue % power),
            padding = new Array(Math.max(precision - fraction.length, 0) + 1).join('0');
        result += '.' + padding + fraction;
    }
    return result;
}

"+ 1"을 추가 한 이유가 궁금하다면 여기 에서 배열 생성자를 사용하여 문자를 반복하는 방법에 대한 자세한 내용을 읽어보십시오 .


정밀도가 2 또는 3 인 708.3333333333333 값을 전달하면 반환 값이 708.00이됩니다. Chrome 및 IE 9 .toFixed (2)가 내 요구를 충족시키는 소수점 이하 2 자리에 필요합니다.
alan

이것은 일반적인 방법이 아닙니다. 예를 들어 toFixed (16.775, 2)는 16.77을 반환합니다. 숫자를 문자열로 변환 한 다음 변환하는 것이 유일한 방법입니다.
hiway

2
이 메서드에는 버그가 있습니다. toFixed (-0.1111, 2)는 0.11을 반환합니다. 즉, 음수 부호가 손실됩니다.
Matt

끝에 parseFloat (result)를 추가 한 것을 제외하고는 훌륭하게 작동합니다. 편집 할 가치가 있습니다.
Artur Barseghyan 2015 년

16

일을하는 데 항상 더 나은 방법이 있습니다.

var number = 51.93999999999761;

4 자리 정밀도를 얻고 싶습니다 : 51.94

그냥 해:

number.toPrecision(4);

결과는 51.94입니다.


2
100을 더하면 어떨까요? number.toPrecision (5)로 변경해야합니까?
JohnnyBizzle

2
예. 31.939383.toPrecision (4)> "31.94"/ 131.939383.toPrecision (4)> "131.9"
ReSpawN

6

PHP와 유사한 반올림 방법

아래 코드는 정밀도 매개 변수를 사용하는 고유 한 버전의 Math.round를 고유 한 네임 스페이스에 추가하는 데 사용할 수 있습니다. 위의 예에서 십진수 반올림과 달리 이것은 문자열과의 변환을 수행하지 않으며 정밀도 매개 변수는 PHP 및 Excel과 동일한 방식으로 작동합니다. 따라서 양수 1은 소수점 1 자리로 반올림하고 -1은 10 자리로 반올림합니다.

var myNamespace = {};
myNamespace.round = function(number, precision) {
    var factor = Math.pow(10, precision);
    var tempNumber = number * factor;
    var roundedTempNumber = Math.round(tempNumber);
    return roundedTempNumber / factor;
};

myNamespace.round(1234.5678, 1); // 1234.6
myNamespace.round(1234.5678, -1); // 1230

에서 ) (Math.round에 대한 모질라 개발자 참조


2

제대로 작동하는 코드 (많은 테스트를하지 않음) :

function toFixed(value, precision) {
    var precision = precision || 0,
        neg = value < 0,
        power = Math.pow(10, precision),
        value = Math.round(value * power),
        integral = String((neg ? Math.ceil : Math.floor)(value / power)),
        fraction = String((neg ? -value : value) % power),
        padding = new Array(Math.max(precision - fraction.length, 0) + 1).join('0');

    return precision ? integral + '.' +  padding + fraction : integral;
}

코드에 버그가 있습니다. 나는 toFixed (2.01, 4)를 시도했고 "2.100"의 결과를 얻었습니다. 문제를 해결할 방법을 찾으면이 질문에 대한 답변으로 게시하겠습니다.
Elias Zamaria

@ mikez302 : 패딩 계산이 1 씩 벗어났습니다. 지금 작동해야하지만 여전히 고장난 경우 다시 나를
Christoph

아주 이상한. firefox 17에서 firebug 콘솔을 연 상태에서이 기능을 실행하면 js가 끝없는 루프에 빠진 것처럼 전체 브라우저가 정지됩니다. 내가 console.log하지 않더라도 출력을 기록하십시오. 방화범이 활성화되어 있지 않으면 버그가 발생하지 않습니다.
SublymeRick

1
업데이트, 크롬에서 실행했는데 다음과 같은 메시지가 나타납니다. Uncaught RangeError : toFixed 함수 호출과 관련하여 최대 호출 스택 크기가 초과되었습니다.
SublymeRick

@SublymeRick : 왜 이런 일이 발생하는지 모르겠습니다. 어둠 속에서 샷 : ... 함수 이름을 변경하려고
크리스토프

2

아래 기능이 도움이 될 수 있다고 생각합니다.

function roundOff(value,round) {
   return (parseInt(value * (10 ** (round + 1))) - parseInt(value * (10 ** round)) * 10) > 4 ? (((parseFloat(parseInt((value + parseFloat(1 / (10 ** round))) * (10 ** round))))) / (10 ** round)) : (parseFloat(parseInt(value * (10 ** round))) / ( 10 ** round));
}

사용법 : roundOff(600.23458,2);반환됩니다600.23


2

이것은 N 자리로 반올림하는 데 작동합니다 (N 자리로 자르려면 Math.round 호출을 제거하고 Math.trunc 하나를 사용하십시오) :

function roundN(value, digits) {
   var tenToN = 10 ** digits;
   return /*Math.trunc*/(Math.round(value * tenToN)) / tenToN;
}

내가 저작 할 때 과거에 Java에서 이러한 논리에 의존해야했습니다. 데이터 조작 E-Slate 구성 요소를 . 0에 0.1을 여러 번 더하면 예기치 않게 긴 소수 부분이 발생한다는 것을 알게 되었기 때문입니다 (이것은 부동 소수점 산술 때문입니다).

사용자 댓글 항상 소수점 이하 2 자리를 표시하는 Format number 이 기술을 스케일링이라고합니다.

일부는 예상대로 반올림되지 않는 경우가 있으며 http://www.jacklmoore.com/notes/rounding-in-javascript/ 에서 대신 제안됩니다.

function round(value, decimals) {
  return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
}

btw, POSITS는 미래의 하드웨어
George Birbilis

-2

반올림에 대해 정말로 신경 쓰지 않는다면 toFixed (x)를 추가하고 필요한 경우 후행 0과 점을 제거하십시오. 빠른 해결책이 아닙니다.

function format(value, decimals) {
    if (value) {
        value = value.toFixed(decimals);            
    } else {
        value = "0";
    }
    if (value.indexOf(".") < 0) { value += "."; }
    var dotIdx = value.indexOf(".");
    while (value.length - dotIdx <= decimals) { value += "0"; } // add 0's

    return value;
}

나는 예상 한 동안 시도 format(1.2, 5)하고 얻었습니다 . 1.21.20000
Elias Zamaria 2014 년

죄송합니다 @EliasZamaria, 처음에는 이해하지 못했습니다. 게시물을 편집했습니다. 값이 정의되지 않은 경우 "0.0000"을 반환합니다.
Juan Carrey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.