According to the man page: The functions exp(), expm1(), pow() detect if the computed value will overflow, set the global variable errno to ERANGE, and ... However, pow() does not set errno to ERANGE on overflow. Fix: Please update the pow() function to set errno on overflow. Might also check other likely suspects such as exp() and expm1(). --Thanks. How-To-Repeat: Example: The attached code generates: Inf 0 The output should be: Inf 34 (34 is ERANGE) #include <math.h> #include <stdio.h> #include <errno.h> #include <ieeefp.h> main() { fpsetmask(0); printf( "%g\n", pow(1e300,2) ); pow(1e300,2); printf( "%d\n", errno ); }
On Mon, 4 Sep 2000 aa8vb@nc.rr.com wrote: > >Description: > > According to the man page: > > The functions exp(), expm1(), pow() detect if the computed value will > overflow, set the global variable errno to ERANGE, and ... This is mainly a bug in the man page. This part of it describes the behaviour of pow() in the old BSD libm, but we use Sun's fdlibm. The man page had already rotted for exp() and expm1() in the old libm -- errno was set for pow() on Vaxes and Tahoes, but was not set for exp() or expm1() on any machine. The man page actually says: ... set the global variable errno to ERANGE [no comma here] and cause a reserved operand fault on a Vax or Tahoe. so it is not clear that ERANGE is set except on Vaxes and Tahoes. In fact, according to the sources it _is_ only set on Vaxes and Tahoes (all settings of errno in the old libm are done by infnan.s which only exists for Vaxes and Tahoes). > However, pow() does not set errno to ERANGE on overflow. The actual behaviour on overflow is: (1) Attempt to set the IEEE exception flags (if any) in an IEEE'ish way by evaluating the overflowing expression `huge*huge' where `huge' is `static const double huge = 1.0e300'. This normally fails due to dubious compiler optimizations (gcc evaluates the expression at compile time and doesn't generate code to set the flags at runtime). (2) If libm is compiled with -D_POSIX_MODE and the library mode is not changed from the resulting default, then set errno to ERANGE. -D_POSIX_MODE is not the default and not recommended, although it is required for "POSIX" (actually old Standard C) conformance -- see src/lib/msun/Makefile. It mainly slows things down and messes up the return value for domain errors. There are other configuration flags/library modes which mess up the return value even for range errors. This non-conformance with old Standard C is unlikely to be changed, since setting errno for math functions is considered harmful and is not required in the current C standard. This PR should be turned into one about the libm man pages. The descriptions of error handling are anachronistic and/or incomplete. As an example of incompleteness, there are 19 special cases for pow() (see the sources) and only a couple of these are described in the man page. Bruce
Class Changed From-To: sw-bug->doc-bug After getting bitten by the pow(3) inaccuracies, I was about to file a PR correcting it, but found this one alredy filed (two years old). Per Bruce's suggestion reclassify it as a documentation problem and assign to Bruce :-)
Responsible Changed From-To: freebsd-bugs->bde
The man page discussed in this PR has had many changes since this PR was filed back in 2000. It appears no longer relevant to src/lib/msun/man/exp.3. I suggest to close this PR. http://www.freebsd.org/cgi/query-pr.cgi?pr=docs/21024
State Changed From-To: open->closed As indicated in recent followup, the man page no longer misclaims that pow() sets errno to ERANGE on overflow. (Such setting is a C90 misfeature that has never been supported.)