Michael Veksler <[EMAIL PROTECTED]> writes:
| Hello,
|
| In previous discussions on rounding of double on x86 I wanted
| to find an example that points to the absurdity of current
| gcc behavior.
| At last I found such an example:
Thanks for investing time in this and reporting.
| ---- t.cpp start ---
| #include <tr1/unordered_set>
| #include <iostream>
|
| double x=3.0;
|
| int main()
| {
| std::tr1::unordered_set<double> myset;
| myset.insert(2/x);
| myset.insert(2/x);
| std::cout << myset.size() << " elements\n";
| if (myset.size() > 1)
| std::cout << "Are last and first equal? "
| << std::boolalpha
| << ( *myset.begin() == *++myset.begin())
| << "\n";
| return 0;
| }
| --- t.cpp end ---
|
| Here is what I get (Pentium 4):
|
| --- trace begin ---
| test$ /opt/gcc-4.0-20050602/bin/g++ t.cpp
| test$ ./a.out
| 1 elements
| test$ /opt/gcc-4.0-20050602/bin/g++ -O3 -finline-limit=1000000 t.cpp
| test$ ./a.out
| 2 elements
| Are last and first equal? true
| --- trace end ---
|
| The behavior of the second run does not look right. What does it mean?
| 1. Is it forbidden by tr1 to define unordered_set<double> ?
| 2. Is it a bug in the tr1 document (which should have forbidden this).
| 3. Is it OK to have repetitions in unordered_set?
| 4. Is it a bug in gcc, for handling double the way it does?
| 5. Is it a bug in the implementation of tr1 in libstdc++ ?
| Maybe handling of double should move to a different
| translation unit, to avoid aggressive inlining. Or maybe
| there should be a specialization for equal_to<double>,
| where error bands will be used.
The different behaviour do not look right to me, no matter how IBM
is committed to GCC :-)
At the very least, there is a problem with GCC -- please, in case anybody
feels the need to read the standard to me; pause a minute :-)
I don't believe it is OK to have repetition in an unordered set.
However, there seems to be a need to clarifications. In particular,
how an implementation is supposed to behave if it supported NaNs and
other curiosity. I'll forward this to the LWG.
|
|
| Using error bands will work fine for unordered_set<doble> insertion.
| It may lead to the "loss" of close entries, but in case of double it sounds
| reasonable.
|
|
| P.S.
| std::tr1::hash<dobule> is implemented in a very bad way.
| it casts double to size_t, which of course does a very poor job on big
| values (is the result of 1.0e100 cast to size_t defined ?).
|
| Michael
--
Gabriel Dos Reis
[EMAIL PROTECTED]