From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17232 invoked by alias); 6 May 2003 16:46:00 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 17212 invoked by uid 71); 6 May 2003 16:46:00 -0000 Resent-Date: 6 May 2003 16:46:00 -0000 Resent-Message-ID: <20030506164600.17211.qmail@sources.redhat.com> Resent-From: gcc-gnats@gcc.gnu.org (GNATS Filer) Resent-Cc: gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org Resent-Reply-To: gcc-gnats@gcc.gnu.org, bird@bainet.com Received: (qmail 10200 invoked by uid 48); 6 May 2003 16:38:32 -0000 Message-Id: <20030506163832.10199.qmail@sources.redhat.com> Date: Tue, 06 May 2003 16:46:00 -0000 From: bird@bainet.com Reply-To: bird@bainet.com To: gcc-gnats@gcc.gnu.org X-Send-Pr-Version: gnatsweb-2.9.3 (1.1.1.1.2.31) Subject: optimization/10644: float calculation exceeds representation max, only when optimizer is turned on X-SW-Source: 2003-05/txt/msg00395.txt.bz2 List-Id: >Number: 10644 >Category: optimization >Synopsis: float calculation exceeds representation max, only when optimizer is turned on >Confidential: no >Severity: non-critical >Priority: medium >Responsible: unassigned >State: open >Class: wrong-code >Submitter-Id: net >Arrival-Date: Tue May 06 16:46:00 UTC 2003 >Closed-Date: >Last-Modified: >Originator: Rebecca Bird >Release: gcc version 3.2.3 (also 3.2.1 and 3.2) >Organization: >Environment: Red Hat Linux 7.2, kernel 2.4.18, on Pentium IV >Description: #include // ostream #include // numeric_limits::max using namespace std; // ------------------------------------------------------------------- template // T = double or float static T factorial(T value) { T fact = 1.0; while (value > 1.0) fact *= value--; return fact; } // ------------------------------------------------------------------- template // T = double or float static void test(T) { cout << "representation max = " << numeric_limits::max() << "\n\n"; cout << "factorial(34) = "<< factorial(T(34)) << endl; cout << "factorial(35) = " << factorial(T(35)) << endl; cout << "factorial(170) = " << factorial(T(170)) << endl; cout << "factorial(171) = " << factorial(T(171)) << "\n\n"; } // ------------------------------------------------------------------- int main() { cout << "factorial limits for floats:\n"; test((float)0); cout << "factorial limits for doubles:\n"; test((double)0); return 0; } >How-To-Repeat: The code explores the range of the factorial function for floats vs doubles. When run without optimization: g++-3.2 factorial.cpp -o test the code correctly outputs "inf" for arguments > 34 for float instantiation, and "inf" for arguments > 170 for double. When any optimization level is used, say: g++-3.2 -O3 factorial.cpp -o test the double output remains the same, but factorial(float 35) and factorial(float 170) now give incorrect results. Specifically, the float instantiation returns values 1.03331e+40 for 35! and 7.25742e+306 for 170! which are more than the max float = 2.95233e+38. >Fix: If I add code to factorial such as: T fact = 1.0; ostringstream ist; ist << fact; the program produces correct answers even with optimization turned on. However, this slows down the processing time for the factorial routine (and shouldn't be necessary). >Release-Note: >Audit-Trail: >Unformatted: ----gnatsweb-attachment---- Content-Type: text/plain; name="factorial.cpp" Content-Disposition: inline; filename="factorial.cpp" // Show limits of factorial routine for floats vs doubles #include // ostream #include // numeric_limits::max using namespace std; // ------------------------------------------------------------------- template // T = double or float static T factorial(T value) { T fact = 1.0; while (value > 1.0) fact *= value--; return fact; } // ------------------------------------------------------------------- template // T = double or float static void test(T) { cout << "representation max = " << numeric_limits::max() << "\n\n"; cout << "factorial(34) = "<< factorial(T(34)) << endl; cout << "factorial(35) = " << factorial(T(35)) << endl; cout << "factorial(170) = " << factorial(T(170)) << endl; cout << "factorial(171) = " << factorial(T(171)) << "\n\n"; } // ------------------------------------------------------------------- int main() { cout << "factorial limits for floats:\n"; test((float)0); cout << "factorial limits for doubles:\n"; test((double)0); return 0; }