Как форматировать числа по значащим цифрам
Управляйте отображением и округлением чисел, задавая точность через значащие цифры
Введение
При форматировании чисел для отображения иногда нужно контролировать точность не по количеству знаков после запятой, а по количеству значащих цифр. Такой подход называется форматированием по значащим цифрам.
Значащие цифры — это цифры в числе, которые несут важную информацию о его точности. В числе 123,45 — пять значащих цифр. В числе 0,00123 — три значащие цифры, потому что ведущие нули показывают только порядок числа, а не его точность.
В этом уроке вы узнаете, как форматировать числа по значащим цифрам в JavaScript. Вы поймёте, когда этот подход лучше, чем контроль количества знаков после запятой, и как использовать опции minimumSignificantDigits и maximumSignificantDigits с API Intl.NumberFormat.
Что такое значащие цифры
Значащие цифры — это цифры в числе, которые определяют его точность. Чтобы понять, какие цифры считаются значащими, нужно следовать определённым правилам.
Все отличные от нуля цифры всегда значащие. В числе 123 все три цифры значащие. В 45,67 — все четыре цифры значащие.
Ведущие нули никогда не считаются значащими. Они только указывают положение десятичной точки. В числе 0,0045 значащими являются только 4 и 5. В этом числе две значащие цифры, а не шесть.
Концевые нули после запятой считаются значащими. Они показывают, что измерение или вычисление было выполнено с такой точностью. В числе 1,200 — четыре значащие цифры, а в 1,2 — только две.
Нули в конце числа перед десятичной точкой зависят от контекста. В числе 1200 без дополнительной информации неясно, являются ли эти нули значимыми. Эту неоднозначность можно устранить с помощью научной записи или явного указания точности.
Форматирование чисел с максимальным количеством значимых цифр
Параметр maximumSignificantDigits ограничивает количество значимых цифр в отформатированном числе. Это удобно, если нужно показывать числа с одинаковой точностью независимо от их величины.
const formatter = new Intl.NumberFormat("en-US", {
maximumSignificantDigits: 3,
});
console.log(formatter.format(1.2345));
// Output: "1.23"
console.log(formatter.format(12.345));
// Output: "12.3"
console.log(formatter.format(123.45));
// Output: "123"
console.log(formatter.format(1234.5));
// Output: "1,230"
Если в числе больше значимых цифр, чем указано в максимуме, форматтер округляет число. Округление происходит по стандартным правилам — до ближайшего значения. Если число находится ровно посередине между двумя значениями, оно округляется до ближайшего чётного.
Параметр maximumSignificantDigits принимает значения от 1 до 21. По умолчанию, если параметр не указан, используется 21, что фактически означает отсутствие ограничения.
const oneDigit = new Intl.NumberFormat("en-US", {
maximumSignificantDigits: 1,
});
console.log(oneDigit.format(54.33));
// Output: "50"
console.log(oneDigit.format(56.33));
// Output: "60"
Этот параметр работает со всеми типами чисел: целыми, десятичными и числами в разных форматах записи.
Форматирование чисел с минимальным количеством значимых цифр
Параметр minimumSignificantDigits гарантирует, что в отформатированном числе будет не меньше указанного количества значимых цифр. Если в числе меньше значимых цифр, чем минимум, форматтер добавляет нули в конце.
const formatter = new Intl.NumberFormat("en-US", {
minimumSignificantDigits: 5,
});
console.log(formatter.format(1.23));
// Output: "1.2300"
console.log(formatter.format(123));
// Output: "123.00"
console.log(formatter.format(0.0012));
// Output: "0.0012000"
Этот параметр полезен, если нужно показывать числа с одинаковой точностью, чтобы было видно, что измерения или вычисления проводились с определённой точностью.
Параметр minimumSignificantDigits принимает значения от 1 до 21. Значение по умолчанию — 1, то есть числа отображаются с их естественной точностью без добавления нулей.
const manyDigits = new Intl.NumberFormat("en-US", {
minimumSignificantDigits: 10,
});
console.log(manyDigits.format(5));
// Output: "5.000000000"
Форматтер добавляет нули после запятой, чтобы достичь минимального количества знаков, или добавляет нули перед запятой, если это необходимо.
Совмещение минимального и максимального количества значащих цифр
Вы можете указать одновременно minimumSignificantDigits и maximumSignificantDigits, чтобы задать диапазон допустимой точности. Форматтер будет отображать числа в этом диапазоне.
const formatter = new Intl.NumberFormat("en-US", {
minimumSignificantDigits: 3,
maximumSignificantDigits: 5,
});
console.log(formatter.format(1.2));
// Output: "1.20"
// Expanded to meet minimum of 3
console.log(formatter.format(1.234));
// Output: "1.234"
// Within range, displayed as-is
console.log(formatter.format(1.23456789));
// Output: "1.2346"
// Rounded to meet maximum of 5
При совмещении этих опций минимальное значение должно быть меньше или равно максимальному. Если вы укажете минимальное значение больше максимального, форматтер выдаст ошибку RangeError.
try {
const invalid = new Intl.NumberFormat("en-US", {
minimumSignificantDigits: 5,
maximumSignificantDigits: 3,
});
} catch (error) {
console.log(error.name);
// Output: "RangeError"
}
Такое сочетание особенно полезно в научных или финансовых приложениях, когда нужно обеспечить минимальный уровень точности и при этом не перегружать отображение лишними знаками.
Чем значащие цифры отличаются от знаков после запятой
Значащие цифры и знаки после запятой — это два разных подхода к управлению точностью чисел. Понимание, когда использовать каждый из них, поможет правильно форматировать числа.
Знаки после запятой определяют, сколько цифр будет отображаться после запятой, независимо от величины числа. Опции minimumFractionDigits и maximumFractionDigits реализуют этот подход.
const decimalPlaces = new Intl.NumberFormat("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
console.log(decimalPlaces.format(1.2));
// Output: "1.20"
console.log(decimalPlaces.format(12.3));
// Output: "12.30"
console.log(decimalPlaces.format(123.4));
// Output: "123.40"
Значащие цифры определяют, сколько значимых цифр будет показано во всём числе, подстраиваясь под его величину. Числа с разным порядком величины будут показывать разное количество знаков после запятой, чтобы сохранять одинаковую точность.
const significantDigits = new Intl.NumberFormat("en-US", {
minimumSignificantDigits: 3,
maximumSignificantDigits: 3,
});
console.log(significantDigits.format(1.2));
// Output: "1.20"
console.log(significantDigits.format(12.3));
// Output: "12.3"
console.log(significantDigits.format(123.4));
// Output: "123"
Обратите внимание, что при использовании значащих цифр количество знаков после запятой уменьшается с увеличением величины числа, а при использовании знаков после запятой их количество остаётся одинаковым независимо от величины.
Взаимодействие с опциями дробных знаков
Когда вы указываете параметры значимых цифр, они по умолчанию имеют приоритет над параметрами дробных разрядов. Форматтер игнорирует minimumFractionDigits и maximumFractionDigits, если задан хотя бы один параметр значимых цифр.
const formatter = new Intl.NumberFormat("en-US", {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
maximumSignificantDigits: 3,
});
console.log(formatter.format(1234.56));
// Output: "1,230"
// Significant digits option takes precedence
// Fraction digit options are ignored
Это поведение регулируется опцией roundingPriority, которая определяет, как форматтер разрешает конфликты между разными настройками точности. Значение по умолчанию — "auto", при котором приоритет отдается значимым цифрам.
Вы можете изменить это поведение, установив roundingPriority в "morePrecision" или "lessPrecision", но это продвинутые опции для специальных случаев. Для большинства задач стандартное поведение приоритета подходит.
Когда использовать значимые цифры вместо знаков после запятой
Выбирайте значимые цифры, если вам нужна одинаковая точность для чисел с разными порядками величин. Такой подход часто используется в науке, инженерии и визуализации данных.
Используйте значимые цифры для научных измерений и расчетов. Результаты лабораторных анализов, показания датчиков и физические измерения часто должны отражать точность измерительного прибора. Отображение трёх значимых цифр всегда показывает уровень точности, независимо от того, составляет ли измерение 0,0123, 1,23 или 123.
const measurement = new Intl.NumberFormat("en-US", {
maximumSignificantDigits: 4,
});
console.log(measurement.format(0.012345));
// Output: "0.01235"
console.log(measurement.format(1.2345));
// Output: "1.235"
console.log(measurement.format(1234.5));
// Output: "1,235"
Используйте значимые цифры для метрик на дашбордах, где отображаются числа с разными порядками величин. Например, при показе статистики просмотров страниц, дохода или количества пользователей значимые цифры не дают маленьким числам выглядеть слишком детализированными, а большие — остаются читаемыми.
const metric = new Intl.NumberFormat("en-US", {
maximumSignificantDigits: 3,
});
console.log(metric.format(1.234));
// Output: "1.23"
console.log(metric.format(123.4));
// Output: "123"
console.log(metric.format(12345));
// Output: "12,300"
Используйте знаки после запятой для валюты и финансовых сумм, где дробная часть означает центы или другие фиксированные денежные единицы. Для таких сумм важно всегда показывать одинаковое количество знаков после запятой, независимо от величины.
const currency = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
console.log(currency.format(1.5));
// Output: "$1.50"
console.log(currency.format(123.5));
// Output: "$123.50"
Выбор между этими подходами зависит от того, связана ли точность с общим количеством цифр или с фиксированной дробной частью.