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]