javascript - 如何确定 Javascript Number 是否在单精度范围内?

标签 javascript floating-point ieee-754 floating-point-conversion webidl

根据ECMAScript specification , Javascript 数字值对应一个 double 64 位二进制格式 IEEE 754 值。

对于我目前正在研究的 WebIDL 验证器,我需要能够确定给定的数值是否可以转换为 WebIDL float。类型,即它是否可以表示为有限单精度 32 位 IEEE 754 值。

我目前已经确定了以下方法:

validate: function(value) {
    if (typeof value !== 'number' || !Number.isFinite(value)) {
        return false;
    }

    if (value === 0) {
        return true;
    }

    var view = new DataView(new ArrayBuffer(4));

    view.setFloat32(0, value);

    var converted = view.getFloat32(0);
    var relativeError = Math.abs(value - converted) / value;

    return relativeError < Number.EPSILON;
}

本质上,我正在做的是:

  1. 包装一个DataView大约 4 个字节 ArrayBuffer .
  2. Number 值作为 32 位 float 存储在缓冲区中。
  3. 从缓冲区中取出转换后的数字。
  4. 计算原始值与转换后值的相对误差。
  5. 检查相对误差是否小于machine epsilon对于 float ,使用 Number.EPSILON .

一些评论:

以上逻辑是否符合我要实现的目标?是不是矫枉过正?是否有更惯用、更优雅或更高效的方式来做到这一点?

更新

同时我发现上述方法是不正确的。对于范围广泛的值,例如 1.0013.14159 等,它将失败。另一方面,将 epsilon 值更改为 32 位 float (2−23) 的机器 epsilon 过于宽松,允许像 16777217 这样的值。

仍在寻找一个好的解决方案,但目前正在使用下面的函数,该函数仅检查整数上限和下限(224 和 -(224)) .

validate: function(value) {
    return typeof value === 'number' && Number.isFinite(value)
            && value >= -16777216 && value <= 16777216;
}

最佳答案

当您使用 ECMAScript 6 时,您可以使用 Math.fround检查它是否是单精度数:

function isfloat32(x) {
  return isNaN(x) || x == Math.fround(x);
}

更新:我错过了关于 WebIDL float 的部分是有限的(即不是 Inf 或 NaN)。在这种情况下,

function isfloat32(x) {
  return isFinite(x) && x == Math.fround(x);
}

关于javascript - 如何确定 Javascript Number 是否在单精度范围内?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32448199/

相关文章:

javascript - 上传文档时突出显示最新文件,并且滚动条应根据文档移动

javascript - YUI 中限制拖动模块

javascript - Edge Animate 自定义百分比预加载器

math - OpenEdge abl truncate( log(4)/log(2) ) 应为 2 返回 1

haskell - Haskell 中 float 的十六进制表示

javascript - 将 javascript 数字转换为 float (单精度 IEEE-754)并接收整数位

javascript - IEEE 754 中 Infinity 的用例是什么

javascript - 如何通过http正确发送二进制文件并使用javascript下载它?

c - printf() 中大 float 的奇怪行为并分配给一个 int

PHP Printf 作为浮点精度