delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2007/04/23/20:58:58

X-Spam-Check-By: sourceware.org
Message-ID: <462D5638.70808@cox.net>
Date: Tue, 24 Apr 2007 00:58:32 +0000
From: Greg Chicares <chicares AT cox DOT net>
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>
X-IsSubscribed: yes
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
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	<main+162>:		fld1
-	0x4010f4	<main+164>:		fstpl  0xfffffff8(%ebp)
	20	  printf("1.0 ** inf is %f", var);
-	0x4010f7	<main+167>:		fldl   0xfffffff8(%ebp)
-	0x4010fa	<main+170>:		fstpl  0x4(%esp)
-	0x4010fe	<main+174>:		movl   $0x40203d,(%esp)
-	0x401105	<main+181>:		call   0x401330 <printf>
	21	  var = pow(one, inf); // This produces incorrect results!
	0x40110a	<main+186>:		fldl   0xffffffe8(%ebp)
-	0x40110d	<main+189>:		fstpl  0x8(%esp)
-	0x401111	<main+193>:		fldl   0xffffffd8(%ebp)
-	0x401114	<main+196>:		fstpl  (%esp)
-	0x401117	<main+199>:		call   0x401320 <pow>
-	0x40111c	<main+204>:		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/

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019