如何以工程计数法格式化数字

使用工程计数法以指数形式显示与国际单位制(SI)前缀对齐的数字

简介

工程计数法是一种使用 10 的幂来表示数字的方法,其中指数始终是 3 的倍数。例如,123,000,000 在工程计数法中不会显示为 1.23×10⁸,而是显示为 123×10⁶。这种与 3 的倍数对齐的方式符合国际单位制 (SI) 前缀,例如千 (10³)、兆 (10⁶) 和吉 (10⁹)。

这种计数法在工程、电子学和科学领域中经常出现,因为这些领域的测量通常使用 SI 前缀。例如,标称值为 4.7×10⁻⁶ 法拉的电容器会被表示为 4.7 微法拉。频率为 2.4×10⁹ 赫兹会被表示为 2.4 吉赫兹。工程计数法使这些转换变得自然,因为指数直接对应于 SI 前缀。

JavaScript 提供了对工程计数法的内置支持,通过 Intl.NumberFormat API 实现。该 API 能够自动处理转换,并根据不同的语言和地区调整格式。

什么是工程计数法

工程计数法将数字表示为一个系数乘以 10 的幂,其中指数始终是 3 的倍数。例如,数字 987,654,321 在工程计数法中表示为 987.654×10⁶,在 JavaScript 输出中写作 987.654E6。

系数是一个介于 1 和 999.999 之间的数字,后跟 E 和指数。E 代表指数,表示乘以 10 的该幂次方。值 987.654E6 的含义是 987.654 × 10⁶,等于 987,654,000。

这种格式不同于标准十进制计数法,后者使用分隔符将所有数字写出,例如 987,654,321。它也不同于紧凑计数法,后者使用 K、M 和 B 等字母来表示数量级。工程计数法通过指数计数法明确显示 10 的幂。

为什么工程计数法使用 3 的倍数

限制为 3 的倍数是因为 SI 单位前缀是以 1000 为因数递增或递减的。每向上一个前缀级别乘以 10³,每向下一个前缀级别除以 10³。

以下是 10 的幂次对应的 SI 前缀:

  • 10³ = 千 (k)
  • 10⁶ = 兆 (M)
  • 10⁹ = 吉 (G)
  • 10¹² = 太 (T)
  • 10⁻³ = 毫 (m)
  • 10⁻⁶ = 微 (μ)
  • 10⁻⁹ = 纳 (n)
  • 10⁻¹² = 皮 (p)

当一个数字使用工程计数法且指数为 6 时,你知道它对应的是兆 (mega) 前缀。当指数为 -9 时,你知道它对应的是纳 (nano) 前缀。这种直接对应使得工程计数法在以 SI 单位为主的技术领域中非常实用。

如果没有这种限制,你需要进行心算来在计数法和 SI 前缀之间转换。而有了这种限制,转换是即时的。

工程计数法与科学计数法的区别

科学计数法也使用 10 的幂次表示数字,但它使用最小可能的指数。例如,数字 987,654,321 在科学计数法中表示为 9.87654321×10⁸,写作 9.87654321E8。

科学计数法总是将小数点前保留一个非零数字。而工程计数法允许小数点前最多保留三位数字,以确保指数是 3 的倍数。

const scientificFormatter = new Intl.NumberFormat("en-US", {
  notation: "scientific"
});

console.log(scientificFormatter.format(987654321));
// 输出: "9.877E8"

const engineeringFormatter = new Intl.NumberFormat("en-US", {
  notation: "engineering"
});

console.log(engineeringFormatter.format(987654321));
// 输出: "987.654E6"

科学计数法格式化器输出 9.877E8,将小数点前保留一位数字。而工程计数法格式化器输出 987.654E6,将小数点前保留三位数字,从而使指数为 6 而不是 8。

两种计数法表示的值相同,但工程计数法优先考虑与 SI 前缀的对齐,而不是最小化指数。

在 JavaScript 中使用工程计数法

Intl.NumberFormatnotation 选项控制数字的表示方式。将其设置为 "engineering" 可启用工程计数法。

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

console.log(formatter.format(1500));
// 输出: "1.5E3"

console.log(formatter.format(1500000));
// 输出: "1.5E6"

console.log(formatter.format(1500000000));
// 输出: "1.5E9"

格式化器会根据数字的大小自动选择合适的指数。指数始终是 3 的倍数,以确保与国际单位制 (SI) 前缀对齐。

您无需手动计算正确的指数或系数。Intl API 会根据数字的值自动处理这些计算。

工程计数法如何格式化不同数量级的数字

工程计数法适用于所有范围的数字,从非常小到非常大的数字。了解不同数量级如何映射到指数有助于预测输出结果。

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

console.log(formatter.format(0.0015));
// 输出: "1.5E-3"

console.log(formatter.format(0.0000015));
// 输出: "1.5E-6"

console.log(formatter.format(1.5));
// 输出: "1.5E0"

console.log(formatter.format(1500));
// 输出: "1.5E3"

console.log(formatter.format(1500000));
// 输出: "1.5E6"

console.log(formatter.format(1500000000));
// 输出: "1.5E9"

console.log(formatter.format(1500000000000));
// 输出: "1.5E12"

小于 1 的数字使用负指数。例如,数字 0.0015 会变成 1.5E-3,对应于毫 (milli) 前缀。数字 0.0000015 会变成 1.5E-6,对应于微 (micro) 前缀。

接近 1 的数字使用指数 0。例如,数字 1.5 会变成 1.5E0,即 1.5 × 10⁰ = 1.5 × 1 = 1.5。

较大的数字使用正指数。例如,数字 1500 会变成 1.5E3,对应于千 (kilo) 前缀。此模式会继续适用于兆 (mega)、吉 (giga) 和太 (tera)。

控制工程计数法中的小数位数

默认情况下,格式化器会在系数中包含若干小数位。您可以使用 minimumFractionDigitsmaximumFractionDigits 选项来控制精度。

const defaultFormatter = new Intl.NumberFormat("en-US", {
  notation: "engineering"
});

console.log(defaultFormatter.format(1234567));
// 输出: "1.235E6"

const noDecimalsFormatter = new Intl.NumberFormat("en-US", {
  notation: "engineering",
  maximumFractionDigits: 0
});

console.log(noDecimalsFormatter.format(1234567));
// 输出: "1E6"

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

console.log(twoDecimalsFormatter.format(1234567));
// 输出: "1.23E6"

maximumFractionDigits 选项限制了系数中小数点后的位数。将其设置为 0 会移除所有小数位,仅显示系数的整数部分。

您还可以强制显示最少的小数位数,以在多个数字之间保持一致的格式。

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

console.log(formatter.format(1000));
// 输出: "1.00E3"

console.log(formatter.format(1500));
// 输出: "1.50E3"

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

这确保了所有数字都显示精确的两位小数,有助于在表格和报告中保持视觉一致性。

工程计数法在不同语言环境中的工作原理

工程计数法会根据不同语言环境的十进制分隔符约定进行适配。指数格式保持一致,但系数的格式会根据语言环境而变化。

const enFormatter = new Intl.NumberFormat("en-US", {
  notation: "engineering"
});

console.log(enFormatter.format(1234567));
// 输出: "1.235E6"

const deFormatter = new Intl.NumberFormat("de-DE", {
  notation: "engineering"
});

console.log(deFormatter.format(1234567));
// 输出: "1,235E6"

const frFormatter = new Intl.NumberFormat("fr-FR", {
  notation: "engineering"
});

console.log(frFormatter.format(1234567));
// 输出: "1,235E6"

英语使用句点作为系数中的十进制分隔符。德语和法语使用逗号作为十进制分隔符。E 和指数在所有语言环境中保持不变。

这种本地化仅适用于系数部分。使用 E 和指数值的指数表示法遵循国际科学惯例,在不同语言环境之间不会发生变化。

将工程计数法与其他格式选项结合使用

工程计数法可以与其他数字格式选项一起使用。您可以在使用工程计数法时控制舍入、有效数字和符号显示。

const formatter = new Intl.NumberFormat("en-US", {
  notation: "engineering",
  signDisplay: "always"
});

console.log(formatter.format(1500000));
// 输出: "+1.5E6"

console.log(formatter.format(-1500000));
// 输出: "-1.5E6"

signDisplay 选项控制正数是否显示加号。将其设置为 "always" 会为正负值都显示符号。

您还可以控制有效数字而不是小数位数。

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

console.log(formatter.format(1234567));
// 输出: "1.235E6"

console.log(formatter.format(1567890));
// 输出: "1.568E6"

minimumSignificantDigitsmaximumSignificantDigits 选项控制系数中有意义数字的总数,而不仅仅是小数位数。

何时使用工程计数法

工程计数法最适用于技术场景,尤其是使用国际单位制(SI)前缀的测量值。电子文档、科学论文和工程规范中通常会使用这种计数法。

在记录一个具有 4.7×10⁻⁶ 法拉电容的电路时,工程计数法将其显示为 4.7E-6。工程师会立即识别这表示 4.7 微法拉。当显示一个 2.4×10⁹ 赫兹的频率时,工程计数法将其显示为 2.4E9,工程师会识别为 2.4 吉赫兹。

这种计数法不太适合普通受众,因为他们可能不理解指数计数法。社交媒体计数器、电商价格和面向消费者的仪表盘应使用标准计数法或简洁计数法。

在精度至关重要且所有数字都必须准确的情况下,不要使用工程计数法。财务计算、法律文件和审计记录需要精确的十进制表示。例如,银行余额应显示为 $1,234.56,而不是 1.23456E3。

请考虑您的受众。工程师、物理学家和技术专业人士期望并理解工程计数法。普通消费者则更容易阅读标准计数法或简洁计数法。