- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有一些数字要比较。它们代表通过不同空间的路径长度。
对我来说不幸的是,一些不精确导致了错误的比较。例如,在注意到错误的效果后,我发现我在进行这样的比较:
a = 384.527100541296
b = 384.52710054129614 // Note the trailing 14
为了我的目的,a 和 b 应该是相等的。
我注意到 guava 有一个用于 double 的 fuzzyCompare()
方法,它似乎做了我想做的,忽略了一些这种精度:
private static final double COMPARISON_PRECISION=1e-10;
private static final Comparator<Double> fuzzyCompare= new Comparator<Double>(){
public int compare(Double o1, Double o2) {
return DoubleMath.fuzzyCompare(o1, o2, COMPARISON_PRECISION);
}
};
public int compareTo(Object o) {
if (o instanceof Spam) {
Spam other = (Spam) (o);
return ComparisonChain.start()
.compare(this.getLength(),other.getLength(),fuzzyCompare)
//...
.result();
} else {
throw new ClassCastException();
}
}
关于模糊比较的警告并没有引起我的注意:
This is not a total ordering and is not suitable for use in Comparable.compareTo(T) implementations. In particular, it is not transitive
我的问题是,传递性的缺乏是一个真正的问题吗?如果是,它将如何呈现自己?我认为,如果比较确实被违反,它会抛出类似于 this question: Java error: Comparison method violates its general contract 的错误,并且即使针对我测试过的各种值,它也不会这样做。
或者也许因为 IllegalArgumentException
是一个运行时错误,我只是还没有遇到问题,因为只有一些不正当的值才会触发问题?
或者也许它现在做错了什么,只是非常微妙以至于我没有注意到它?
最佳答案
您的运算符不可传递。考虑 a = 0
, b = 0.6
, c = 1.2
公差为 1
. a==b
, b==c
但是a!=c
.解决方案是将您的值划分为类(例如通过舍入或截断)并使用 Double.compare()
以保持传递性。
首先让我们讨论在使用 fuzzyCompare(double, double, double)
时您的数据是否可传递:
虽然在大多数情况下您的数据将是可传递的,但可以生成不是可传递的样本。让我们采用以下值:
a = 384.52710054120
b = 384.52710054126
c = 384.52710054132
如您所见,使用我们的新指标,以下内容为真:a==b
, b==c
,但是a!=c
.可以看到,你违反了transitivity .
如果您的 Comparator
有问题吗?是不可传递的?
方法通过使用文档和/或注释来声明某些条件。 compare
方法 promise 该方法是可传递的。在传递性不重要的情况下,违反该 promise 可能没问题,但依赖于该 promise 的代码可能会被破坏。
如果传递性的 promise 被破坏,可能无法运行的代码示例是什么?
让我们创建一个场景,其中我们有 3 个类型为 Foo
的元素根据一些 Comparator
是不可传递的称为 fooComparator
.我们称它们为f1
, f2
和 f3
.
Comparator<Foo> fooComparator = new Comparator<Foo>(){
public int compare(Foo o1, Foo o2) {
// some non-transitive return value
}
};
由于它们不可传递,我们假设 f0
< f1
, f1
< f2
, f2
< f0
成立。如果你把它们放在一个列表中并尝试 sort()
会发生什么?他们?
List<Foo> foos = new LinkedList<>();
Collections.addAll(f1, f2, f3)
Collections.sort(foos, fooComparator);
如何解决问题
您可以通过将数据映射到另一个数据集并使用在该数据集上定义的传递运算符来创建传递运算符。让我们将实数映射到精度较低的实数。
考虑以下值:
a = 0.01; b = 0.05; c = 0.13; d = 0.19; e = 0.21
如果将它们截断到第二位 ( Math.truncate(x * 10)/10
) 并使用 Double.compare()
, 传递性被保留。
你可以看到我们已经将我们的值分为三类{a, b} < {c, d} < {e}
.肯定有一些重要的定理证明是这样的,但我不记得它的名字了..
关于java - 由于数值精度错误而违反 compareTo 传递契约的影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47018744/
Github:https://github.com/jjvang/PassIntentDemo 我一直在关注有关按 Intent 传递对象的教程:https://www.javacodegeeks.c
我有一个 View ,其中包含自动生成的 text 类型的 input 框。当我单击“通过电子邮件发送结果”按钮时,代码会将您带到 CalculatedResults Controller 中的 Em
我有一个基本的docker镜像,我将以此为基础构建自己的镜像。我没有基础镜像的Dockerfile。 基本上,基本镜像使用两个--env arg,一个接受其许可证,一个选择在容器中激活哪个框架。我可以
假设我想计算 2^n 的总和,n 范围从 0 到 100。我可以编写以下内容: seq { 0 .. 100 } |> Seq.sumBy ((**) 2I) 但是,这与 (*) 或其他运算符/函数不
我有这个网址: http://www.example.com/get_url.php?ID=100&Link=http://www.test.com/page.php?l=1&m=7 当我打印 $_G
我想将 window.URL.createObjectURL(file) 创建的地址传递给 dancer.js 但我得到 GET blob:http%3A//localhost/b847c5cd-aa
我想知道如何将 typedef 传递给函数。例如: typedef int box[3][3]; box empty, *board[3][3]; 我如何将 board 传递给函数?我
我正在将一些代码从我的 Controller 移动到核心数据应用程序中的模型。 我编写了一个方法,该方法为我定期发出的特定获取请求返回 NSManagedObjectID。 + (NSManagedO
为什么我不能将类型化数组传递到采用 any[] 的函数/构造函数中? typedArray = new MyType[ ... ]; items = new ko.observableArray(ty
我是一名新的 Web 开发人员,正在学习 html5 和 javascript。 我有一个带有“选项卡”的网页,可以使网页的某些部分消失并重新出现。 链接如下: HOME 和 JavaScript 函
我试图将对函数的引用作为参数传递 很难解释 我会写一些伪代码示例 (calling function) function(hello()); function(pass) { if this =
我在尝试调用我正在创建的 C# 项目中的函数时遇到以下错误: System.Runtime.InteropServices.COMException: Operation is not allowed
使用 ksh。尝试重用当前脚本而不修改它,基本上可以归结为如下内容: `expr 5 $1 $2` 如何将乘法命令 (*) 作为参数 $1 传递? 我首先尝试使用“*”,甚至是\*,但没有用。我尝试
我一直在研究“Play for Java”这本书,这本书非常棒。我对 Java 还是很陌生,但我一直在关注这些示例,我有点卡在第 3 章上了。可以在此处找到代码:Play for Java on Gi
我知道 Javascript 中的对象是通过引用复制/传递的。但是函数呢? 当我跳到一些令人困惑的地方时,我正在尝试这段代码。这是代码片段: x = function() { console.log(
我希望能够像这样传递参数: fn(a>=b) or fn(a!=b) 我在 DjangoORM 和 SQLAlchemy 中看到了这种行为,但我不知道如何实现它。 最佳答案 ORM 使用 specia
在我的 Angular 项目中,我最近将 rxjs 升级到版本 6。现在,来自 npm 的模块(在 node_modules 文件夹内)由于一些破坏性更改而失败(旧的进口不再有效)。我为我的代码调整了
这个问题在这里已经有了答案: The issue of * in Command line argument (6 个答案) 关闭 3 年前。 我正在编写一个关于反向波兰表示法的 C 程序,它通过命
$(document).ready(function() { function GetDeals() { alert($(this).attr("id")); } $('.filter
下面是一个例子: 复制代码 代码如下: use strict; #这里是两个数组 my @i =('1','2','3'); my @j =('a','b','c'); &n
我是一名优秀的程序员,十分优秀!