소수점 이하 두 자리까지 반올림하고 싶지만 필요한 경우에만 .
입력:
10
1.7777777
9.1
산출:
10
1.78
9.1
JavaScript로 어떻게 할 수 있습니까?
Number.EPSILON
. 사용하십시오 Math.round( num * 100 + Number.EPSILON ) / 100
.
Number.EPSILON
여기서 사용하는 이유를 설명해 주 시겠습니까?
소수점 이하 두 자리까지 반올림하고 싶지만 필요한 경우에만 .
입력:
10
1.7777777
9.1
산출:
10
1.78
9.1
JavaScript로 어떻게 할 수 있습니까?
Number.EPSILON
. 사용하십시오 Math.round( num * 100 + Number.EPSILON ) / 100
.
Number.EPSILON
여기서 사용하는 이유를 설명해 주 시겠습니까?
답변:
사용하다 Math.round(num * 100) / 100
편집 : 1.005와 같은 것을 올바르게 반올림하기 위해
Math.round((num + Number.EPSILON) * 100) / 100
Math.round((num + 0.00001) * 100) / 100
. 시도 Math.round((1.005 + 0.00001) * 100) / 100
와Math.round((1.0049 + 0.00001) * 100) / 100
값이 텍스트 유형 인 경우 :
parseFloat("123.456").toFixed(2);
값이 숫자 인 경우 :
var numb = 123.23454;
numb = numb.toFixed(2);
1.5와 같은 값은 "1.50"을 출력으로 제공한다는 단점이 있습니다. @minitech가 제안한 수정 사항 :
var numb = 1.5;
numb = +numb.toFixed(2);
// Note the plus sign that drops any "extra" zeroes at the end.
// It changes the result (which is a string) into a number again (think "0 + foo"),
// which means that it uses only as many digits as necessary.
Math.round
더 나은 솔루션 인 것 같습니다 . 그러나 그렇지 않습니다! 어떤 경우에는 올바르게 반올림 되지 않습니다 .
Math.round(1.005 * 1000)/1000 // Returns 1 instead of expected 1.01!
경우에 따라 toFixed ()도 올바르게 반올림 되지 않습니다 (Chrome v.55.0.2883.87에서 테스트)!
예 :
parseFloat("1.555").toFixed(2); // Returns 1.55 instead of 1.56.
parseFloat("1.5550").toFixed(2); // Returns 1.55 instead of 1.56.
// However, it will return correct result if you round 1.5551.
parseFloat("1.5551").toFixed(2); // Returns 1.56 as expected.
1.3555.toFixed(3) // Returns 1.355 instead of expected 1.356.
// However, it will return correct result if you round 1.35551.
1.35551.toFixed(2); // Returns 1.36 as expected.
내 생각에 이것은 1.555가 실제로 배후에 1.55499994 인 플로트와 같은 것이기 때문입니다.
해결 방법 1 은 필요한 반올림 알고리즘이있는 스크립트를 사용하는 것입니다. 예를 들면 다음과 같습니다.
function roundNumber(num, scale) {
if(!("" + num).includes("e")) {
return +(Math.round(num + "e+" + scale) + "e-" + scale);
} else {
var arr = ("" + num).split("e");
var sig = ""
if(+arr[1] + scale > 0) {
sig = "+";
}
return +(Math.round(+arr[0] + "e" + sig + (+arr[1] + scale)) + "e-" + scale);
}
}
https://plnkr.co/edit/uau8BlS1cqbvWPCHJeOy?p=preview
참고 : 이것은 모든 사람에게 보편적 인 솔루션은 아닙니다. 몇 가지 다른 반올림 알고리즘이 있으며 구현이 다를 수 있으며 요구 사항에 따라 다릅니다. https://en.wikipedia.org/wiki/Rounding
해결 방법 2 는 프런트 엔드 계산을 피하고 백엔드 서버에서 반올림 된 값을 가져 오는 것입니다.
parseFloat(number.toFixed(decimalPlaces));
@PerLundberg
parseFloat("55.555").toFixed(2)
"55.55"
Chrome 개발자 콘솔로 돌아갑니다 .
당신이 사용할 수있는
function roundToTwo(num) {
return +(Math.round(num + "e+2") + "e-2");
}
나는 이것을 MDN 에서 발견했다 . 그들의 방법은 언급 된 1.005의 문제를 피합니다 .
roundToTwo(1.005)
1.01
roundToTwo(10)
10
roundToTwo(1.7777777)
1.78
roundToTwo(9.1)
9.1
roundToTwo(1234.5678)
1234.57
+(val)
사용하는 것과 동일 Number(val)
합니다. "e-2"를 숫자로 연결하면 문자열을 숫자로 다시 변환해야했습니다.
roundToTwo(1.0049999999999999)
1.01 (필수적으로 이후 1.0049999999999999 == 1.005
)로 표시됩니다. num = 1.005
num의 정확한 값이 1.005보다 작기 때문에 '명확하게' 입력 해야하는 부동 소수점 은 1.00으로 반올림됩니다. 물론, 문자열 '1.005' '분명히' '는 1.01로 반올림되어야합니다. 다른 사람들이 실제 올바른 행동이 무엇인지에 대한 다른 직관을 가지고있는 사실은 그것이 왜 복잡한 지의 일부입니다.
1.0049999999999999
와 사이에 (부동 소수점) 숫자가 없으므로 1.005
정의에 따라 숫자가 동일합니다. 이것을 dedekind cut이라고합니다.
1.00499 < 1.005
IS true
, 1.0049999999999999 < 1.005
평가 false
.
MarkG의 답변이 맞습니다. 소수점 이하 자릿수에 대한 일반적인 확장은 다음과 같습니다.
Number.prototype.round = function(places) {
return +(Math.round(this + "e+" + places) + "e-" + places);
}
용법:
var n = 1.7777;
n.round(2); // 1.78
단위 테스트 :
it.only('should round floats to 2 places', function() {
var cases = [
{ n: 10, e: 10, p:2 },
{ n: 1.7777, e: 1.78, p:2 },
{ n: 1.005, e: 1.01, p:2 },
{ n: 1.005, e: 1, p:0 },
{ n: 1.77777, e: 1.8, p:1 }
]
cases.forEach(function(testCase) {
var r = testCase.n.round(testCase.p);
assert.equal(r, testCase.e, 'didn\'t get right number');
});
})
function round(number, decimals) { return +(Math.round(number + "e+" + decimals) + "e-" + decimals); }
(-1.005).round(2) === -1
다음을 사용해야합니다.
Math.round( num * 100 + Number.EPSILON ) / 100
아무도 모르는 것 같습니다 Number.EPSILON
.
또한 이것은 일부 사람들이 언급 한 것처럼 이상한 JavaScript 가 아니라는 점에 주목할 가치가 있습니다.
그것은 컴퓨터에서 부동 소수점 숫자가 작동하는 방식입니다. 프로그래밍 언어의 99 %와 마찬가지로 JavaScript에는 집에서 만든 부동 소수점 숫자 가 없습니다 . 이를 위해 CPU / FPU에 의존합니다. 컴퓨터는 이진법을 사용하며, 이진법에는와 같은 숫자가 0.1
없지만 단순한 이진법이 있습니다. 왜? 같은 이유로 1/3보다 10 진수로 쓸 수 없습니다. 값은 0.33333333입니다. 무한대는 3입니다.
여기로 오세요 Number.EPSILON
. 이 숫자는 배정 밀도 부동 소수점 숫자에 존재하는 1과 다음 숫자 의 차이 입니다. 그게 다야 : 1
와 1 + 사이에는 숫자가 없습니다 Number.EPSILON
.
편집하다:
주석에서 요청했듯이 한 가지를 분명히합시다. Number.EPSILON
반올림 할 값이 부동 소수점 오류 델타를 삼킬 수 있기 때문에 반올림 값이 산술 연산의 결과 일 때만 관련이 있습니다.
값이 직접 소스 (예 : 리터럴, 사용자 입력 또는 센서)에서 오는 경우에는 유용하지 않습니다.
편집 (2019) :
@maganap과 일부 사람들이 지적했듯이 Number.EPSILON
곱하기 전에 추가하는 것이 가장 좋습니다 .
Math.round( ( num + Number.EPSILON ) * 100 ) / 100
편집 (2019 년 12 월) :
최근에 나는 엡실론을 인식하는 숫자를 비교하기 위해이 기능과 비슷한 기능을 사용합니다.
const ESPILON_RATE = 1 + Number.EPSILON ;
const ESPILON_ZERO = Number.MIN_VALUE ;
function epsilonEquals( a , b ) {
if ( Number.isNaN( a ) || Number.isNaN( b ) ) {
return false ;
}
if ( a === 0 || b === 0 ) {
return a <= b + EPSILON_ZERO && b <= a + EPSILON_ZERO ;
}
return a <= b * EPSILON_RATE && b <= a * EPSILON_RATE ;
}
내 유스 케이스는 몇 년 동안 개발중인 주장 + 데이터 유효성 검사 라이브러리 입니다.
실제로, 부동 소수점 오류를 누적하기 위해 동등성 검사기를 느슨하게 원하기 때문에 내가 사용하는 코드에서 (엡실론의 네 배) 사용 ESPILON_RATE = 1 + 4 * Number.EPSILON
하고 EPSILON_ZERO = 4 * Number.MIN_VALUE
있습니다.
지금까지는 나에게 완벽 해 보입니다. 도움이 되길 바랍니다.
Math.round( (num + Number.EPSILON) * 100) / 100
. 나는 이것이 올바르게 반올림하는 올바른 방법이라는 것에 동의합니다 (이 질문에서 정확히 질문 한 것은 아니지만).
0.004999999999999999
복합 부동 소수점 오류의 결과 일뿐 이며 수학적으로 올바른 결과는 아마도 0.005 일 것입니다. 센서에서 읽는 경우? 별로.
Math.round(1.5)
= 2이지만 Math.round(-1.5)
= -1입니다. 따라서 이것은 완벽하게 일관됩니다. 여기서 -1000이 -1000.01보다 큰 것처럼 -1은 -2보다 큽니다. 더 큰 절대 숫자 와 혼동하지 마십시오 .
하나를 사용할 수 있습니다 .toFixed(NumberOfDecimalPlaces)
.
var str = 10.234.toFixed(2); // => '10.23'
var number = Number(str); // => 10.23
Number(9).toFixed(2).replace(/0+$/, '')
=> "9."
이 질문은 복잡합니다.
roundTo2DP(num)
float을 인수로 사용하고 소수점 이하 2 자리로 반올림 한 값을 반환 하는 함수가 있다고 가정 합니다. 이러한 각 표현은 무엇을 평가해야합니까?
roundTo2DP(0.014999999999999999)
roundTo2DP(0.0150000000000000001)
roundTo2DP(0.015)
'명백한'답변은 첫 번째 예제는 0.01로 반올림해야하고 (0.02보다 0.01에 가깝기 때문에) 다른 두 개는 0.02로 반올림해야합니다 (0.0150000000000000001은 0.01보다 0.02에 가깝기 때문에 0.015는 정확히 중간에 있기 때문에) 그들과 같은 숫자가 반올림되는 수학적 규칙이 있습니다).
당신이 짐작 할 수있다 캐치는 점이다 roundTo2DP
가능하게 할 수 그것을 전달되는 모든 세 개의 숫자이기 때문에, 그 명백한 해답을 제공하도록 구현 될 같은 번호 . IEEE 754 이진 부동 소수점 숫자 (JavaScript에서 사용되는 종류)는 대부분의 정수가 아닌 숫자를 정확하게 나타낼 수 없으므로 위의 세 숫자 리터럴은 모두 근처의 유효한 부동 소수점 숫자로 반올림됩니다. 이 숫자는 발생하는 대로 정확하게
0.01499999999999999944488848768742172978818416595458984375
0.02보다 0.01에 가깝습니다.
브라우저 콘솔, 노드 셸 또는 기타 JavaScript 인터프리터에서 세 숫자가 모두 같은 것을 알 수 있습니다. 그냥 그들을 비교하십시오 :
> 0.014999999999999999 === 0.0150000000000000001
true
제가 글을 쓸 때 m = 0.0150000000000000001
, 그로m
끝나는 정확한 가치 는 실제0.01
보다 더 가깝습니다 0.02
. 그러나 m
String으로 변환 하면 ...
> var m = 0.0150000000000000001;
> console.log(String(m));
0.015
> var m = 0.014999999999999999;
> console.log(String(m));
0.015
... 0.015를 얻습니다. 0.02로 반올림해야합니다. 이것은 이전 에이 모든 숫자가 정확히 같았다고 말한 56 세 자리 수 는 아닙니다 . 이게 무슨 마법입니까?
답변은 ECMAScript 사양, 7.1.12.1 : ToString이 Number 유형에 적용됨 섹션에 있습니다. 여기에 일부 숫자 m 을 문자열 로 변환하는 규칙 이 정리되어 있습니다. 핵심 부분은 포인트 5이며, m 의 문자열 표현에 숫자가 사용될 정수 s 가 생성됩니다 .
있도록 N , K를 , 및 s의 정수가되도록 수행 K ≥ 1, 10 K -1 ≤ S <10 K 에 대한 숫자 값 S × 10 N - K는 인 m 과 k는 가능한 한 작게한다. 이 K의 소수 표현 자리수 유의 S , S를 10로 나누어 아니고, 최하위 디지트 것을 들 반드시 고유 이러한 기준에 의해 결정되지 않는다.
여기서 중요한 부분은 " k 는 가능한 한 작아야 "한다는 요구 사항입니다 . 그 요구 사항 m
의 가치 는 Number가 주어지면 의 요구 사항을 충족하면서도 가능한 최소 자릿수 를 String(m)
가져야 한다는 요구 사항입니다 . 우리는 이미 그것을 알고 있기 때문에 , 왜 사실이어야 하는지 분명 합니다.Number(String(m)) === m
0.015 === 0.0150000000000000001
String(0.0150000000000000001) === '0.015'
물론,이 토론의 아무도는 직접 어떤 대답하지 않았다 roundTo2DP(m)
해야 돌아갑니다. 경우 m
'의 정확한 값이 0.01499999999999999944488848768742172978818416595458984375이지만, 그것의 String 표현은'0.015, 그 다음 무엇이며 올바른 수학적, 실제적으로, 철학적으로, 또는 무엇 이건 - - 대답은 우리는 두 개의 소수 자릿수로 반올림 할 때?
이에 대한 올바른 정답은 없습니다. 사용 사례에 따라 다릅니다. 다음과 같은 경우 문자열 표현을 존중하고 위쪽으로 반올림하려고합니다.
반면에, 이진 부동 소수점 값을 존중하고 값이 본질적으로 연속적인 스케일 (예 : 센서에서 읽은 값) 인 경우 아래쪽으로 반올림합니다.
이 두 가지 접근 방식에는 다른 코드가 필요합니다. 숫자의 문자열 표현을 존중하기 위해 (합리적으로 약간의 미묘한 코드를 사용하여) 학교에서 사용했을 때와 동일한 알고리즘을 사용하여 숫자로 숫자로 문자열 표현에 직접 작용하는 자체 반올림을 구현할 수 있습니다 숫자를 반올림하는 방법을 배웠습니다. 다음은 소수점 이하의 후행 0을 제거하여 "필요한 경우에만"소수점 이하 2 자리까지 숫자를 나타내는 OP의 요구 사항을 준수하는 예입니다. 물론 정확한 요구에 맞게 조정해야 할 수도 있습니다.
/**
* Converts num to a decimal string (if it isn't one already) and then rounds it
* to at most dp decimal places.
*
* For explanation of why you'd want to perform rounding operations on a String
* rather than a Number, see http://stackoverflow.com/a/38676273/1709587
*
* @param {(number|string)} num
* @param {number} dp
* @return {string}
*/
function roundStringNumberWithoutTrailingZeroes (num, dp) {
if (arguments.length != 2) throw new Error("2 arguments required");
num = String(num);
if (num.indexOf('e+') != -1) {
// Can't round numbers this large because their string representation
// contains an exponent, like 9.99e+37
throw new Error("num too large");
}
if (num.indexOf('.') == -1) {
// Nothing to do
return num;
}
var parts = num.split('.'),
beforePoint = parts[0],
afterPoint = parts[1],
shouldRoundUp = afterPoint[dp] >= 5,
finalNumber;
afterPoint = afterPoint.slice(0, dp);
if (!shouldRoundUp) {
finalNumber = beforePoint + '.' + afterPoint;
} else if (/^9+$/.test(afterPoint)) {
// If we need to round up a number like 1.9999, increment the integer
// before the decimal point and discard the fractional part.
finalNumber = Number(beforePoint)+1;
} else {
// Starting from the last digit, increment digits until we find one
// that is not 9, then stop
var i = dp-1;
while (true) {
if (afterPoint[i] == '9') {
afterPoint = afterPoint.substr(0, i) +
'0' +
afterPoint.substr(i+1);
i--;
} else {
afterPoint = afterPoint.substr(0, i) +
(Number(afterPoint[i]) + 1) +
afterPoint.substr(i+1);
break;
}
}
finalNumber = beforePoint + '.' + afterPoint;
}
// Remove trailing zeroes from fractional part before returning
return finalNumber.replace(/0+$/, '')
}
사용법 예 :
> roundStringNumberWithoutTrailingZeroes(1.6, 2)
'1.6'
> roundStringNumberWithoutTrailingZeroes(10000, 2)
'10000'
> roundStringNumberWithoutTrailingZeroes(0.015, 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes('0.015000', 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes(1, 1)
'1'
> roundStringNumberWithoutTrailingZeroes('0.015', 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes(0.01499999999999999944488848768742172978818416595458984375, 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes('0.01499999999999999944488848768742172978818416595458984375', 2)
'0.01'
위의 기능은 사용자가 입력 한 숫자가 잘못 반올림되는 것을 방지하기 위해 사용하려는 것일 수 있습니다.
(대안으로, 다른 구현으로 비슷하게 동작하는 기능을 제공하는 round10 라이브러리를 사용해 볼 수도 있습니다 .)
그러나 두 번째 종류의 숫자-연속 스케일에서 가져온 값을 사용하면 소수점 이하 자릿수가 적은 근사 소수를 더 많이 나타내는 것보다 더 정확 하다고 생각할 이유가 없습니다 . 이 경우, 우리 는 String 표현을 존중하고 싶지 않습니다. 그 표현은 (사양에서 설명 된 바와 같이) 이미 반올림 되었기 때문입니다. "0.014999999 ... 375는 0.015로 반올림하여 0.02로 반올림하므로 0.014999999 ... 375는 0.02로 반올림"하는 실수를 저지르고 싶지 않습니다.
여기서 우리는 단순히 내장 toFixed
방법을 사용할 수 있습니다 . 에 의해 Number()
반환 된 String 을 호출 하면 String toFixed
표현에 후행 0이없는 Number를 얻습니다 (JavaScript 가이 답변의 앞부분에서 설명한 Number의 String 표현을 계산하는 방식 덕분입니다).
/**
* Takes a float and rounds it to at most dp decimal places. For example
*
* roundFloatNumberWithoutTrailingZeroes(1.2345, 3)
*
* returns 1.234
*
* Note that since this treats the value passed to it as a floating point
* number, it will have counterintuitive results in some cases. For instance,
*
* roundFloatNumberWithoutTrailingZeroes(0.015, 2)
*
* gives 0.01 where 0.02 might be expected. For an explanation of why, see
* http://stackoverflow.com/a/38676273/1709587. You may want to consider using the
* roundStringNumberWithoutTrailingZeroes function there instead.
*
* @param {number} num
* @param {number} dp
* @return {number}
*/
function roundFloatNumberWithoutTrailingZeroes (num, dp) {
var numToFixedDp = Number(num).toFixed(dp);
return Number(numToFixedDp);
}
roundStringNumberWithoutTrailingZeroes(362.42499999999995, 2)
. 예상 결과 (PHP에서와 같이 echo round(362.42499999999995, 2)
) : 362.43
. 실제 결과 :362.42
round
가 362.43을 제공 하는지 잘 모르겠습니다 . 362.42499999999995가 362.425 (수학 및 코드-JS 362.42499999999995 < 362.425
와 PHP 모두에 해당) 보다 작기 때문에 직관적으로 잘못된 것 같습니다 . PHP의 대답은 원래와 둥근 부동 소수점 숫자 사이의 거리를 최소화하지도 않습니다 362.43 - 362.42499999999995 > 362.42499999999995 - 362.42
. php.net/manual/en/function.round.php 에 따르면 , PHP round
는 C99 표준을 따릅니다. 나는 무슨 일이 일어나고 있는지 이해하기 위해 C의 땅으로 모험을해야합니다.
고려 .toFixed()
하고 .toPrecision()
:
정확한 반올림 방법. 출처 : Mozilla
(function(){
/**
* Decimal adjustment of a number.
*
* @param {String} type The type of adjustment.
* @param {Number} value The number.
* @param {Integer} exp The exponent (the 10 logarithm of the adjustment base).
* @returns {Number} The adjusted value.
*/
function decimalAdjust(type, value, exp) {
// If the exp is undefined or zero...
if (typeof exp === 'undefined' || +exp === 0) {
return Math[type](value);
}
value = +value;
exp = +exp;
// If the value is not a number or the exp is not an integer...
if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
return NaN;
}
// Shift
value = value.toString().split('e');
value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
// Shift back
value = value.toString().split('e');
return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
}
// Decimal round
if (!Math.round10) {
Math.round10 = function(value, exp) {
return decimalAdjust('round', value, exp);
};
}
// Decimal floor
if (!Math.floor10) {
Math.floor10 = function(value, exp) {
return decimalAdjust('floor', value, exp);
};
}
// Decimal ceil
if (!Math.ceil10) {
Math.ceil10 = function(value, exp) {
return decimalAdjust('ceil', value, exp);
};
}
})();
예 :
// Round
Math.round10(55.55, -1); // 55.6
Math.round10(55.549, -1); // 55.5
Math.round10(55, 1); // 60
Math.round10(54.9, 1); // 50
Math.round10(-55.55, -1); // -55.5
Math.round10(-55.551, -1); // -55.6
Math.round10(-55, 1); // -50
Math.round10(-55.1, 1); // -60
Math.round10(1.005, -2); // 1.01 -- compare this with Math.round(1.005*100)/100 above
// Floor
Math.floor10(55.59, -1); // 55.5
Math.floor10(59, 1); // 50
Math.floor10(-55.51, -1); // -55.6
Math.floor10(-51, 1); // -60
// Ceil
Math.ceil10(55.51, -1); // 55.6
Math.ceil10(51, 1); // 60
Math.ceil10(-55.59, -1); // -55.5
Math.ceil10(-59, 1); // -50
Math.round10(3544.5249, -2)
3544.52 대신 3544.53 반환
3544.5249
소수점 이하 2 자리에 가장 가까운 근사값 은 3544.52
(오류 = 0.0049)입니다. 인 경우 3544.53
오류는 0.0051입니다. 연속 반올림을 수행합니다 (예 : Math.round10 (Math.round10 (3544.5249, -3), -2)). 더 큰 반올림 오류가 발생하므로 바람직하지 않습니다.
number += 0.00011
Math.round10( Math.round10(3544.5249, -3) , -2)
여기서 찾은 답변 중 올바른 것은 없습니다 . @stinkycheeseman가하도록 요청 반올림 하면 모든 숫자를 반올림.
반올림하려면 다음을 사용하십시오.
Math.ceil(num * 100)/100;
Math.ceil(1.1 * 100)/100;
-it 리턴 을 테스트하는 동안 이상한 버그가 발견 되었습니다 . 1.11
110.00000000000001
1.1*100=1100
Math.ceil(num.toFixed(4) * 100) / 100
Math.ceil((1.1).toFixed(4) * 100) / 100
는 1.11
Firefox 에서도 반환 됩니다. 현대 브라우저 문제 / 버그는 곱셈이며 사람들은 그것에 대해 알아야합니다 (예를 들어 그 당시 복권 게임에서 일했습니다).
간단한 방법은 다음과 같습니다.
Math.round(value * 100) / 100
그래도 당신을 위해 그것을하기 위해 별도의 기능을 만들고 싶을 수도 있습니다.
function roundToTwo(value) {
return(Math.round(value * 100) / 100);
}
그런 다음 단순히 값을 전달합니다.
두 번째 매개 변수를 추가하여 임의의 소수 자릿수로 반올림하도록 향상시킬 수 있습니다.
function myRound(value, places) {
var multiplier = Math.pow(10, places);
return (Math.round(value * multiplier) / multiplier);
}
+(10).toFixed(2); // = 10
+(10.12345).toFixed(2); // = 10.12
(10).toFixed(2); // = 10.00
(10.12345).toFixed(2); // = 10.12
+(0.015).toFixed(2) == 0.01
.
나에게 Math.round () 는 정답을주지 못했습니다. toFixed (2) 가 더 잘 작동 한다는 것을 알았습니다 . 아래는 두 가지 예입니다.
console.log(Math.round(43000 / 80000) * 100); // wrong answer
console.log(((43000 / 80000) * 100).toFixed(2)); // correct answer
1.005
. (1.005).toFixed(2)
여전히 결과 1.00
.
이 기능을 사용하십시오 Number(x).toFixed(2);
Number
호출은 필요하지 않습니다 x.toFixed(2)
작동합니다.
(1).toFixed(2)
반환 1.00
되지만 질문자에게는 1
이 질문이 필요합니다 .
1.005.toFixed(2)
수율 "1"
이해야 할 때 "1.01"
.
2017
네이티브 코드 만 사용.toFixed()
number = 1.2345;
number.toFixed(2) // "1.23"
엄격해야하고 필요한 경우 숫자를 추가하면 사용할 수 있습니다. replace
number = 1; // "1"
number.toFixed(5).replace(/\.?0*$/g,'');
toFixed
몇 년 전에 여러 번의 답변 으로 제안되었을뿐만 아니라 질문의 "필요한 경우에만"조건을 충족시키지 못합니다. asker가 원하는 곳을 (1).toFixed(2)
제공 "1.00"
합니다 "1"
.
이 경량 솔루션을 사용해보십시오 .
function round(x, digits){
return parseFloat(x.toFixed(digits))
}
round(1.222, 2) ;
// 1.22
round(1.222, 10) ;
// 1.222
.toFixed()
어쨌든 숫자 만 허용 하므로 내가 볼 수있는 한 아무런 차이가 없어야합니다 .
round(1.005, 2)
결과를 보십시오 . 1
1.01
round(0.995, 2) => 0.99
; round(1.006, 2) => 1.01
; round(1.005, 2) => 1
몇 가지 방법이 있습니다. 나와 같은 사람들에게 Lodash의 변형
function round(number, precision) {
var pair = (number + 'e').split('e')
var value = Math.round(pair[0] + 'e' + (+pair[1] + precision))
pair = (value + 'e').split('e')
return +(pair[0] + 'e' + (+pair[1] - precision))
}
용법:
round(0.015, 2) // 0.02
round(1.005, 2) // 1.01
프로젝트가 jQuery 또는 lodash를 사용 round
하는 경우 라이브러리에서 적절한 방법을 찾을 수도 있습니다 .
변형 n.toFixed(2)
이 올바르지 않기 때문에 제거했습니다 . 감사합니다 @ avalanche1
Number.toFixed()
는 문자열을 반환하지만 그 앞에 더하기 기호가 있으면 JS 인터프리터는 문자열을 숫자로 변환합니다. 이것은 구문 설탕입니다.
alert((+1234).toFixed(2))
에서는 "1234.00"을 표시합니다.
alert(+1234.toFixed(2))
던집니다 SyntaxError: identifier starts immediately after numeric literal
. 나는 첫 번째 옵션을 고수합니다.
362.42499999999995
. 예상 결과 (PHP에서와 같이 echo round(362.42499999999995, 2)
) : 362.43
. 실제 결과 :362.42
lodash 라이브러리를 사용하는 경우 다음과 같이 lodash의 라운드 방법을 사용할 수 있습니다.
_.round(number, precision)
예 :
_.round(1.7777777, 2) = 1.78
ES6부터 toPrecision 을 사용하여 이것을 수행하는 '적절한'방법이 있습니다 (정적을 재정의하고 해결 방법을 만들지 않음).
var x = 1.49999999999;
console.log(x.toPrecision(4));
console.log(x.toPrecision(3));
console.log(x.toPrecision(2));
var y = Math.PI;
console.log(y.toPrecision(6));
console.log(y.toPrecision(5));
console.log(y.toPrecision(4));
var z = 222.987654
console.log(z.toPrecision(6));
console.log(z.toPrecision(5));
console.log(z.toPrecision(4));
그러면 그냥 parseFloat
제로가 사라질 것입니다.
console.log(parseFloat((1.4999).toPrecision(3)));
console.log(parseFloat((1.005).toPrecision(3)));
console.log(parseFloat((1.0051).toPrecision(3)));
'1.005 반올림 문제'는 해결하지 못합니다 . 부동 소수점이 처리되는 방식에 내재되어 있기 때문입니다 .
console.log(1.005 - 0.005);
라이브러리가 열려 있으면 bignumber.js 를 사용할 수 있습니다
console.log(1.005 - 0.005);
console.log(new BigNumber(1.005).minus(0.005));
console.log(new BigNumber(1.005).round(4));
console.log(new BigNumber(1.005).round(3));
console.log(new BigNumber(1.005).round(2));
console.log(new BigNumber(1.005).round(1));
<script src="https://cdnjs.cloudflare.com/ajax/libs/bignumber.js/2.3.0/bignumber.min.js"></script>
(1.005).toPrecision(3)
실제로 1.00
대신에 여전히 반환 합니다 1.01
.
toPrecision
원하는 출력 유형을 변경하는 문자열을 반환합니다.
.toPrecision
방법 은 결함이 아니며 부동 소수점 숫자 (JS의 숫자)의 특이성입니다 . 시도 1.005 - 0.005
하면을 반환 0.9999999999999999
합니다.
(1).toPrecision(3)
'1.00'을 반환하지만 질문자는 1
이 경우에 원했습니다 .
toPrecision
형식은 후자가 아니라 형식을 수행하며 OP의 질문에 대한 답변이 아닙니다. 처음에는 관련성이있는 것처럼 보일 수 있지만 많이 잘못됩니다. en.wikipedia.org/wiki/Significant_figures를 참조하십시오 . 예를 들어,를 Number(123.4).toPrecision(2)
반환 "1.2e+2"
하고 Number(12.345).toPrecision(2)
반환합니다 "12"
. 또한 @adamduren의 견해에 따르면 바람직하지 않은 문자열 (거대한 문제는 아니지만 바람직하지 않음)을 반환한다는 데 동의합니다.
MarkG와 Lavamantis는 수용된 것보다 훨씬 나은 솔루션을 제공했습니다. 그들이 더 많은지지를 얻지 못하는 것은 부끄러운 일입니다!
다음은 MDN 기반 의 부동 소수점 소수 문제를 해결하는 데 사용하는 함수 입니다. Lavamantis의 솔루션보다 훨씬 일반적이지만 덜 간결합니다.
function round(value, exp) {
if (typeof exp === 'undefined' || +exp === 0)
return Math.round(value);
value = +value;
exp = +exp;
if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
return NaN;
// Shift
value = value.toString().split('e');
value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));
// Shift back
value = value.toString().split('e');
return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}
함께 사용하십시오 :
round(10.8034, 2); // Returns 10.8
round(1.275, 2); // Returns 1.28
round(1.27499, 2); // Returns 1.27
round(1.2345678e+2, 2); // Returns 123.46
Lavamantis의 솔루션과 비교하여 우리는 할 수 있습니다 ...
round(1234.5678, -2); // Returns 1200
round("123.45"); // Returns 123
이것은 당신을 도울 수 있습니다 :
var result = Math.round(input*100)/100;
자세한 내용은이 링크를 참조하십시오
가장 쉬운 방법은 toFixed를 사용하고 Number 함수를 사용하여 후행 0을 제거하는 것입니다.
const number = 15.5;
Number(number.toFixed(2)); // 15.5
const number = 1.7777777;
Number(number.toFixed(2)); // 1.78
15.00
습니까? JS의 숫자 는 소수점 이하 자릿수를 저장 하지 않으며 모든 디스플레이는 초과 소수점 자릿수 (끝의 0)를 자동으로 자릅니다.
var roundUpto = function(number, upto){
return Number(number.toFixed(upto));
}
roundUpto(0.1464676, 2);
toFixed(2)
여기 2는이 숫자를 반올림 할 자릿수입니다.
그것은 당신을 위해 작동 할 수 있습니다
Math.round(num * 100)/100;
toFixed와 round의 차이점을 알고 싶습니다. Math.round (num) vs num.toFixed (0) 및 브라우저 불일치를 살펴볼 수 있습니다 .
가장 쉬운 방법:
+num.toFixed(2)
문자열로 변환 한 다음 다시 정수 / 부동 소수점으로 변환합니다.
toFixed()
를 3으로 변경하십시오 +num.toFixed(3)
. 1.005는 1.00으로 반올림되어 1과 같습니다.
"parseFloat (parseFloat (value) .toFixed (2))"와 같은 것을 사용하십시오.
parseFloat(parseFloat("1.7777777").toFixed(2))-->1.78
parseFloat(parseFloat("10").toFixed(2))-->10
parseFloat(parseFloat("9.1").toFixed(2))-->9.1
필요한 경우에만 이러한 반올림을 달성하는 한 가지 방법 은 Number.prototype.toLocaleString () 을 사용하는 것입니다 .
myNumber.toLocaleString('en', {maximumFractionDigits:2, useGrouping:false})
이렇게하면 원하는 결과를 정확하게 얻을 수 있지만 문자열로 표시됩니다. 예상 한 데이터 유형이 아닌 경우 숫자를 다시 숫자로 변환 할 수 있습니다.
toLocaleString
아직 인수 전달을 지원하지 않습니다 .
정확한 정확한 10 진수 반올림 정밀도를 달성하기 위해 가능한 모든 방법을 다양하게 반복 한 후에 가장 정확하고 효율적인 솔루션은 Number.EPSILON을 사용하는 것입니다. 이것은 부동 소수점 수학 정밀도 문제에 대한 진정한 수학 솔루션을 제공합니다. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON 과 같이 쉽게 폴리 필 할 수 있습니다. 어쩌면에게 다시 우리를 마지막으로 남아있는 IE 사용자 모두를 (지원하기 위해 그만해야합니다).
https://stackoverflow.com/a/48850944/6910392에 제공된 솔루션에서 채택되었습니다.
전체 라이브러리를 추가하지 않고도 선택적 정밀도 변수를 사용하여 정확한 10 진수 반올림, 바닥 및 천장을 제공하는 간단한 솔루션 드롭
업데이트 : Sergey가 의견에서 언급했듯이 지적 할 가치가있는이 (또는 다른) 방법에는 제한이 있습니다. 0.014999999999999999와 같은 숫자의 경우에도 부동 소수점 값 저장에 대한 정확도 한계의 절대 한계에 도달 한 결과로 부정확성이 발생합니다. 값 자체가 즉시 0.015로 평가되므로이를 설명하기 위해 적용 할 수있는 수학 또는 기타 솔루션은 없습니다. 콘솔에서 자체적으로 해당 값을 호출하여이를 확인할 수 있습니다. 이 제한으로 인해 문자열 표현이 단순히 "0.015"이므로 문자열 조작을 사용하여이 값을 줄이는 것도 불가능합니다. 이를 설명하기위한 모든 솔루션은 값을 스크립트에 적용하기 전에 데이터 소스에 논리적으로 적용되어야합니다.
var DecimalPrecision = (function(){
if (Number.EPSILON === undefined) {
Number.EPSILON = Math.pow(2, -52);
}
this.round = function(n, p=2){
let r = 0.5 * Number.EPSILON * n;
let o = 1; while(p-- > 0) o *= 10;
if(n < 0)
o *= -1;
return Math.round((n + r) * o) / o;
}
this.ceil = function(n, p=2){
let r = 0.5 * Number.EPSILON * n;
let o = 1; while(p-- > 0) o *= 10;
if(n < 0)
o *= -1;
return Math.ceil((n + r) * o) / o;
}
this.floor = function(n, p=2){
let r = 0.5 * Number.EPSILON * n;
let o = 1; while(p-- > 0) o *= 10;
if(n < 0)
o *= -1;
return Math.floor((n + r) * o) / o;
}
return this;
})();
console.log(DecimalPrecision.round(1.005));
console.log(DecimalPrecision.ceil(1.005));
console.log(DecimalPrecision.floor(1.005));
console.log(DecimalPrecision.round(1.0049999));
console.log(DecimalPrecision.ceil(1.0049999));
console.log(DecimalPrecision.floor(1.0049999));
console.log(DecimalPrecision.round(2.175495134384,7));
console.log(DecimalPrecision.round(2.1753543549,8));
console.log(DecimalPrecision.round(2.1755465135353,4));
이것은 가장 간단하고 우아한 솔루션입니다 (그리고 나는 세계 최고입니다).
function roundToX(num, X) {
return +(Math.round(num + "e+"+X) + "e-"+X);
}
//roundToX(66.66666666,2) => 66.67
//roundToX(10,2) => 10
//roundToX(10.904,2) => 10.9
E
표기법을 사용하여 인수를 수락하기 위해 허용 된 답변을 다시 쓰는 좋은 방법 입니다.
roundToX(362.42499999999995, 2)
. 예상 결과 (PHP에서와 같이 echo round(362.42499999999995, 2)
) : 362.43
. 실제 결과 :362.42