对于测试和QUOT;双"在JavaScript平等 [英] Testing for "double" equality in javascript
问题描述
我翻译了实验C#浮动克利伯库到JavaScript版本。在最新版本的沙盒有一个功能 IsAlmostEqual 这似乎是很难翻译。双人平等不能使用比较==操作符由于数值稳定性的问题,所以需要这个函数来处理这些问题。
I have translated the experimental C# "float" version of Clipper library to javascript. In the newest sandbox version there is a function IsAlmostEqual which seems to be hard to translate. Double equality cannot be compared using == operator due to numerical stability issues, so this function is needed to handle those issues.
-9223372036854775808 - 是不是
和 -9223372036854775808 - 宾特
很容易使用例如计算BigInteger的库,但 BitConverter.DoubleToInt64Bits
是更难了。
-9223372036854775808 - aInt
and -9223372036854775808 - bInt
are easy to calculate using e.g. BigInteger library, but BitConverter.DoubleToInt64Bits
is harder.
不知道如何翻译 IsAlmostEqual
函数的JavaScript?或具体如何实施 BitConverter.DoubleToInt64Bits
来的JavaScript?
Any idea how to translate IsAlmostEqual
function to javascript? Or specifically how to implement BitConverter.DoubleToInt64Bits
to 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 /酒吧/ nonrobust_cgta_06.pdf 结果
的 http://cpc.cs.qub.ac.uk/MRSN/higham.pdf 结果
的 http://www.2ality.com/2012/04/number-encoding.html
推荐答案
最后我用完全不同的功能,测试从的此处。原函数采用签名的int64双这不是在Javascript可能表示不使用缓慢和复杂的位操作或使用一些BigDecimal的库。它使用相对和绝对误差的组合。
I ended up using completely different function to test double equality from here. The original function uses signed int64 representation of double which is not possible in Javascript without using slow and complex bitwise operations or using some BigDecimal library. It uses a combination of relative and absolute error.
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 。
编辑:我更新了上面的代码。现在,它产生相同的结果,在所有83测试用例(使用maxUpls 10,000) ULP技术。 ULP技术是8倍,20倍比上面EPSILON技术是因为JavaScript缺少64位整数慢。
I updated the code above. Now it produces the same result as with ULP technique in all 83 test cases (using maxUpls 10,000). ULP technique is 8x-20x slower than above EPSILON technique due to Javascript lack of 64 bit integers.
这篇关于对于测试和QUOT;双"在JavaScript平等的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!