Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Qt, hash and doubles

152 views
Skip to first unread message

Pleg

unread,
Sep 28, 2010, 11:03:04 PM9/28/10
to
Hi everybody,

yesterday I tried writing something simple and innocent as a QHash
with doubles as keys... and there's no way of making it work. Now,
qHash(double) is not defined, but even if I define it the compiler
still complains with "/usr/include/qt4/QtCore/qhash.h:875: error: call
of overloaded ‘qHash(const double&)’ is ambiguous".

E.g., starting from the given code in QtCreator:

#include <QtCore/QCoreApplication>
#include <qhash.h>

inline uint qHash(double key) { return uint(key); }

int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QHash<double, int> hash;
hash.insert(1.0, 1);
return a.exec();
}


This doesn't compile, it fails with that error.
I use Debian Squeeze AMD64, QtCreator 1.3.1, Qt should be 4.6.3.

It's totally weird, I can't be the first one with this problem, yet I
couldn't find anything on google (the only thing I found was someone
having this problem and SOLVING it by defining the qHash(double),
which doesn't work in my case).

Any ideas?

Thx,


Pleg

jack

unread,
Sep 29, 2010, 3:07:13 AM9/29/10
to

Haven't looked closely at it, but two things caught my eye here:

1. the compiler is complaining about qHash(const double&) being
ambiguous, i.e. there are two or more functions defined that it could
use for qHash(12.34). Makes me think that somebody somewhere already
defines one, so you shouldn't have to create your own definition.
Sure the result should be uint? 'Ambiguous' warnings often pop up when
there are two almost identical functions that return different types,
and the compiler can do an automatic cast from the one return type to
the other.

2. the difference in const-ness and reference: you define the function
taking a 'double' argument, qHash seems to be looking for something
taking a 'const double &' argument. Both can be called the same way as
qHash(12.34L), but they are different functions to the compiler.

Try changing your definition to

uint qHash(const double& key) { return uint(key); }

either it will work, or the compiler will tell you it is already
defined, and maybe even where.

-j

Ersek, Laszlo

unread,
Sep 29, 2010, 10:50:11 AM9/29/10
to
On Tue, 28 Sep 2010, Pleg wrote:

> yesterday I tried writing something simple and innocent as a QHash
> with doubles as keys...

Why? IMHO, floating point types are spectacularly unsuitable for keys.

Keys need to be identified uniquely and exactly. Floating point values
generally represent a real value within some error boundary.

Suppose you populate the hash from one source, then have to look up some
keys in a later phase from a different source. For example, you might
compute some values with an involved calculation and use the results as
keys to be stored. Suppose then the user types numbers on the terminal or
provides them in a text file, and you use strtod() to parse them. There's
no guarantee that the parsed values will match what they should match in
your intention. There's also no guarantee that they won't match keys you'd
deem unrelated (beyond normal hash collision, which the API handles
transparently).

A difference of 1 in least significant bit (or, ahem, radix) position of a
floating point value's mantissa should be considered "equal" under most
circumstances where floating point types are correctly used. However, two
such values might yield completely different hash values if digested
byte-for-byte. (And should, if the hash function is any good.)

----v----

-Wfloat-equal

Warn if floating point values are used in equality comparisons.

The idea behind this is that sometimes it is convenient (for the
programmer) to consider floating-point values as approximations to
infinitely precise real numbers. If you are doing this, then you need to
compute (by analyzing the code, or in some other way) the maximum or
likely maximum error that the computation introduces, and allow for it
when performing comparisons (and when producing output, but that's a
different problem). In particular, instead of testing for equality, you
would check to see whether the two values have ranges that overlap; and
this is done with the relational operators, so equality comparisons are
probably mistaken.

----^----

I believe tracking precision is very involving, one has to follow rounding
error through all arithmetic operations. That's why floating point should
only be used in numerical analysis apps and libs.

lacos

Pleg

unread,
Sep 29, 2010, 11:56:34 AM9/29/10
to
On Sep 29, 7:50 am, "Ersek, Laszlo" <la...@caesar.elte.hu> wrote:

[cut]

All true, but someone decided to represent time as a double, and I
need a QHash to store some stuff indexed by time.
Now, I want to get rid of it and use some integer type for time (e.g.
a little wrapper class for "struct timeval"), but for now I have to
live with it. But now the compiler spits out this incomprehensible
error...

Pleg

Pleg

unread,
Sep 29, 2010, 11:59:32 AM9/29/10
to
> Haven't looked closely at it, but two things caught my eye here:
>
> 1. the compiler is complaining about qHash(const double&) being
> ambiguous, i.e. there are two or more functions defined that it could
> use for qHash(12.34). Makes me think that somebody somewhere already
> defines one, so you shouldn't have to create your own definition.

Nope, if I don't put in my definition I get the same error.


> Sure the result should be uint? 'Ambiguous' warnings often pop up when
> there are two almost identical functions that return different types,
> and the compiler can do an automatic cast from the one return type to
> the other.

It should be, I checked the manual. Also, it's what these guys did
(and it solved their problem):
http://www.qtcentre.org/threads/24721-qHash%28double%29-problem-with-Qt-4.6-%28tp1%29


>
> 2. the difference in const-ness and reference: you define the function
> taking a 'double' argument, qHash seems to be looking for something
> taking a 'const double &' argument. Both can be called the same way as
> qHash(12.34L), but they are different functions to the compiler.
>
> Try changing your definition to
>
> uint qHash(const double& key) { return uint(key); }


I tried that also, but I always get the same error -- and no extra
info :(


Pleg

Jasen Betts

unread,
Sep 30, 2010, 5:08:13 AM9/30/10
to
On 2010-09-29, Pleg <pleg...@gmail.com> wrote:
> On Sep 29, 7:50 am, "Ersek, Laszlo" <la...@caesar.elte.hu> wrote:
>
> [cut]
>
> All true, but someone decided to represent time as a double, and I
> need a QHash to store some stuff indexed by time.

storing is the easy bit, with float keys retreiving the stored data
could be hard. consider using some sort of ordered storage instead
(like a tree)

> Now, I want to get rid of it and use some integer type for time (e.g.
> a little wrapper class for "struct timeval"), but for now I have to
> live with it. But now the compiler spits out this incomprehensible
> error...

making it compile is the least of the problems.

--
¡spuɐɥ ou 'ɐꟽ ʞooꞀ

0 new messages