编程语言
首页 > 编程语言> > 如何确定Javascript Number是否在单精度范围内?

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

作者:互联网

根据ECMAScript specification,Javascript编号值对应于双精度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;
}

从本质上讲,我正在做的是:

>将DataView缠绕在4字节ArrayBuffer左右.
>将Number值存储为缓冲区中的32位浮点数.
>将转换后的数字从缓冲区中取出.
>计算原始值和转换值之间的相对误差.
>使用Number.EPSILON检查相对误差是否小于浮点数的machine epsilon.

几条评论:

>我将此作为Chrome扩展程序的一部分实现,浏览器兼容性并不是真正的问题.
>是的,我读过What Every Computer Scientist Should Know About Floating-Point Arithmetic.我的眼睛还没有止血.

以上逻辑是否适用于我想要实现的目标?这有点矫枉过正吗?有没有更惯用,优雅或高效的方式来做到这一点?

更新

我在此期间发现上述方法不正确.对于各种值,例如1.001,3.14159等,它将失败.另一方面,对于32位浮点(2-23),将epsilon值更改为机器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,floating-point,ieee-754,floating-point-conversion,webidl
来源: https://codeday.me/bug/20190628/1315200.html