newlib?: pow function can produce incorrect results.
Tue Apr 24 00:58:00 GMT 2007
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.
one = 1.0;
, and these two expressions
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
More information about the Cygwin