【问题标题】:Why is Node.js automatically rounding my floating point?为什么 Node.js 会自动舍入我的浮点数?
【发布时间】:2021-05-16 03:39:20
【问题描述】:

我正在尝试编写一个函数,该函数将使用来自here 的答案作为参考来获取浮点文字中小数点后的小数位数。

虽然在浏览器控制台中尝试这似乎可以正常工作,但在 Node.js 环境中运行测试用例时,精度仅被截断至 14 位。

let data = 123.834756380650877834678
console.log(data) // 123.83475638065088

该函数返回 14 作为答案。

为什么会在静止时进行舍入?这是默认行为吗?

【问题讨论】:

  • 基本上,您不能期望任何特定的浮点数以任何一种特定的方式“成为”。该值将与您在文字中所写的值接近,但永远不能保证它会完全在您的文字中所写。如果您需要该数字准确无误,或者您想对其中的小数位数做出任何明确的断言,您不想使用浮点数。
  • 这是一个实际的例子吗?对我来说,打印的是“123.83475638065087”,最后一位不同。如果你的 JavaScript 实现打印“123.83475638065088”,它可能有缺陷。当 123.834756380650877834678 转换为 JavaScript 用于浮点的格式 IEEE-754 binary64 时,确切的结果是 123.834756380650873097692965529859066009521484375,并以默认格式打印应生成“123.8347563806”。 (默认格式只打印足够的数字来唯一区分表示的值。)
  • Re “虽然在浏览器控制台中尝试这似乎工作正常”:尝试计算“123.834756380650877834678”的小数点后的位数不应该在 JavaScript 实现中工作,因为它已经已转换为内部浮点格式。请显示示例代码、输入数据和输出。
  • "精度只截断到 14 位" --> 123.83475638065088 有 17 位有效数字。对于 FP 数字,计算的是前导有效数字,而不是小数点后的数字。

标签: javascript node.js floating-point precision


【解决方案1】:

这是 JavaScript 的默认行为。我认为它在 node.js 中是相同的。

在 JS 中最大小数位数为 17。

更多详情请查看here

【讨论】:

  • 您指向的页面不正确;十进制位数的最大位数不是 17。每个 IEEE-754 binary64 值除 NaNs 外,精确表示一个数字,其中一些以十进制表示时超过 17 位,例如 123.834756380650873097692965529859066009521484375。
【解决方案2】:

JavaScript(可能是 Node.js)中使用的浮点格式是 IEEE-754 binary64。在源代码中使用123.834756380650877834678时,将其转换为最接近的可表示值,即123.834756380650873097692965529859066009521484375。

当它被转换为具有默认格式的字符串时,JavaScript uses just enough digits to uniquely distinguish the value。对于 123.834756380650873097692965529859066009521484375,这应该产生“123.83475638065087”。如果您收到“123.83475638065088”,最后一位不同,那么您使用的软件不符合 JavaScript 规范(ECMAScript)。

无论如何,binary64 格式的精度不足以保留原始数字“123.834756380650877834678”小数点后有 21 位的信息。

您链接到的代码也不会也无法计算原始数字中的位数。它计算唯一区分转换为 binary64 后表示的值所需的位数。对于小数点后没有尾随零的足够短的数字,这与原始数字中小数点后的位数相同。对于其他人来说,可能不是。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 2010-12-11
    • 1970-01-01
    相关资源
    最近更新 更多