Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 4

Qt-interest Archive, July 2007
QCOMPARE and double


Message 1 in thread

Are there any particular caveats for using doubles with QCOMPARE ? I could not 
find any references in the list archives or in the docs and I don't have Qt 
sources at hand, but the following happens to me regularly:

QDEBUG : test::drotg() "Automatically Tuned Linear Algebra Subprograms 
(ATLAS)"  implements drotg
FAIL!  : test::drotg() Compared doubles are not the same (fuzzy compare)
   Actual (a): 0.223607
   Expected (0.223607): 0.223607
   Loc: [test.cpp(133)]

The code is as follows:

double a = 0.1;
double b = 0.2;
double c = 0.3;
double s = 0.4;
b1i->qblas_rotg(&a,  &b, &c, &s);
QCOMPARE(a, 0.223607);
QCOMPARE(b, 2.236068);
QCOMPARE(c, 0.447214);
QCOMPARE(s, 0.894427);

With floats it works ok (with 0.223607f of course), but with doubles it fails, 
likely because of some precision related problems. Is there a way to define 
precision/epsilon (and report it) in QCOMPARE for real variable types ?

--
 [ signature omitted ] 

Message 2 in thread

> With floats it works ok (with 0.223607f of course), but with doublesit 
fails, 
> likely because of some precision related problems. Is there a way to 
define 
> precision/epsilon (and report it) in QCOMPARE for real variable types ?

A rule of thumb tells us to never compare floating point numbers for 
equality! Since QCOMPARE does an equality test, I fear you would have to 
implement some epsilon-function yourself :-(

Regards,
Malte

--
 [ signature omitted ] 

Message 3 in thread

On Tuesday 17 July 2007 11:08, Malte Witt wrote:
> A rule of thumb tells us to never compare floating point numbers for
> equality! Since QCOMPARE does an equality test, I fear you would have to
> implement some epsilon-function yourself :-(

Yes, I'm very aware of the generic real number comparison problem, but 
QCOMPARE apparently handles this to an extent. You can see for example that 
it has explicit float/double QCOMPARE functions, does not allow mixing of the 
two (rightly so) and upon error it says 'Compared floats are not the same 
(fuzzy compare)'. So it does realize it's a float and does a fuzzy compare, 
it's just that it's not clear to me from the docs what this fuzzy compare 
means mathematically and if I can somehow influence the extent of 
the 'fuzziness'.

--
 [ signature omitted ] 

Message 4 in thread

On Jul 17, 2007, at 4:58 AM, Attila Csipa wrote:

> Are there any particular caveats for using doubles with QCOMPARE ?  
> I could not
> find any references in the list archives or in the docs and I don't  
> have Qt
> sources at hand, but the following happens to me regularly:
>
I haven't looked at the source since Qt 4.1, but back then the level  
of comparison was hard coded directly in the macro ( epsilon was  
something like 0.000000001 ).  I put in a task tracker request to be  
able to specify this epsilon level, but haven't heard any comments on  
it since I requested it.

Caleb

--
 [ signature omitted ] 

Message 5 in thread

On Tuesday 17 July 2007 20:58, Caleb Tennis wrote:
> On Jul 17, 2007, at 4:58 AM, Attila Csipa wrote:
> > Are there any particular caveats for using doubles with QCOMPARE ?
> > I could not
> > find any references in the list archives or in the docs and I don't
> > have Qt
> > sources at hand, but the following happens to me regularly:
>
> I haven't looked at the source since Qt 4.1, but back then the level
> of comparison was hard coded directly in the macro ( epsilon was
> something like 0.000000001 ).  I put in a task tracker request to be
> able to specify this epsilon level, but haven't heard any comments on
> it since I requested it.
Looks like no change....

template <>
bool QTest::qCompare<float>(float const &t1, float const &t2, const char *actual, const char *expected,
                    const char *file, int line)
{
    return (qAbs(t1 - t2) < 0.00001f)
            ? compare_helper(true, "COMPARE()", file, line)
            : compare_helper(false, "Compared floats are not the same (fuzzy compare)",
                             toString(t1), toString(t2), actual, expected, file, line);
}


template <>
bool QTest::qCompare<double>(double const &t1, double const &t2, const char *actual, const char *expected,
                    const char *file, int line)
{
    return (qAbs(t1 - t2) < 0.000000000001)
            ? compare_helper(true, "COMPARE()", file, line)
            : compare_helper(false, "Compared doubles are not the same (fuzzy compare)",
                             toString(t1), toString(t2), actual, expected, file, line);
}


Brad

Attachment:

Attachment: pgpHtqjCtW4zh.pgp
Description: PGP signature


Message 6 in thread

On Tuesday 17 July 2007 14:02, Brad Hards wrote:
> Looks like no change....

There is a change in the tracker which has already been applied to qt-copy in 
the KDE branch of qt4 ( http://websvn.kde.org/?view=rev&revision=600291 ), 
but that solution still does not work for numbers close to 0 (and still has 
hardcoded epsilon values which is not all that good either).

--
 [ signature omitted ] 

Message 7 in thread

On Tuesday 17 July 2007 22:35, Attila Csipa wrote:
> On Tuesday 17 July 2007 14:02, Brad Hards wrote:
> > Looks like no change....
>
> There is a change in the tracker which has already been applied to qt-copy
> in the KDE branch of qt4 ( http://websvn.kde.org/?view=rev&revision=600291
> ), but that solution still does not work for numbers close to 0 (and still
> has hardcoded epsilon values which is not all that good either).
That change appears not to be in qt-copy any more. I actually pasted the code 
from my local qt-copy, not from an official Qt4.

Brad

Attachment:

Attachment: pgpuH6RXXa5g5.pgp
Description: PGP signature


Message 8 in thread

On Wednesday 18 July 2007 13:13, Brad Hards wrote:
> That change appears not to be in qt-copy any more. I actually pasted the
> code from my local qt-copy, not from an official Qt4.

The trolls are watching, the tracker changed this morning :)

Task 137260 - QCOMPARE() doesn't perform properly when comparing very small 
floating numbers.
2007-07-18 10:50 - Version for fix set to '4.4.0 (Next Minor Release)'
2007-07-18 10:51 - Priority changed to '2'

--
 [ signature omitted ] 

Message 9 in thread

On Tuesday 17 July 2007 14:02:49 Brad Hards wrote:
> > I haven't looked at the source since Qt 4.1, but back then the level
> > of comparison was hard coded directly in the macro ( epsilon was
> > something like 0.000000001 ).  I put in a task tracker request to be

> Looks like no change....


> template <>
> bool QTest::qCompare<double>(double const &t1, double const &t2, const char
> *actual, const char *expected, const char *file, int line)
> {
>     return (qAbs(t1 - t2) < 0.000000000001)
>             ? compare_helper(true, "COMPARE()", file, line)
>
>             : compare_helper(false, "Compared doubles are not the same
>             : (fuzzy compare)",
>
>                              toString(t1), toString(t2), actual, expected,
> file, line); }

I also found an improvement submitted to qt-bugs ( 
http://trolltech.com/developer/task-tracker/index_html?id=137260&method=entry ) 
which takes into account the absolute values of the operands, but that is not 
perfect either (it will perform poorly on numbers around 0). Depending on 
public interest I'm inclined to write a patch to QCOMPARE wrt to the IEEE754 
recommendation or ditch QCOMPARE altogether for floats and doubles so I don't 
need to recompile qt with every release. So, if you are interested in more 
precise Qt float/double routines, speak up !




--
 [ signature omitted ] 

Message 10 in thread

On 7/17/07, Attila Csipa <plists@xxxxxxxxxxxxxxxxx> wrote:
> need to recompile qt with every release. So, if you are interested in more
> precise Qt float/double routines, speak up !

Yes, we do a lot of a less than/greater than checks, would be nice if
Qt contained generic methods for that.

-- 
 [ signature omitted ]