Bug 21024 - pow() ERANGE bug
Summary: pow() ERANGE bug
Status: Closed FIXED
Alias: None
Product: Documentation
Classification: Unclassified
Component: Books & Articles (show other bugs)
Version: Latest
Hardware: Any Any
: Normal Affects Only Me
Assignee: Bruce Evans
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2000-09-04 13:10 UTC by aa8vb
Modified: 2005-12-31 23:39 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description aa8vb 2000-09-04 13:10:01 UTC
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 );
}
Comment 1 Bruce Evans 2000-09-05 07:40:55 UTC
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
Comment 2 Mikhail Teterin freebsd_committer freebsd_triage 2002-08-20 17:26:57 UTC
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 :-) 


Comment 3 Mikhail Teterin freebsd_committer freebsd_triage 2002-08-20 17:26:57 UTC
Responsible Changed
From-To: freebsd-bugs->bde
Comment 4 Siebrand Mazeland 2005-12-31 16:23:14 UTC
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
Comment 5 Bruce Evans freebsd_committer freebsd_triage 2005-12-31 23:33:59 UTC
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.)