【问题标题】:Use `Intl.NumberFormat` with `maximumFractionDigits` and `maximumSignificantDigits` at once同时使用 `Intl.NumberFormat` 和 `maximumFractionDigits` 和 `maximumSignificantDigits`
【发布时间】:2019-09-14 00:27:27
【问题描述】:

运行时

console.log(new Intl.NumberFormat('en-US', {
  minimumFractionDigits: 0,
  maximumFractionDigits: 0,
  maximumSignificantDigits: 3,
  minimumSignificantDigits: 1 
}).format(10.123456789));

我希望输出为10。相反,由于某种原因,它输出 10.1 打破了 maximumFractionDigits: 0 约束。这是怎么回事?考虑到这个约束在浏览器中被忽略,这似乎符合规范,但我无法想象这是什么原因。

【问题讨论】:

  • 这种同样的行为似乎也在迅速发生:stackoverflow.com/questions/27644341/…
  • 似乎有效数字优先于小数数字。我想如果你真的不想要小数位数,你总是可以Math.round,尽管我同意这不太理想。

标签: javascript number-formatting


【解决方案1】:

来自Intl.NumberFormat parameter descriptions(强调添加):

以下属性分为两组:minimumIntegerDigitsminimumFractionDigitsmaximumFractionDigits 在一组中, minimumSignificantDigitsmaximumSignificantDigits 在另一个。 如果 至少定义了第二组中的一个属性,然后第一个 组被忽略。

必须有一些覆盖行为来处理属性设置冲突,但在您的示例中,人们可能有理由希望覆盖行为不是全有或全无(因为对小数位数限制的调整落在指定范围内有效数字)。不幸的是,如果设置了有效数字属性,规范只是忽略任何分数或整数数字限制。

如果有人来寻找一种方法来利用这两种类型的属性来格式化单个数字,下面是一个非常基本的示例,它连续使用两个构造函数(请注意,如果格式化要求更复杂,这可能会很快变得混乱)。

const sigDigits = (n, min, max, minf, maxf) => {
  let num = new Intl.NumberFormat('en-US', {
    minimumSignificantDigits: min,
    maximumSignificantDigits: max
  })
  .format(n);
  
  num = new Intl.NumberFormat('en-US', {
    minimumFractionDigits: minf,
    maximumFractionDigits: maxf
  })
  .format(num);
  
  return num;
};

const result = sigDigits(10.123456789, 1, 3, 0, 0);
console.log(result);
// 10

【讨论】:

  • 是的,这正是我最终所做的,只是对这种行为感到非常困惑,以至于我不得不问是否有人知道一些理由或任何东西......至少它可以在这种情况下抛出一个错误(就像你提供一个超出界限的值一样),但是哦,好吧~奇怪的是他们似乎没有任何批判性思考就复制了 Swift 规范。
  • 无论如何,我在 MDN 页面上错过了那一行(我认为它属于分组参数)。可能会接受这个答案,但如果有人知道一些合乎逻辑的原因,会给出一点。
  • @DavidMulder - 我也有兴趣了解钝器覆盖行为的基本原理。我怀疑这与在规范中组合 ToRawPrecision(有效数字)和 ToRawFixed(小数)操作的困难有关,但不确定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-08-19
  • 2010-11-22
  • 2021-01-27
  • 2020-06-19
  • 2021-02-12
  • 1970-01-01
  • 2021-05-26
相关资源
最近更新 更多