From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19377 invoked by alias); 5 Jul 2005 14:28:30 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 19330 invoked by uid 22791); 5 Jul 2005 14:28:25 -0000 Received: from smtp-102-tuesday.noc.nerim.net (HELO mallaury.nerim.net) (62.4.17.102) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Tue, 05 Jul 2005 14:28:25 +0000 Received: from uniton.integrable-solutions.net (gdr.net1.nerim.net [62.212.99.186]) by mallaury.nerim.net (Postfix) with ESMTP id 38F404F3F4; Tue, 5 Jul 2005 16:28:14 +0200 (CEST) Received: from uniton.integrable-solutions.net (localhost [127.0.0.1]) by uniton.integrable-solutions.net (8.12.10/8.12.10/SuSE Linux 0.7) with ESMTP id j65ERFKY006186; Tue, 5 Jul 2005 16:27:15 +0200 Received: (from gdr@localhost) by uniton.integrable-solutions.net (8.12.10/8.12.10/Submit) id j65ERFL0006185; Tue, 5 Jul 2005 16:27:15 +0200 To: Michael Veksler Cc: gcc@gcc.gnu.org Subject: Re: tr1::unordered_set bizarre rounding behavior (x86) References: From: Gabriel Dos Reis In-Reply-To: Date: Tue, 05 Jul 2005 14:28:00 -0000 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2005-07/txt/msg00150.txt.bz2 Michael Veksler 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 | #include | | double x=3.0; | | int main() | { | std::tr1::unordered_set 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 ? | 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, | 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 insertion. | It may lead to the "loss" of close entries, but in case of double it sounds | reasonable. | | | P.S. | std::tr1::hash 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 gdr@integrable-solutions.net