X-Spam-Check-By: sourceware.org Message-ID: <462D5638.70808@cox.net> Date: Tue, 24 Apr 2007 00:58:32 +0000 From: Greg Chicares User-Agent: Thunderbird 1.5.0.10 (Windows/20070221) MIME-Version: 1.0 To: cygwin AT cygwin DOT com Subject: Re: newlib?: pow function can produce incorrect results. References: <17190 DOT 86623 DOT qm AT web59108 DOT mail DOT re1 DOT yahoo DOT com> In-Reply-To: <17190.86623.qm@web59108.mail.re1.yahoo.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-IsSubscribed: yes Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com On 2007-04-23 23:52Z, Cary R. wrote: > I had some more time to look into this and when the > simple C program I mentioned earlier uses variables > like the other program, incorrect results are > produced. I have attached this C/C++ program. I > certainly don't understand what is going on. I would > have expected pow to be pass-by value Unless the function call is optimized away. Here, gcc seems to do that iff you feed the floating literal '1.0' to pow() as its first argument. The "as-if" rule allows that IIRC. In one case, it behaves as if an IEC 60559 math library were used. In the other case, it calls into a math library that doesn't conform to IEC 60559. > which should > make the two calls identical from a system standpoint, > but the results imply something different. Any > suggestions would be greatly appreciated. You've got double one; one = 1.0; , and these two expressions pow(1.0, inf); pow(one, inf); produce different results: unity and NaN, respectively. Compile with '-ggdb'; run in insight; set "source mode" to "mixed": 19 var = pow(1.0, inf); 0x4010f2 : fld1 - 0x4010f4 : fstpl 0xfffffff8(%ebp) 20 printf("1.0 ** inf is %f", var); - 0x4010f7 : fldl 0xfffffff8(%ebp) - 0x4010fa : fstpl 0x4(%esp) - 0x4010fe : movl $0x40203d,(%esp) - 0x401105 : call 0x401330 21 var = pow(one, inf); // This produces incorrect results! 0x40110a : fldl 0xffffffe8(%ebp) - 0x40110d : fstpl 0x8(%esp) - 0x401111 : fldl 0xffffffd8(%ebp) - 0x401114 : fstpl (%esp) - 0x401117 : call 0x401320 - 0x40111c : fstpl 0xfffffff8(%ebp) Note that there's only one 'FLD1': the others are 'FLDL'. C99 F.9.4.4 says "pow(+1, y) returns 1 for any y, even a NaN." and evidently the compiler relies on that on line 19, where it elides the function call. That particular result is required if __STDC_IEC_559__ is defined, but not forbidden if that macro isn't defined. (I'm not sure what C89 says.) On line 21, the compiler calls into the library, and gets a different result. That's just what this math library does: it simply doesn't conform to IEC 60559. Incidentally, '-mno-cygwin' gives a similar outcome: 1.0 ** -inf is 1.000000, -1.#IND00. with a different math library. Are you only seeking insight, or is there a particular problem you want to solve? -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/