繁体   English   中英

格式化浮点值时,JavaScript 如何确定要生成的位数?

[英]How does JavaScript determine the number of digits to produce when formatting floating-point values?

在 JavaScript 中,大家都知道著名的计算: 0.1 + 0.2 = 0.30000000000000004 但是为什么 JavaScript 打印这个值而不是打印更准确和精确的0.300000000000000044408920985006呢?

Number值转换为十进制数字时,JavaScript 的默认规则是使用足够的数字来区分Number值。 (您可以使用toPrecision方法请求更多或更少的数字。)

JavaScript 使用 IEEE-754 基本 64 位二进制浮点数作为其Number类型。 使用 IEEE-754, .1 + .2的结果正好是 0.3000000000000000444089209850062616169452667236328125。 这源于:

  • 将“.1”转换为可在Number类型中表示的最接近的值。
  • 将“.2”转换为可在Number类型中表示的最接近的值。
  • 将上述两个值相加,并将结果四舍五入到Number类型中可表示的最接近的值。

格式化此Number值以供显示时,“0.30000000000000004”的有效数字刚好足以唯一区分该值。 要看到这一点,请观察相邻值是:

  • 0.299999999999999988897769753748434595763683319091796875 ,
  • 0.3000000000000000444089209850062616169452667236328125 ,和
  • 0.300000000000000099920072216264088638126850128173828125 .

如果转换为十进制数字只产生“0.3000000000000000”,这将是更接近0.299999999999999988897769753748434595763683319091796875比0.3000000000000000444089209850062616169452667236328125。 因此,需要另一个数字。 当我们有那个数字“0.30000000000000004”时,结果比它的任何一个邻居更接近 0.3000000000000000444089209850062616169452667236328125。 因此,“0.30000000000000004”是最短的十进制数(忽略领先的“0”,这是有出于美观的目的),该唯一区分要可能Number值的原始值。

此规则来自 ECMAScript 2017 语言规范第 7.1.12.1 条中的第 5 步,这是将Numberm转换为ToString操作的十进制数字的步骤之一:

否则,让nks是整数,使得k ≥ 1, 10 k ‐1s < 10 ks × 10 nk 的数值为m ,并且k尽可能小。

这里的措辞有点不准确。 我花了一段时间才弄清楚,“ s × 10 n - k的数值”,标准是指将数学值s × 10 n - k转换为Number类型的结果的Number值(与通常的四舍五入)。 在这个描述中, k是将使用的有效数字的数量,这一步告诉我们最小化k ,所以它说使用最小数量的数字,这样我们产生的数字将在转换回Number键入,产生原始数m

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM