Как управлять количеством десятичных знаков при форматировании процентов

Установите точное или максимальное количество десятичных знаков для процентных значений, чтобы контролировать точность и отображение

Введение

Разные контексты требуют разного уровня точности при отображении процентов. Процентная ставка 3.25% требует ровно два знака после запятой, чтобы передать точное значение. Коэффициент конверсии, отображаемый на панели мониторинга, лучше выглядит как 85.5% с одним знаком после запятой для удобства чтения. Процент выполнения вполне приемлем в виде 100% без знаков после запятой.

Без контроля над количеством знаков после запятой форматирование процентов становится непоследовательным. Значение 0.8547 может отображаться как 85% в одном месте и как 85.47% в другом, создавая путаницу относительно того, какое представление является точным. Явный контроль над количеством знаков после запятой обеспечивает единообразную точность во всем приложении.

API Intl.NumberFormat в JavaScript предоставляет параметры minimumFractionDigits и maximumFractionDigits для управления количеством знаков после запятой при форматировании процентов. Эти параметры работают с учетом локализации, чтобы правильно отображать проценты для пользователей по всему миру.

Как проценты отображаются по умолчанию

API Intl.NumberFormat по умолчанию форматирует проценты без знаков после запятой. Оно умножает входное значение на 100, округляет до ближайшего целого числа и добавляет знак процента.

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

console.log(formatter.format(0.8547));
// Вывод: "85%"

console.log(formatter.format(0.8234));
// Вывод: "82%"

console.log(formatter.format(0.0325));
// Вывод: "3%"

Все проценты отображаются как целые числа, независимо от точности входного значения. Форматтер округляет 0.8547 до 85% и 0.8234 до 82%, отбрасывая информацию о десятичных долях.

Такое поведение по умолчанию хорошо подходит для отображения процентов выполнения, результатов опросов или других значений, где десятичная точность не добавляет значимой информации. Однако во многих случаях требуется отображение знаков после запятой для передачи точных значений.

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

const conversionRate = 0.8547;
console.log(formatter.format(conversionRate));
// Вывод: "85%"

Отображение коэффициента конверсии как 85%, когда фактическое значение составляет 85.47%, скрывает важную точность, которая влияет на бизнес-решения и анализ.

Форматирование процентов с точным количеством десятичных знаков

Чтобы отобразить определённое количество десятичных знаков, установите значения minimumFractionDigits и maximumFractionDigits одинаковыми. Это гарантирует, что каждый процент будет отображаться с точно таким количеством десятичных знаков.

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

console.log(formatter.format(0.8547));
// Вывод: "85.47%"

console.log(formatter.format(0.0325));
// Вывод: "3.25%"

console.log(formatter.format(0.85));
// Вывод: "85.00%"

Форматер отображает ровно два десятичных знака для всех значений. Если входное значение имеет большую точность, форматер округляет до двух десятичных знаков. Если входное значение имеет меньше десятичных знаков, форматер добавляет нули.

Установка обоих параметров в одно и то же значение гарантирует единообразное количество десятичных знаков для всех процентов в вашем приложении. Это важно для финансовых отображений, таблиц данных и любого интерфейса, где пользователи сравнивают несколько процентных значений.

Форматирование с одним десятичным знаком

Установите оба параметра в 1, чтобы отображать ровно один десятичный знак.

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

console.log(formatter.format(0.8547));
// Вывод: "85.5%"

console.log(formatter.format(0.85));
// Вывод: "85.0%"

console.log(formatter.format(0.8234));
// Вывод: "82.3%"

Форматер округляет 0.8547 до 85.5% и отображает 0.85 как 85.0% с завершающим нулём. Этот формат хорошо подходит для отображения на панелях управления, где одного десятичного знака достаточно для точности, не перегружая пользователей числами.

Форматирование с тремя или более десятичными знаками

Научные или финансовые приложения иногда требуют более двух десятичных знаков. Установите оба параметра в 3 или больше для увеличения точности.

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

console.log(formatter.format(0.854732));
// Вывод: "85.473%"

console.log(formatter.format(0.85));
// Вывод: "85.000%"

Форматер отображает ровно три десятичных знака, добавляя нули при необходимости. Такой уровень точности подходит для лабораторных измерений, статистического анализа или финансовых расчётов, требующих высокой точности.

Форматирование процентов с точностью до N десятичных знаков

Иногда требуется отображать десятичные знаки только тогда, когда они предоставляют значимую информацию. Установите maximumFractionDigits, чтобы ограничить точность, позволяя форматеру опускать ненужные конечные нули.

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

console.log(formatter.format(0.8547));
// Вывод: "85.47%"

console.log(formatter.format(0.85));
// Вывод: "85%"

console.log(formatter.format(0.8));
// Вывод: "80%"

Форматер отображает до двух десятичных знаков, но удаляет конечные нули. Значение 0.8547 отображается как 85.47% с двумя десятичными знаками, тогда как 0.85 отображается как 85% без ненужных нулей.

Этот подход хорошо подходит для отображения статистики, метрик или вычисленных значений, где конечные нули не добавляют информации. Отображение 85% вместо 85.00% создает более чистый и читаемый вид.

Вы можете установить minimumFractionDigits на значение меньшее, чем maximumFractionDigits, чтобы контролировать, сколько конечных нулей будет отображаться.

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

console.log(formatter.format(0.8547));
// Вывод: "85.47%"

console.log(formatter.format(0.85));
// Вывод: "85.0%"

console.log(formatter.format(0.8));
// Вывод: "80.0%"

Теперь форматер всегда показывает как минимум один десятичный знак, но отображает второй десятичный знак только при необходимости. Этот формат поддерживает визуальную согласованность, избегая излишней точности.

Локальное форматирование десятичных разделителей в процентах

Разные локали используют разные символы в качестве десятичных разделителей. API Intl.NumberFormat автоматически использует правильный разделитель для каждой локали.

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

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

const rate = 0.8547;

console.log(usFormatter.format(rate));
// Вывод: "85.47%"

console.log(deFormatter.format(rate));
// Вывод: "85,47 %"

Форматер для американского английского использует точку в качестве десятичного разделителя и размещает знак процента сразу после числа. Немецкий форматер использует запятую в качестве десятичного разделителя и добавляет пробел перед знаком процента.

Эти различия распространяются на многие локали. Французский использует запятую, как и немецкий. Арабский использует другие формы цифр. API Intl.NumberFormat автоматически обрабатывает все эти вариации, когда вы указываете соответствующую локаль.

const frFormatter = new Intl.NumberFormat("fr-FR", {
  style: "percent",
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

const arFormatter = new Intl.NumberFormat("ar-EG", {
  style: "percent",
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

const rate = 0.8547;

console.log(frFormatter.format(rate));
// Вывод: "85,47 %"

console.log(arFormatter.format(rate));
// Вывод: "٨٥٫٤٧٪"

Арабский форматер использует арабско-индийские цифры и арабский знак процента. Используя форматирование, учитывающее локаль, ваши проценты будут отображаться корректно для пользователей независимо от их языка и региона.

Когда использовать точное количество десятичных знаков и максимальное

Выбирайте между точным количеством десятичных знаков и максимальным количеством в зависимости от контекста и цели отображения процентов.

Используйте точное количество десятичных знаков для финансовых процентов, таких как процентные ставки, годовые процентные ставки (APR) или доходность. Эти значения требуют постоянной точности для соблюдения нормативных требований и ожиданий пользователей. Процентная ставка всегда должна отображаться как 3,25%, а не как 3,3% или 3%, чтобы избежать путаницы относительно фактической ставки.

Используйте точное количество десятичных знаков для таблиц данных и сравнительных отображений, где пользователи читают несколько процентов одновременно. Последовательное количество десятичных знаков упрощает сравнение и предотвращает визуальную несогласованность, которая может указывать на различную точность исходных данных.

Используйте максимальное количество десятичных знаков для панелей управления и сводной статистики, где читаемость важнее точности. Отображение 85% вместо 85,00% создает более чистый интерфейс. Показывайте десятичные знаки только тогда, когда они предоставляют значимую информацию.

Используйте максимальное количество десятичных знаков для вычисленных процентов, которые могут быть целыми числами. Проценты завершения, показатели успеха и распределения часто заканчиваются на .00 и выглядят лучше без завершающих нулей.

Форматирование отрицательных процентов с десятичными знаками

Опции для десятичных знаков работают одинаково для отрицательных процентов. Форматтер отображает соответствующее количество десятичных знаков независимо от того, положительный процент или отрицательный.

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

console.log(formatter.format(-0.0325));
// Вывод: "-3,25%"

console.log(formatter.format(-0.1547));
// Вывод: "-15,47%"

Знак минуса появляется перед числом, а десятичные знаки отображаются в соответствии с вашими параметрами форматирования. Это работает для отображения процентных изменений, снижений или убытков.

Повторное использование форматтеров для повышения производительности

Создание нового экземпляра Intl.NumberFormat требует выполнения операций инициализации. Если вы форматируете множество процентов с одинаковыми параметрами, создайте форматтер один раз и используйте его повторно.

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

const rates = [0.8547, 0.0325, 0.9123, 0.0045];

rates.forEach(rate => {
  console.log(formatter.format(rate));
});
// Результат:
// "85.47%"
// "3.25%"
// "91.23%"
// "0.45%"

Этот подход более эффективен, чем создание нового форматтера для каждого процента. Разница в производительности становится заметной при форматировании сотен или тысяч значений, например, при рендеринге таблиц или графиков.

Использование предпочтительного языка пользователя

Вместо жесткого указания локали используйте языковые предпочтения браузера пользователя для форматирования процентов в ожидаемом формате. Свойство navigator.language предоставляет предпочтительную локаль пользователя.

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

const rate = 0.8547;
console.log(formatter.format(rate));
// Результат зависит от локали пользователя
// Для en-US: "85.47%"
// Для de-DE: "85,47 %"
// Для fr-FR: "85,47 %"

Вы также можете передать весь массив navigator.languages, чтобы API Intl выбрал первую поддерживаемую локаль из предпочтений пользователя.

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

Этот подход обеспечивает автоматический резервный вариант, если первая предпочтительная локаль пользователя не поддерживается средой выполнения.