如何使用有效数字格式化数字

通过指定精度来控制格式化数字中显示和舍入的数字

介绍

在格式化数字以供显示时,有时需要根据数字中包含的有效位数来控制精度,而不是仅仅根据小数点后的位数。这种方法称为使用有效位数进行格式化。

有效位数是指数字中携带有关其精度的有意义信息的数字。数字 123.45 有五个有效位数。数字 0.00123 有三个有效位数,因为前导零仅表示数量级,而不表示精度。

本课程将向您展示如何在 JavaScript 中使用有效位数格式化数字。您将了解这种方法何时比控制小数位数更好,以及如何使用 minimumSignificantDigitsmaximumSignificantDigits 选项与 Intl.NumberFormat API。

什么是有效位数

有效位数是数字中表示其精度的数字。理解哪些数字是有效的需要遵循特定规则。

所有非零数字始终是有效的。在数字 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));
// 输出: "1.23"

console.log(formatter.format(12.345));
// 输出: "12.3"

console.log(formatter.format(123.45));
// 输出: "123"

console.log(formatter.format(1234.5));
// 输出: "1,230"

当数字的有效位数超过最大值时,格式化器会对数字进行四舍五入。四舍五入遵循标准的舍入规则,向最接近的值舍入。当数字正好位于两个值的中间时,会舍入到最接近的偶数。

maximumSignificantDigits 选项接受的值范围是 1 到 21。如果未指定此选项,默认值为 21,这实际上意味着没有限制。

const oneDigit = new Intl.NumberFormat("en-US", {
  maximumSignificantDigits: 1,
});

console.log(oneDigit.format(54.33));
// 输出: "50"

console.log(oneDigit.format(56.33));
// 输出: "60"

此选项适用于所有数字类型,包括整数、小数和不同表示法的数字。

使用最小有效数字格式化数字

minimumSignificantDigits 选项确保格式化输出中至少显示指定数量的有效数字。当数字的有效位数少于最小值时,格式化器会添加尾随零。

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

console.log(formatter.format(1.23));
// 输出: "1.2300"

console.log(formatter.format(123));
// 输出: "123.00"

console.log(formatter.format(0.0012));
// 输出: "0.0012000"

当您需要以一致的精度显示数字,表明测量或计算是以特定的准确性完成时,此选项非常有用。

minimumSignificantDigits 选项接受的值范围是 1 到 21。默认值为 1,这意味着数字以其自然精度显示,不会添加零。

const manyDigits = new Intl.NumberFormat("en-US", {
  minimumSignificantDigits: 10,
});

console.log(manyDigits.format(5));
// 输出: "5.000000000"

格式化器会在小数点后添加零以达到最小值,或者在必要时在小数点前添加零。

结合最小有效数字和最大有效数字

您可以同时指定 minimumSignificantDigitsmaximumSignificantDigits,以创建一个可接受的精度范围。格式化器将在此范围内显示数字。

const formatter = new Intl.NumberFormat("en-US", {
  minimumSignificantDigits: 3,
  maximumSignificantDigits: 5,
});

console.log(formatter.format(1.2));
// 输出: "1.20"
// 扩展以满足最小值 3

console.log(formatter.format(1.234));
// 输出: "1.234"
// 在范围内,按原样显示

console.log(formatter.format(1.23456789));
// 输出: "1.2346"
// 四舍五入以满足最大值 5

在组合这些选项时,最小值必须小于或等于最大值。如果您指定的最小值大于最大值,格式化器将抛出一个 RangeError。

try {
  const invalid = new Intl.NumberFormat("en-US", {
    minimumSignificantDigits: 5,
    maximumSignificantDigits: 3,
  });
} catch (error) {
  console.log(error.name);
  // 输出: "RangeError"
}

这种组合在科学或金融应用中特别有用,因为您可以同时强制执行最低精度水平并防止过多的数字使显示变得混乱。

有效数字与小数位的区别

有效数字和小数位是控制数字精度的两种不同方法。了解何时使用每种方法有助于您适当地格式化数字。

小数位控制小数点后显示的数字数量,而不考虑数字的大小。选项 minimumFractionDigitsmaximumFractionDigits 实现了这种方法。

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

console.log(decimalPlaces.format(1.2));
// 输出: "1.20"

console.log(decimalPlaces.format(12.3));
// 输出: "12.30"

console.log(decimalPlaces.format(123.4));
// 输出: "123.40"

有效数字控制整个数字中显示的有意义数字的数量,并根据数字的大小进行调整。具有不同大小的数字会显示不同数量的小数位,以保持一致的精度。

const significantDigits = new Intl.NumberFormat("en-US", {
  minimumSignificantDigits: 3,
  maximumSignificantDigits: 3,
});

console.log(significantDigits.format(1.2));
// 输出: "1.20"

console.log(significantDigits.format(12.3));
// 输出: "12.3"

console.log(significantDigits.format(123.4));
// 输出: "123"

注意,有效数字方法随着数字大小的增加显示更少的小数位,而小数位方法无论大小如何都显示相同数量的小数位。

与小数位选项的交互

当您指定有效数字选项时,它们默认优先于小数位选项。当存在任何有效数字选项时,格式化器会忽略 minimumFractionDigitsmaximumFractionDigits

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

console.log(formatter.format(1234.56));
// 输出: "1,230"
// 有效数字选项优先
// 小数位选项被忽略

此行为由 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));
// 输出: "0.01235"

console.log(measurement.format(1.2345));
// 输出: "1.235"

console.log(measurement.format(1234.5));
// 输出: "1,235"

在显示具有不同数量级的数字的仪表板指标时使用有效数字。当显示页面浏览量、收入或用户数量等统计数据时,有效数字可以防止小数字显示过多的精度,同时保持大数字的可读性。

const metric = new Intl.NumberFormat("en-US", {
  maximumSignificantDigits: 3,
});

console.log(metric.format(1.234));
// 输出: "1.23"

console.log(metric.format(123.4));
// 输出: "123"

console.log(metric.format(12345));
// 输出: "12,300"

对于货币和财务金额,使用小数位,其中小数部分表示分币或其他固定货币单位。这些金额需要在不同数量级之间保持一致的小数位。

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

console.log(currency.format(1.5));
// 输出: "$1.50"

console.log(currency.format(123.5));
// 输出: "$123.50"

在这些方法之间的选择取决于精度是与总位数相关还是与固定的小数部分相关。