c# - 在 javascript 中测试 "double"是否相等

标签 c# javascript numerical-stability

我已经翻译了 Clipper library 的实验性 C#“ float ”版本到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

最佳答案

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

var IsAlmostEqual = function(a, b)
{
  if (a == b) return true;
  var diff = Math.abs(a - b);
  if (diff < 4.94065645841247E-320) return true;
  a = Math.abs(a);
  b = Math.abs(b);
  var smallest = (b < a) ? b : a;
  return diff < smallest * 1e-12;
}

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

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

关于c# - 在 javascript 中测试 "double"是否相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20935282/

相关文章:

javascript - angular2中templatURL中的动态模板

c - gcc 编译器是否尊重我的代码中编写的表达式形式?

c# - 循环 SQL 查询的正确方法?

c# - 如何使用 C# 有效地合并巨大的文件

c# - 寻找最小精度

tensorflow - LSTM 'recurrent_dropout' 和 'relu' 产生 NaN

python - softmax 的 Tensorflow 问题

c# - 将 int 值分配给自定义枚举属性

javascript - angularjs 多重解析与 loadsequence 和 auth 权限

javascript - 为什么 SVG sprite XML 文件在服务器上显示为文本字符串,而不是在本地显示?