From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19746 invoked by alias); 27 Feb 2007 19:35:15 -0000 Received: (qmail 19622 invoked by uid 48); 27 Feb 2007 19:35:05 -0000 Date: Tue, 27 Feb 2007 19:35:00 -0000 Message-ID: <20070227193505.19621.qmail@sourceware.org> X-Bugzilla-Reason: CC References: Subject: [Bug fortran/30981] a ** exp fails for integer exponents if exp is "-huge()-1" (endless loop) In-Reply-To: Reply-To: gcc-bugzilla@gcc.gnu.org To: gcc-bugs@gcc.gnu.org From: "burnus at gcc dot gnu dot org" Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2007-02/txt/msg02978.txt.bz2 ------- Comment #3 from burnus at gcc dot gnu dot org 2007-02-27 19:35 ------- Hi, > > Could you post an example? With example I mean something which actually compiles and runs. Here, I have two problems: include '$(where)/amos/include/essential.ecm' is missing as well as the main program which calls the routine. And as always: The smaller the better. In addition, please attach such long files, they clutter the bug report page quite a bit if they are put into the comment field. > if ( n_normal .ge. 10.-eps .and. n_normal .le. 10+eps ) then > > PS. Notice the "eps" in the last segment of code. This is > really a bug also. It originally was > If ( n_normal .eq. 10. ) then > But in some cases it missed the proper branch. If you do: n_normal = 10.0 then if(n_normal == 10.0) should work. If you do n_normal = 500.0/100.0*2.0 then it might not work due to rounding errors and representation problems of a decimal number as binary number. Therefore, one should almost always use something like if ( abs(n_normal - 10.0) < eps), where eps is sensibly chosen, it could be e.g. eps = epsilon(n_normal), but this might be even too small. For irrational numbers such as 3.14159 it is more obvious that one should use, e.g. (abs(myNumber - 3.14159) < 1e-4) instead of "if (myNumber == 3.14159)". Back to the problem: The calculation goes only into an endless loop if the exponent is "-huge(integer)-1". Test case: program test implicit none print *, 5.0**(-huge(i)-1) end program The problem is that in pow_r4_i4 the following operation is done: if (n < 0) { n = -n; The problem is: For n == -huge(n) - 1 exists no positive number. Thus n == -n == -2147483648 (for integer(4)) -- burnus at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Ever Confirmed|0 |1 Keywords| |wrong-code Last reconfirmed|0000-00-00 00:00:00 |2007-02-27 19:35:04 date| | Summary|Program "Hangs" |a ** exp fails for integer | |exponents if exp is "- | |huge()-1" (endless loop) http://gcc.gnu.org/bugzilla/show_bug.cgi?id=30981