JavaScript에서 숫자를 소수점 2자리로 포맷하는 방법

가격, 백분율, 측정값을 정확히 소수점 2자리로 표시하기

소개

많은 애플리케이션에서 고정된 소수 자릿수로 숫자를 표시해야 합니다. 가격은 일반적으로 $19.99와 같이 소수점 2자리로 표시됩니다. 백분율은 종종 45.50%로 표시됩니다. 측정값은 3.14미터와 같이 가독성을 위해 일관된 소수 자릿수를 사용합니다.

소수 자릿수를 제어하면 애플리케이션 전체에서 시각적 일관성을 보장할 수 있습니다. 명시적인 포맷 없이 JavaScript는 실제 값에 따라 다양한 소수 자릿수로 숫자를 표시합니다. 숫자 5는 "5"로 표시되고 5.5는 "5.5"로 표시되어 일관되지 않은 정렬과 외관을 만듭니다.

이 레슨에서는 다양한 로케일 규칙을 준수하면서 숫자를 정확히 소수점 2자리 또는 최대 소수점 2자리로 포맷하는 방법을 보여줍니다.

기본 포맷을 위한 toFixed() 사용

toFixed() 메서드는 숫자를 지정된 소수 자릿수를 가진 문자열로 변환합니다. 소수 자릿수를 인수로 전달하세요.

const price = 19.9;
const formatted = price.toFixed(2);
console.log(formatted);
// Output: "19.90"

이 메서드는 항상 정확히 2자리의 소수를 표시합니다. 숫자의 소수 자릿수가 더 적으면 toFixed()가 0으로 채웁니다. 소수 자릿수가 더 많으면 메서드는 2자리로 반올림합니다.

const examples = [5, 5.5, 5.555, 5.999];

examples.forEach(num => {
  console.log(num.toFixed(2));
});
// Output:
// "5.00"
// "5.50"
// "5.56"
// "6.00"

toFixed() 메서드는 숫자가 아닌 문자열을 반환합니다. 이는 의도적인 것으로, 뒤에 오는 0은 표시에 의미가 있지만 숫자로 반환되면 손실되기 때문입니다.

toFixed()의 로케일 문제

toFixed() 메서드는 사용자의 로케일에 관계없이 항상 마침표를 소수점 구분 기호로 사용합니다. 많은 국가에서는 마침표 대신 쉼표를 소수점 구분 기호로 사용합니다.

const price = 19.99;
console.log(price.toFixed(2));
// Output: "19.99" (always uses period)

독일, 프랑스, 스페인 및 기타 많은 국가의 사용자에게는 이것이 잘못되어 보입니다. 그들은 "19.99" 대신 "19,99"를 보기를 기대합니다. toFixed() 메서드는 로케일에 적합한 출력을 생성할 수 없습니다.

다양한 로케일에 맞게 숫자를 올바르게 형식화하려면 Intl.NumberFormat API를 사용하세요.

로케일 인식 형식화를 위한 Intl.NumberFormat 사용

Intl.NumberFormat API는 로케일 규칙에 따라 숫자를 형식화합니다. 로케일과 옵션으로 포매터를 생성한 다음 숫자와 함께 format() 메서드를 호출하세요.

const formatter = new Intl.NumberFormat("de-DE", {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

const price = 19.99;
console.log(formatter.format(price));
// Output: "19,99" (uses comma for German locale)

동일한 포매터가 다양한 로케일에 대해 다른 출력을 생성합니다.

const price = 19.99;

const usFormatter = new Intl.NumberFormat("en-US", {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

const deFormatter = new Intl.NumberFormat("de-DE", {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

console.log(usFormatter.format(price));
// Output: "19.99"

console.log(deFormatter.format(price));
// Output: "19,99"

소수점 구분 기호는 로케일에 따라 자동으로 변경됩니다.

정확히 2자리 소수점으로 형식화

정확히 2자리의 소수를 표시하려면 minimumFractionDigitsmaximumFractionDigits를 모두 2로 설정하세요. 이렇게 하면 출력이 항상 2자리의 소수를 가지며, 필요할 때 0으로 채우고 숫자의 정밀도가 더 높을 때 반올림합니다.

const formatter = new Intl.NumberFormat("en-US", {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

console.log(formatter.format(5));
// Output: "5.00"

console.log(formatter.format(5.5));
// Output: "5.50"

console.log(formatter.format(5.555));
// Output: "5.56"

minimumFractionDigits 옵션은 후행 0을 제어합니다. 이 옵션이 없으면 소수 자릿수가 적은 숫자는 0을 표시하지 않습니다.

const withoutMinimum = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 2
});

console.log(withoutMinimum.format(5));
// Output: "5"

const withMinimum = new Intl.NumberFormat("en-US", {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

console.log(withMinimum.format(5));
// Output: "5.00"

두 옵션을 동일한 값으로 설정하면 모든 숫자에서 일관된 소수점 자릿수가 보장됩니다.

최대 2자리 소수점으로 형식화

때로는 필요할 때만 최대 2자리까지 소수점을 표시하고 싶을 수 있습니다. maximumFractionDigits를 2로 설정하고 minimumFractionDigits를 0으로 설정하거나 완전히 생략하세요.

const formatter = new Intl.NumberFormat("en-US", {
  minimumFractionDigits: 0,
  maximumFractionDigits: 2
});

console.log(formatter.format(5));
// Output: "5"

console.log(formatter.format(5.5));
// Output: "5.5"

console.log(formatter.format(5.555));
// Output: "5.56"

이 접근 방식은 후행 0을 제거하지만 여전히 정밀도를 2자리 소수점으로 제한합니다. 후행 0이 정보를 추가하지 않는 측정값이나 통계를 표시하는 데 적합합니다.

일반 숫자 형식 지정의 경우 minimumFractionDigits의 기본값은 0이므로 생략할 수 있습니다.

const formatter = new Intl.NumberFormat("en-US", {
  maximumFractionDigits: 2
});

console.log(formatter.format(5));
// Output: "5"

console.log(formatter.format(5.5));
// Output: "5.5"

더 나은 성능을 위한 포매터 재사용

새로운 Intl.NumberFormat 인스턴스를 생성하는 것은 상대적으로 비용이 많이 듭니다. 동일한 옵션으로 많은 숫자를 형식 지정하는 경우 포매터를 한 번 생성하고 재사용하세요.

const formatter = new Intl.NumberFormat("en-US", {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

const prices = [19.99, 29.5, 99, 149.999];

prices.forEach(price => {
  console.log(formatter.format(price));
});
// Output:
// "19.99"
// "29.50"
// "99.00"
// "150.00"

이 패턴은 각 숫자마다 새로운 포매터를 생성하는 것보다 더 효율적입니다.

각 접근 방식을 사용해야 하는 경우

가격, 통화 금액 또는 소수 자릿수가 의미를 갖는 값을 표시할 때는 정확히 소수점 이하 2자리를 사용하세요. "$5" 대신 "$5.00"을 표시하면 정밀도를 나타내고 가격에 대한 사용자의 기대와 일치합니다.

통계, 측정값 또는 계산된 값을 표시할 때는 최대 소수점 이하 2자리를 사용하세요. 이 경우 후행 0은 정보를 추가하지 않습니다. "5.00미터" 대신 "5미터"를 표시하는 것이 더 깔끔하고 읽기 쉽습니다.

toFixed()는 모든 사용자가 동일한 소수점 구분 기호 규칙을 사용한다고 확신하거나 출력이 사용자 대면이 아닌 경우에만 사용하세요. 국제화된 애플리케이션의 경우 Intl.NumberFormat를 선호하세요.

사용자의 선호 로케일 사용

로케일을 하드코딩하는 대신 사용자의 브라우저 언어 기본 설정을 사용하세요. navigator.language 속성은 사용자가 선호하는 로케일을 제공합니다.

const formatter = new Intl.NumberFormat(navigator.language, {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

const price = 19.99;
console.log(formatter.format(price));
// Output varies by user's locale
// For en-US: "19.99"
// For de-DE: "19,99"
// For fr-FR: "19,99"

또한 전체 navigator.languages 배열을 전달하여 Intl API가 사용자의 기본 설정에서 지원되는 첫 번째 로케일을 선택하도록 할 수 있습니다.

const formatter = new Intl.NumberFormat(navigator.languages, {
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

이 접근 방식은 사용자의 첫 번째 기본 설정이 지원되지 않는 경우 자동 폴백을 제공합니다.