blog

금액(재무 관련) 문자열 서식 지정 도구의 JS

금액 처리 방법: 천분위 처리, 소수점 이하 n자리 유지 및 반올림(예: 0.1+0.2=0.1+) 이 문제에서 진행 상황을 확인하는 방법은 무엇인가요? 서문 수량 데이터로 작업할 ...

Oct 17, 2025 · 3 min. read
シェア

금액 처리: 천 분의 일 처리, 소수점 이하 소수점 이하 반올림만 가능합니다.

예: 0.1+0.2=0.1+0.2=0.30000000000000004 이런 종류의 문제에 대한 진행 상황을 어떻게 보장하나요?

서문

  • 금액 데이터를 다룰 때는 '천 단위 구분'과 '소수점 이하 자릿수 유지'가 필요한 경우가 많은데, 단순히 toLocalString과 toFixed를 사용하면 몇 가지 문제가 발생하기 쉽습니다.
  • 예를 들어, toLocalString은 일부 호환성 문제가 있으며 일부 하이브리드 프레임워크를 통해 모바일 앱을 개발할 때 유효하지 않을 수 있으며, toFixed는 반올림 방식이므로 한 자리 반올림이 가능합니다.
  • 5를 2로 반올림하는 방식인 '5를 2로 반올림'은 5 뒤의 숫자에 따라 ① 5가 홀수일 때는 5를 1로 반올림하고, ② 5가 짝수일 때는 5가 들어가지 않는 두 가지 경우로 나눠서 ① 홀수 앞의 5는 5를 1로 반올림합니다.
  • 금액 서식을 지정할 때 '천 단위 구분 기호' 외에 '소수점 이하 자릿수 유지'에 대한 요구 사항은 가장 가까운 소수점 이하를 반올림하지 않고 초과 소수점 이하를 직접 반올림하는 것입니다.
  • 제가 제안하는 한 가지 방법은 다음과 같습니다.

코드가 여기 있습니다!

/** * 값이 숫자 값인지 확인합니다. * @param {*} str * @returns */ export function isNumber(str) { if (typeof str === 'number') { return true } if (typeof str !== 'string') { return false } return !isNaN(str) && !isNaN(parseFloat(str)) } /** * * @param {*} str * @returns */ export function toNumber(str) { return isNumber(str) ? Number(str) : 0 } /** * 합산 기능 * @param {*} arr * @param {*} property * @param {*} digit 정밀도, 즉 각 합산 계산에서 가로채는 소수점 이하 자릿수를 제어하는 데 사용됩니다. * @returns */ export function calcSum(arr, property, _digit = 2) { // 합산 정확도 문제를 방지하는 데 사용됩니다(예: 0)..1+0.2=0.30000000000000004 function formatFloat(f, digit = _digit) { var m = Math.pow(10, digit) return parseInt(f * m, 10) / m } if (!property) { return arr.reduce((a, b) => formatFloat(toNumber(a) + toNumber(b)), 0) } return arr.reduce( (total, item) => formatFloat(toNumber(total) + toNumber(item[property])), 0 ) } /** * 숫자 유형 서식 * @param {*} num * @param {*} fractionDigits * @returns */ export function fixedNumber(_num, fractionDigits = 2) { const num = String(_num) // 숫자가 아닌 것을 처리합니다. if (!isNumber(num)) { return Number(0).toFixed(fractionDigits) } // 소수점 처리 let numStr = num.replace(/\.\d*$/g, function(m) { return m.slice(0, fractionDigits + 1) }) // 소수점 이하 자릿수가 부족하면 0을 보충합니다. const amountAry = numStr.split('.') if (amountAry.length > 1 && amountAry[1].length < fractionDigits) { amountAry[1] = amountAry[1].padEnd(fractionDigits, '0') } else if (amountAry.length < fractionDigits) { amountAry[1] = '0'.repeat(fractionDigits) } numStr = fractionDigits < 1 ? amountAry[0] : amountAry.join('.') return numStr } /** * 금액 서식 * @param {*} amount * @returns */ export function formatAmount(_amount, fractionDigits = 2) { let amount = fixedNumber(_amount, fractionDigits) // 숫자가 아닌 것을 처리합니다. if (!isNumber(amount)) { return Number(0).toFixed(fractionDigits) } // 천분의 1초 처리 amount = !(amount + '').includes('.') ? // 1-3비트 뒤 3자리와 일치해야 함 (amount + '').replace(/\d{1,3}(?=(\d{3})+$)/g, (match) => { return match + ',' }) : (amount + '').replace(/\d{1,3}(?=(\d{3})+(\.))/g, (match) => { return match + ',' }) // 소수점 처리 return amount }

실제 테스트:

  • 금액 합계 테스트
let mockData = [{cost:0.01}, {cost:0.02}, {cost:9999.82}, {cost:6699.120090213}, {cost:6699.25}]
// --
console.log('값의 합산: ', 0.01+0.02+9999.82+6699.120090213+6699.25)
console.log('reduce개체 합산: ', mockData.reduce((total,item) => total+item.cost,0))
console.log('calcSum 기능 테스트 합산: ', calcSum(mockData,'cost'))
console.log('fixedNumber+calcSum 기능 테스트 합산: ', fixedNumber(calcSum(mockData,'cost')))
console.log('formatAmount+calcSum 기능 테스트 합산: ', formatAmount(calcSum(mockData,'cost')))

출력:

Read next

간단한 제목, 35명의 프로그래머가 2023년에 대해 요약한 내용

소박한 삶에도 소박한 행복이 있다\n- 가장 행복한 것은 물론 가족이 추가 한 어린 왕자 라, 사실 2022 년 말에 태어 났지만 올해 2023 년에 아버지로서 하루하루 조금씩 자라는 모습을 지켜 보면서 마음도 누워서 엄청나게 행복합니다!

Oct 17, 2025 · 3 min read