比较两个double或两个float值的最有效方法是什么?
简单地这样做是不正确的:
bool CompareDoubles1 (double A, double B)
{
return A == B;
}
Run Code Online (Sandbox Code Playgroud)
但是像这样:
bool CompareDoubles2 (double A, double B)
{
diff = A - B;
return (diff < EPSILON) && (-diff < EPSILON);
}
Run Code Online (Sandbox Code Playgroud)
似乎浪费处理.
有谁知道更聪明的浮动比较器?
到目前为止,我已经看到很多关于浮点数相等的帖子.对于"我们应该如何决定x和y是否相等?"这样的问题的标准答案.是
abs(x - y) < epsilon
Run Code Online (Sandbox Code Playgroud)
其中epsilon是一个固定的小常数.这是因为"操作数"x和y通常是涉及舍入误差的某些计算的结果,因此标准相等运算符==不是我们的意思,我们应该问的是x和y是否接近,不相等.
现在,我觉得如果x与y"几乎相等",那么x*10 ^ 20也应该与y*10 ^ 20"几乎相等",因为相对误差应该是相同的(但是"相对的" "到底是什么?" 但是对于这些大数字,上述测试将失败,即该解决方案不会"扩展".
你会如何处理这个问题?我们应该重新调整数字还是重新调整epsilon?怎么样?(或者我的直觉是错的吗?)
这是一个相关的问题,但我不喜欢它接受的答案,因为reinterpret_cast对我来说似乎有点棘手,我不明白发生了什么.请尝试提供简单的测试.
我有一个有float田地的课.例如:
public class MultipleFields {
final int count;
final float floatValue;
public MultipleFields(int count, float floatValue) {
this.count = count;
this.floatValue = floatValue;
}
}
Run Code Online (Sandbox Code Playgroud)
我需要能够按值比较实例.现在我该如何正确实施 equals&hashCode?
通常的方式来实现equals,并hashCode是只考虑各个领域.例如,Eclipse将生成以下内容equals:
public boolean equals(Object obj) {
// irrelevant type checks removed
....
MultipleFields other = (MultipleFields) obj;
if (count != other.count)
return false;
if (Float.floatToIntBits(floatValue) != Float.floatToIntBits(other.floatValue))
return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
(和类似的hashCode,基本上计算count* 31 + Float.floatToIntBits(floatValue)).
这个问题是我的FP值受到舍入错误的影响(它们可能来自用户输入,来自数据库等).所以我需要一个"宽容"的比较.
常见的解决方案是使用epsilon值进行比较(参见 …
我只能假设这是一个错误.第一个断言在第二个失败时通过:
double sum_1 = 4.0 + 6.3;
assert(sum_1 == 4.0 + 6.3);
double t1 = 4.0, t2 = 6.3;
double sum_2 = t1 + t2;
assert(sum_2 == t1 + t2);
Run Code Online (Sandbox Code Playgroud)
如果不是错误,为什么?
如果我比较两个浮点数,是否存在a>=b不等于b<=a和!(a<b),或者哪里a==b不等于b==a和!(a!=b)?
换句话说:比较总是"对称的",这样我可以通过交换操作数和镜像操作符来获得相同的结果吗?它们总是"可否定的",这样否定运算符(例如>to <=)等同于对结果应用逻辑NOT(!)?
comparison ×2
algorithm ×1
c++ ×1
equals ×1
gcc ×1
hashcode ×1
java ×1
math ×1
optimization ×1
precision ×1