【问题标题】:Testing for "double" equality in javascript在 javascript 中测试“双重”相等性
【发布时间】:2014-01-25 20:21:32
【问题描述】:

我已将 Clipper library 的实验性 C#“浮动”版本翻译为 javascript。在最新的沙盒版本中,有一个函数IsAlmostEqual 似乎很难翻译。由于数值稳定性问题,无法使用 == 运算符比较双重相等,因此需要此函数来处理这些问题。

-9223372036854775808 - aInt-9223372036854775808 - bInt 很容易使用例如计算BigInteger 库,但BitConverter.DoubleToInt64Bits 更难。

知道如何将IsAlmostEqual 函数翻译成javascript吗?或者具体如何实现BitConverter.DoubleToInt64Bits到javascript?

private static bool IsAlmostEqual(double A, double B)
{
  //http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm

  Int64 aInt = BitConverter.DoubleToInt64Bits(A);
  if (aInt < 0) aInt = unchecked(-9223372036854775808 - aInt);
  Int64 bInt = BitConverter.DoubleToInt64Bits(B);
  if (bInt < 0) bInt = unchecked(-9223372036854775808 - bInt);
  return (Math.Abs(aInt - bInt) <= 10000000000);
}

数值稳定性和鲁棒性:
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
http://www.mpi-inf.mpg.de/~kettner/pub/nonrobust_cgta_06.pdf
http://cpc.cs.qub.ac.uk/MRSN/higham.pdf
http://www.2ality.com/2012/04/number-encoding.html

【问题讨论】:

    标签: c# javascript numerical-stability


    【解决方案1】:

    我最终使用完全不同的函数来测试来自here 的双重相等性。原始函数使用 double 的有符号 int64 表示,如果不使用缓慢而复杂的按位运算或使用一些 BigDecimal 库,这在 Javascript 中是不可能的。它使用相对误差和绝对误差的组合。

    var IsAlmostEqual = 函数(a,b) { 如果 (a == b) 返回真; var diff = Math.abs(a - b); if (diff

    根据我的测试,它似乎可靠。请在jsbin进行测试。

    编辑:我更新了上面的代码。现在它在所有 83 个测试用例中产生与 ULP technique 相同的结果(使用 maxUpls 10,000)。由于 Javascript 缺少 64 位整数,ULP 技术比上述 EPSILON 技术慢 8-20 倍。

    【讨论】:

    • 是否可以有两个数字的差小于Number.MIN_VALUE
    • cygnus-software.com/papers/comparingfloats/comparingfloats.htm 中说“此备份 maxAbsoluteError 的典型值将非常小 - FLT_MAX 或更小,具体取决于平台是否支持次规范。”我假设它应该是 FLT_MIN,而不是 FLT_MAX。我不认为,Javascript 支持次规范,所以我认为答案是否定的。
    • 请忽略我上面的评论。 FLT_MIN 为 5e-324。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 表示小于此值的值将转换为 0。我不能再说是或否了。而且我不确定 Number.MIN_VALUE 是否是 maxAbsoluteError 的正确值。
    • 我会说Number.EPSILON,但如果您的指数是负数,它就不适合使用。
    • Number.EPSILON 好像是 2.220446049250313e-16,所以比较合乎逻辑。为什么负指数不合适?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    相关资源
    最近更新 更多