- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我已经成功地编写了一个基于 Ulps 的函数来比较两个 double 是否相等。根据this page ,可以使用绝对和相对 epsilon 的组合或使用整数 (Ulps) 进行比较。
我制作了基于 epsilon 和基于 Ulps 的函数。这是基于 epsilon 的函数:
var IsAlmostEqual_Epsilon = 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;}
And this is the Ulps based (DoubleToInt64Bits
, subtract
, negate
and lessthan
functions are in the below mentioned JSBIN):
var IsAlmostEqual_Ulps = function(A, B){ if (A==B) return true; DoubleToInt64Bits(A, aInt); if(aInt.hi < 0) aInt = subtract(Int64_MinValue, aInt); DoubleToInt64Bits(B, bInt); if(bInt.hi < 0) bInt = subtract(Int64_MinValue, bInt); var sub = subtract(aInt, bInt); if (sub.hi < 0) sub = negate(sub); if (lessthan(sub, maxUlps)) return true; return false;}
According to Bruce Dawson the Ulps based is preferred. IsAlmostEqual_Ulps
is working ok according to test base of 83 cases, but the function is pretty slow. It takes about 700-900 ms to complete the test base (JSBIN) when executed as a standalone html (outside JSBIN). Epsilon based IsAlmostEqual_Epsilon
takes only about 100 ms.
Is there anything that can be done to speedup IsAlmostEqual_Ulps
function? You can propose also a completely different solution or some fixings to my code.
I have tested already the inlining everything, but it cuts the time only about 5-10%. I'm hunting something like 50-80% improvement in execution time. 100-500% improvement would be fine, but it may be only a dream.
right_answers
in the JSBIN code are got using C# IsAlmostEqual
function (see at the top of JSBIN code). Both above functions give the same results in all 83 cases.
EDIT:
C++ version from here:
bool IsAlmostEqual(double A, double B)
{
//http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
long long aInt = reinterpret_cast<long long&>(A);
if (aInt < 0) aInt = -9223372036854775808LL - aInt;
long long bInt = reinterpret_cast<long long&>(B);
if (bInt < 0) bInt = -9223372036854775808LL - bInt;
return (std::abs(aInt - bInt) <= 10000);
}
最佳答案
有一种方法肯定会更快(目前速度是 native 代码速度的 1.5 倍),那就是使用 asm.js ,一个高度可优化的 Javascript 子集。
这是 unreal gaming engine在其上运行,以了解性能类型(需要一点加载但运行非常流畅,使用 firefox 或 chrome)。
它的工作方式是您使用静态类型语言编写代码:C 或 C++。然后编译成LLVM C++虚拟机的字节码。然后使用 emscripten编译器生成 asm.js Javascript 代码。
如果浏览器不检测和优化 asm.js,它会将其作为 Javascript 运行。如果浏览器(如最新版本的 Chrome/Firefox)检测到 asm.js,您将获得接近原生的性能。
检查 blog post John Resig(jQuery 的创造者)关于它的。如今,您无法获得比浏览器更快的速度,而且速度还在不断提高(请参阅 Mozilla 团队博客文章 here)。
关于javascript - 使用 ULP 比较 double (最后一位的单位),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21340372/
我需要 ulp对于给定的 double 值,但由于我正在为代号 ONE 开发,因此未提供 ulp(double)。有谁知道用 Java 计算 ulp 的有效算法?代号 ONE 仅提供 Math 类(j
我有两个字符串形式的十进制数字,它们的舍入略有不同。我想要一个函数,如果它们仅相差 1 ulp(即仅最后一位数字相差 1),则将它们视为“相等”。 目前我能想到的最易读的形式是这样的: private
我阅读了网络上的一些资源,我了解到在比较 float 时没有单一值或通用参数。我读过 from here几个回复,我从谷歌测试中找到了比较 float 的代码。我想更好地理解 ULP 的含义及其值(v
我有一个关于浮点精度的问题。据我了解,ULP 是给定规范中两个连续的离散有限数之间的距离。或如名称所述位于最不重要位置的单位。无论如何,我在 java.lang.Math 中的 sinh 的 Java
谁能解释一下最低精度的 ULP 单位?我有如下定义,但还是不清楚 “表示分数时的误差大小与存储的数字大小成正比。ULP 或最小精度单位定义了存储数字时可以获得的最大误差。存储的数字越大,ULP 越大”
.NET 是否有内置方法来计算 ULP给定的 double 型或浮点型? 如果没有,最有效的方法是什么? 最佳答案 看起来这个功能很简单;这是基于 vulkanino 链接问题的接受答案中的伪代码:
我试图避免使用 epsilon 比较来比较浮点类型。尽管 this article,但我能想到的最佳解决方案使用了 ULP 的差异(单位在最后一位)使用整数表示有一个更好的解决方案(/// 表示我自己
我无法在网上找到任何不假设我知道事情的信息。我想知道是否有人知道我可以研究哪些好的资源来帮助我了解这个函数的具体功能? 根据我收集的信息,我很确定这是错误的,或者至少不完全正确,是否给定一个浮点,它确
我已经成功地编写了一个基于 Ulps 的函数来比较两个 double 是否相等。根据this page ,可以使用绝对和相对 epsilon 的组合或使用整数 (Ulps) 进行比较。 我制作了基于
.NET 是否有内置方法来计算 ULP给定的 double 或 float ? 如果不是,最有效的方法是什么? 最佳答案 看起来这个功能很简单;这是基于 vulkanino 链接的问题的已接受答案中的
如何判断两个 float 之差是否最多为1 ULP? 类似于下面的代码,它(忽略符号和指数,并且)提取尾数的二进制,但稍微不那么糟糕: a = int(.hex().lstrip('-').lstri
java.lang.Math 文档说明了很多函数,例如 Math.pow : The computed result must be within 1 ulp of the exact result.
我正在尝试更详细地了解 Java 中的浮点运算。如果我正确阅读了文档,则以下内容适用于任何给定的双 x: x - Math.ulp(x) == Math.nextAfter(x, Double.NEG
我正在使用 CCS8,使用结构并初始化变量,如下面的代码所示。 CCS 在第 15、16 和 17 行给我的评论如下: #1546-D:(ULP 15.1)检测到连续的位域分配。建议改用位掩码 我真的
我是高性能计算 (HPC) 方面的新手,但我将有一个 HPC 项目,因此我需要一些帮助来解决一些基本问题。 应用场景很简单:通过InfiniBand(IB)网络连接几台服务器,一台服务器做Master
Math.nextUp(arg) 始终与 arg + Math.ulp(arg) 相同,还是我遗漏了什么? System.out.println( 0.5 + Math.ulp(0.5));
我有一组基于通过 json 数据包接收到的数字的浮点计算。在计算结束时,我要求其中一个数字 >= -0.5。我发现有时我有一个未通过测试的值,因为它是一个 ULP低于阈值。无论如何要写一个conste
我是一名优秀的程序员,十分优秀!