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

时间:2018-03-20 12:39:25

标签: javascript floating-point precision

在JavaScript中,每个人都知道着名的计算:GO。但是,为什么JavaScript打印此值而不是打印更准确和精确的conn, err := net.Dial("tcp", "192.168.137.10:502") if err != nil { return nil, err } else { return conn, nil }

1 个答案:

答案 0 :(得分:6)

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,这是将Number m 转换为十进制数字的步骤之一ToString操作:

  

否则,让 n k s 为整数,使 k ≥1,10< sup> k -1 ≤ s &lt; 10 k s的数值×10 n - k m k 尽可能小。

这里的措词有点不精确。通过“ s ×10 n - k 的数值,花了一段时间才弄明白” ,标准意味着Number值是转换数学值 s ×10 n - k 的结果Number类型(通常舍入)。在本说明书中, k 是将要使用的有效位数,此步骤告诉我们最小化 k ,因此它表示使用最小位数这样我们生成的数字在转换回Number类型时会生成原始数字 m