From owner-freebsd-bugs Mon Sep 4 23:50: 6 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 9B48937B43E for ; Mon, 4 Sep 2000 23:50:03 -0700 (PDT) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id XAA50123; Mon, 4 Sep 2000 23:50:03 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Date: Mon, 4 Sep 2000 23:50:03 -0700 (PDT) Message-Id: <200009050650.XAA50123@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Bruce Evans Subject: Re: bin/21024: pow() ERANGE bug Reply-To: Bruce Evans Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org The following reply was made to PR bin/21024; it has been noted by GNATS. From: Bruce Evans To: aa8vb@nc.rr.com Cc: FreeBSD-gnats-submit@FreeBSD.ORG Subject: Re: bin/21024: pow() ERANGE bug Date: Tue, 5 Sep 2000 17:40:55 +1100 (EST) 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 To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message