Hello,
IIRC, general approach to consider a and b being equal is based
on how close a to b is (a should be within epsilon).
We compare double values via operator== which may be incorrect
for floating point numbers.
For example, this simple program
double a,b;
a = 5.0/3.0;
b = 1.666666666666667;
printf("Is %f equals to %f ?\n", a, b);
if (a == b)
printf("Cool, %.24f == %.24f\n", a, b);
else {
printf("Not cool, %.23f != %.23f\n",a ,b);
if (fabs(a - b) <= std::numeric_limits<double>::epsilon())
printf("Yet a-b is less than epsilon\n");
}
produces on my laptop:
Is 1.666667 equals to 1.666667 ?
Not cool, 1.66666666666666674068153 != 1.66666666666666696272614
Yet a-b is less than epsilon
Though, on my laptop operator== compiles to ucomisd
[..]
movabs $0x3ffaaaaaaaaaaaab,%rax
mov %rax,-0x8(%rbp)
movabs $0x3ffaaaaaaaaaaaac,%rax
mov %rax,-0x10(%rbp)
movsd -0x10(%rbp),%xmm1
movsd -0x8(%rbp),%xmm0
mov $0x400fe8,%edi
mov $0x2,%eax
callq 0x4008d8 <pri...@plt>
movsd -0x8(%rbp),%xmm0
ucomisd -0x10(%rbp),%xmm0
jp 0x400cf5 <main+119>
[..]
I'm not sure if operator== will produce `stable results' on different gcc/CPU.
/*For example, Core i3 (which doesn't support SSE2 according to specs
http://ark.intel.com/Product.aspx?id=46472)*/
Arjan, what do you think about using ::epsilon comparison?
Usage example:
double iW, jW;
[..]
if (equals(iW, jW)) {
[..]
---
numeric.h | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/numeric.h b/numeric.h
new file mode 100644
index 0000000..9100359
--- /dev/null
+++ b/numeric.h
@@ -0,0 +1,13 @@
+#ifndef _NUMERIC_H_
+#define _NUMERIC_H_
+
+#include <math.h>
+#include <limits>
+
+inline int equals(double a, double b)
+{
+ return fabs(a - b) <= std::numeric_limits<double>::epsilon();
+}
+
+#endif //_NUMERIC_H_
+
_______________________________________________
Discuss mailing list
[email protected]
http://lists.lesswatts.org/listinfo/discuss