74 Commits

Author SHA1 Message Date
David Schultz
62247e9034 Declare scalbln(), scalblnf(), trunc(), and truncf(). 2004-06-20 09:26:41 +00:00
David Schultz
7ffaea8021 Implement trunc() and truncf(). 2004-06-20 09:25:43 +00:00
David Schultz
2f90a15e14 Add trivial implementations of scalbln() and scalblnf().
These routines are specified in C99 for the sake of
architectures where an int isn't big enough to represent
the full range of floating-point exponents.  However,
even the 128-bit long double format has an exponent smaller
than 15 bits, so for all practical purposes, scalbln() and
scalblnf() are aliases for scalbn() and scalbnf(), respectively.
2004-06-20 09:25:27 +00:00
Stefan Farfeleder
83bc89312c Our MI implementation of ilogb() returns -INT_MAX for the argument 0.0 rather
than INT_MIN, so adjust FP_ILOGB0 to reflect this.  Use <machine/_limits.h> for
INT_MAX's value while there.

Reviewed by:	standards@
2004-06-19 09:25:21 +00:00
David Schultz
c4da2324a3 Fix a bug where rintf() rounded the wrong way in round-to-nearest mode
on all inputs of the form x.75, where x is an even integer and
log2(x) = 21.  A similar problem occurred when rounding upward.
The bug involves the following snippet copied from rint():

	i>>=1;
	if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);

The constant 0x100000 should be 0x200000.  Apparently this case was
never tested.

It turns out that the bit manipulation is completely superfluous
anyway, so remove it.  (It tries to simulate 90% of the rounding
process that the FPU does anyway.)  Also, the special case of +-0 is
handled twice (in different ways), so remove the second instance.

Throw in some related simplifications from bde:

- Work around a bug where gcc fails to clip to float precision by
  declaring two float variables as volatile.  Previously, we
  tricked gcc into generating correct code by declaring some
  float constants as doubles.

- Remove additional superfluous bit manipulation.

- Minor reorganization.

- Include <sys/types.h> explicitly.

Note that some of the equivalent lines in rint() also appear to be
unnecessary, but I'll defer to the numerical analysts who wrote it,
since I can't test all 2^64 cases.

Discussed with:	bde
2004-06-09 21:24:52 +00:00
David Schultz
207bc1d79b Include <sys/cdefs.h> earlier to get the various visibility constants.
Previously, we were relying on <sys/_types.h> to include it implicitly.
2004-06-09 10:32:05 +00:00
David Schultz
d0f1363370 Add round(3) and roundf(3) and the associated documentation.
PR:		59797
Submitted by:	"Steven G. Kargl" <kargl@troutmask.apl.washington.edu>
Reviewed by:	bde (earlier version, last year)
2004-06-07 08:05:36 +00:00
Bruce Evans
4f8f819975 Fixed lots of 1 ULP errors caused by a broken approximation for pi/2.
We approximate pi with more than float precision using pi_hi+pi_lo in
the usual way (pi_hi is actually spelled pi in the source code), and
expect (float)0.5*pi_lo to give the low part of the corresponding
approximation for pi/2.  However, the high part for pi/2 (pi_o_2) is
rounded to nearest, which happens to round up, while the high part for
pi was rounded down.  Thus pi_o_2+(float)0.5*pi (in infinite precision)
was a very bad approximation for pi/2 -- the low term has the wrong
sign and increases the error drom less than half an ULP to a full ULP.

This fix rounds up instead of down for pi_hi.  Consistently rounding
down instead of up should work, and is the method used in e_acosf.c
and e_asinf.c.  The reason for the difference is that we sometimes
want to return precisely pi/2 in e_atan2f.c, so it is convenient to
have a correctly rounded (to nearest) value for pi/2 in a variable.
a_acosf.c and e_asinf.c also differ in directly approximating pi/2
instead pi; they multiply by 2.0 instead of dividing by 0.5 to convert
the approximation.

These complications are not directly visible in the double precision
versions because rounding to nearest happens to round down.
2004-06-02 17:09:05 +00:00
David Schultz
73fbb89dd6 Port a bugfix from FDLIBM 5.3. The bug really only applies to tan()
and not tanf() because float type can't represent numbers large enough
to trigger the problem.  However, there seems to be a precedent that
the float versions of the fdlibm routines should mirror their double
counterparts.

Also update to the FDLIBM 5.3 license.

Obtained from:	FDLIBM
Reviewed by:	exhaustive comparison
2004-06-02 04:39:44 +00:00
David Schultz
21d39caaee Merge a bugfix from FDLIBM 5.3 to ensure that the error in tan()
is always less than 1 ulp.  Also update to the 5.3 license.

Obtained from:	FDLIBM
2004-06-02 04:39:29 +00:00
Bruce Evans
f88a48cc43 Merged from double precision case (e_pow.c 1.10: sign fixes). 2004-06-01 19:33:30 +00:00
Bruce Evans
f083533b68 Fixed the sign of the result in some overflow and underflow cases (ones
where the exponent is an odd integer and the base is negative).

Obtained from:	fdlibm-5.3

Sun finally released a new version of fdlibm just a coupe of weeks
ago.  It only fixes 3 bugs (this one, another one in pow() that we
already have (rev.1.9), and one in tan().  I've learned too much about
powf() lately, so this fix was easy to merge.  The patch is not verbatim,
because our base version has many differences for portability and I
didn't like global renaming of an unrelated variable to keep it separate
from the sign variable.  This patch uses a new variable named sn for
the sign.
2004-06-01 19:28:38 +00:00
Bruce Evans
5f20e5ce7f Fixed another precision bug in powf(). This one is in the computation
[t=p_l+p_h High].  We multiply t by lg2_h, and want the result to be
exact.  For the bogus float case of the high-low decomposition trick,
we normally discard the lowest 12 bits of the fraction for the high
part, keeping 12 bits of precision.  That was used for t here, but it
doesnt't work because for some reason we only discard the lowest 9
bits in the fraction for lg2_h.  Discard another 3 bits of the fraction
for t to compensate.

This bug gave wrong results like:

      powf(0.9999999, -2.9999995) = 1.0000002 (should be 1.0000001)
        hex values: 3F7FFFFF C03FFFFE 3F800002 3F800001

As explained in the log for the previous commit, the bug is normally
masked by doing float calculations in extra precision on i386's, but
is easily detected by ucbtest on systems that don't have accidental
extra precision.

This completes fixing all the bugs in powf() that were routinely found
by ucbtest.
2004-06-01 19:03:31 +00:00
Bruce Evans
12be4e0d5a Fixed 2 bugs in the computation /* t_h=ax+bp[k] High */.
(1) The bit for the 1.0 part of bp[k] was right shifted by 4.  This seems
    to have been caused by a typo in converting e_pow.c to e_powf.c.
(2) The lower 12 bits of ax+bp[k] were not discarded, so t_h was actually
    plain ax+bp[k].  This seems to have been caused by a logic error in
    the conversion.

These bugs gave wrong results like:

    powf(-1.1, 101.0) = -15158.703 (should be -15158.707)
      hex values: BF8CCCCD 42CA0000 C66CDAD0 C66CDAD4

Fixing (1) gives a result wrong in the opposite direction (hex C66CDAD8),
and fixing (2) gives the correct result.

ucbtest has been reporting this particular wrong result on i386 systems
with unpatched libraries for 9 years.  I finally figured out the extent
of the bugs.  On i386's they are normally hidden by extra precision.
We use the trick of representing floats as a sum of 2 floats (one much
smaller) to get extra precision in intermediate calculations without
explicitly using more than float precision.  This trick is just a
pessimization when extra precision is available naturally (as it always
is when dealing with IEEE single precision, so the float precision part
of the library is mostly misimplemented).  (1) and (2) break the trick
in different ways, except on i386's it turns out that the intermediate
calculations are done in enough precision to mask both the bugs and
the limited precision of the float variables (as far as ucbtest can
check).

ucbtest detects the bugs because it forces float precision, but this
is not a normal mode of operation so the bug normally has little effect
on i386's.

On systems that do float arithmetic in float precision, e.g., amd64's,
there is no accidental extra precision and the bugs just give wrong
results.
2004-06-01 18:08:39 +00:00
Stefan Farfeleder
8b5cd5a662 Add implementations for cimag{,f,l}, creal{,f,l} and conj{,f,l}. They are
needed for cases where GCC's builtin functions cannot be used and for
compilers that don't know about them.

Approved by:	das (mentor)
2004-05-30 09:21:56 +00:00
Stefan Farfeleder
b60cb13f76 Add an implementation of copysignl(), a long double version of copysign().
Approved by:	das (mentor)
2004-05-07 18:56:31 +00:00
David Schultz
8f3f7c66d0 Make sure that symbols are declared in math.h iff the appropriate
namespaces are visible.  Previously, math.h failed to hide some C99-,
XSI-, and BSD-specific symbols in certain compilation environments.

The referenced PR has a nice listing of the appropriate conditions for
making symbols visible in math.h.  The only non-stylistic difference
between the patch in the PR and this commit is that I superfluously
test for __BSD_VISIBLE in a few places to be more explicit about which
symbols have historically been part of the FreeBSD environment.

PR:		65939
Submitted by:	Stefan Farfeleder <stefan@fafoe.narf.at>
2004-04-25 02:35:42 +00:00
David Schultz
334c760eea Remove a stale comment referring to values.h, which has never been
part of FreeBSD.

PR:		65939
2004-04-25 02:32:46 +00:00
Bruce Evans
6eb2d83e44 Initial support for C99's (or is it POSIX.1-2001's?) MATH_ERRNO,
MATH_ERREXCEPTION and math_errhandling, so that C99 applications at
least have the possibility of determining that errno is not set for
math functions.  Set math_errhandling to the non-standard-conforming
value of 0 for now to indicate that we don't support either method
of reporting errors.  We intentionally don't support MATH_ERRNO
because errno is a mistake, and we are missing support for
MATH_ERREXCEPTION (<fenv.h>, compiler support for <fenv.h>, and
actually setting the exception flags correctly).
2004-03-12 12:02:03 +00:00
David Schultz
7a773faadc Fix a problem where libm compiled under 5.X would depend on features
that are only in libc.so.5.  This broke some 4.X applications linked
to libm and run under 5.X.

Background:
In C99, isinf() and isnan() cannot be implemented as regular
functions.  We use macros that call libc functions in 5.X, but for
libm-internal use, we need to use the old versions until the next
time libm's major version number is bumped.

Submitted by:	bde
Reported by:	imp, kris
2003-10-27 01:28:07 +00:00
Dag-Erling Smørgrav
2a063d30f6 Better safe than clever.
Submitted by:	das
2003-10-25 19:53:28 +00:00
Dag-Erling Smørgrav
e334ea2edc - fabsl.c should be named s_fabsl.c for consistency with libmsun's
documented naming scheme (unfortunately the documentation isn't in the
   tree as far as I can tell); no repocopy is required as there is no
   history to preserve.

 - replace simple and almost-correct implementation with slightly hackish
   but definitely correct implementation (tested on i386, alpha, sparc64)
   which requires pulling in fpmath.h and the MD _fpmath.h from libc.

 - try not to make a mess of the Makefile in the process.

 - enterprising minds are encouraged to implement more C99 long double
   functions.
2003-10-25 09:32:18 +00:00
Dag-Erling Smørgrav
29bd23abf0 Add prototypes for all long double functions in C99. Leave them all
#if 0'd out, except for fabsl(3) which I've implemented.
2003-10-23 08:23:38 +00:00
Dag-Erling Smørgrav
017e4316ae Implement fabsl(3), allowing the world to build with -fno-builtin. 2003-10-23 08:20:47 +00:00
Peter Wemm
3819e84017 Only provide one copy of the math functions. If we provide a MD function,
do not also provide a __generic_XXX version as well.  This is how we
used to runtime select the generic vs i387 versions on the i386 platform.

This saves a pile of #defines in the src/math_private.h file to undo the
__generic_XXX renames in some of the *.c files.
2003-07-23 04:53:47 +00:00
Peter Wemm
d48084b9e5 No longer need the internal __get_hw_float() function. 2003-07-23 04:25:04 +00:00
Peter Wemm
c3e6df78e1 Now that we do not need to do runtime detection for the broken default
fp emulator, stop doing the runtime selection of hardware or emulated
floating point operations on i386.  Note that I have not suppressed the
duplicate compiles yet.

While here, fix the alpha.  It has provided specific copysign/copysignf
functions since the beginning of time, but they have never been used.
2003-07-23 04:23:36 +00:00
Mike Barcroft
6f9622a926 Fix two misuses of __BSD_VISIBLE.
Submitted by:	bde
Approved by:	re
2003-05-22 17:07:57 +00:00
Peter Wemm
8e80f8a438 AMD64 support (another IEEEFP platform) 2003-04-30 21:06:30 +00:00
David Schultz
6d3bd9530d Fix braino in definition of isfinite().
Noticed by:	marcus
Pointy hat to:	das
2003-04-04 13:27:47 +00:00
Warner Losh
457f6cd2d6 - gamma_r, lgamma_r, gammaf_r, and lgammaf_r were protected by _REENTRANT
in math.h; the consensus here was that __BSD_VISIBLE was correct instead.

- gamma_r, lgamma_r, gammaf_r, and lgammaf_r had no documentation in the
  lgamma(3) manpage.

Reviewed by: standards@
Submitted by: Ben Mesander
2003-02-26 13:12:03 +00:00
Mike Barcroft
5d62092f94 o Implement C99 classification macros isfinite(), isinf(), isnan(),
isnormal().  The current isinf() and isnan() are perserved for
  binary compatibility with 5.0, but new programs will use the macros.
o Implement C99 comparison macros isgreater(), isgreaterequal(),
  isless(), islessequal(), islessgreater(), isunordered().

Submitted by:	David Schultz <dschultz@uclink.Berkeley.EDU>
2003-02-12 20:03:41 +00:00
Mike Barcroft
8e9b28311e Implement C99's signbit() macro. 2003-02-11 21:56:21 +00:00
Mike Barcroft
8cf5ed5125 Implement fpclassify():
o Add a MD header private to libc called _fpmath.h; this header
  contains bitfield layouts of MD floating-point types.
o Add a MI header private to libc called fpmath.h; this header
  contains bitfield layouts of MI floating-point types.
o Add private libc variables to lib/libc/$arch/gen/infinity.c for
  storing NaN values.
o Add __double_t and __float_t to <machine/_types.h>, and provide
  double_t and float_t typedefs in <math.h>.
o Add some C99 manifest constants (FP_ILOGB0, FP_ILOGBNAN, HUGE_VALF,
  HUGE_VALL, INFINITY, NAN, and return values for fpclassify()) to
  <math.h> and others (FLT_EVAL_METHOD, DECIMAL_DIG) to <float.h> via
  <machine/float.h>.
o Add C99 macro fpclassify() which calls __fpclassify{d,f,l}() based
  on the size of its argument.  __fpclassifyl() is never called on
  alpha because (sizeof(long double) == sizeof(double)), which is good
  since __fpclassifyl() can't deal with such a small `long double'.

This was developed by David Schultz and myself with input from bde and
fenner.

PR:		23103
Submitted by:	David Schultz <dschultz@uclink.Berkeley.EDU>
		(significant portions)
Reviewed by:	bde, fenner (earlier versions)
2003-02-08 20:37:55 +00:00
Jens Schweikhardt
9d5abbddbf Correct typos, mostly s/ a / an / where appropriate. Some whitespace cleanup,
especially in troff files.
2003-01-01 18:49:04 +00:00
Archie Cobbs
83999f5a32 Re-apply the previously backed-out commit that fixes the problem where
HUGE_VAL is not properly aligned on some architectures. The previous
fix now works because the two versions of 'math.h' (include/math.h
and lib/msun/src/math.h) have since been merged into one.

PR:	bin/43544
2002-10-31 23:05:20 +00:00
Mark Murray
bf2f52b5fa Remove duplicate declaration. 2002-10-23 17:35:11 +00:00
Bruce Evans
54e9b36765 Fixed a last-minute editing error in previous commit. nfs and/or cvs
replaced a 14-byte change in the middle of the file with 14 NULs at EOF
despite or because of aborting the initial commit to pick up the change.
2002-10-01 11:44:35 +00:00
Bruce Evans
219cbe1087 Merged all interesting difference between the old math.h and the current
one into the latter and removed the former.

This works around the bug that some broken Makefiles add -I.../src/include
to CFLAGS, resulting in the old math.h being preferred and differences
between the headers possibly being fatal.

The merge mainly involves declaring some functions as __pure2 although
they are not yet all strictly free of side effects.

PR:		43544
2002-10-01 11:34:42 +00:00
Archie Cobbs
ae8a4b2f36 Revert previous commit to unbreak world until we figure out the
right way to do it.
2002-09-20 15:43:26 +00:00
Archie Cobbs
f5f1272284 Fix a problem with the definition of HUGE_VAL causing the gcc warning
"cast increases required alignment of target type" on some platforms.

Reviewed by:	bde
2002-09-19 19:47:27 +00:00
Bruce Evans
3e2ec6ea88 e_pow.c:
Fixed pow(x, y) when x is very close to -1.0 and y is a very large odd
integer.  E.g., pow(-1.0 - pow(2.0, -52.0), 1.0 + pow(2.0, 52.0)) was
0.0 instead of being very close to -exp(1.0).

PR:		39236
Submitted by:	Stephen L Moshier <steve@moshier.net>

e_powf.c:
Apply the same patch although it is just cosmetic because odd integers
large enough to cause the problem are too large to be precisely represented
as floats.

MFC after:	1 week
2002-06-17 15:28:59 +00:00
Alfred Perlstein
59b19ff14a Fix formatting, this is hard to explain, so I'll show one example.
-       float ynf(int n, float x)       /* wrapper ynf */
+float
+ynf(int n, float x)    /* wrapper ynf */

This is because the __STDC__ stuff was indented.

Reviewed by: md5
2002-05-28 18:15:04 +00:00
Alfred Perlstein
2dcc228679 Assume __STDC__, remove non-__STDC__ code.
Reviewed by: md5
2002-05-28 17:51:46 +00:00
Alfred Perlstein
a82bbc730e Assume __STDC__, remove non-__STDC__ code.
Submitted by: keramida
2002-05-28 17:03:12 +00:00
Benno Rice
7191eaa757 Spread the word of PowerPC. 2002-05-21 04:00:47 +00:00
Bruce Evans
46d7c2979e Resurrect Lite1's gamma() as C99's tgamma(). Minimal changes. 2002-03-26 11:59:29 +00:00
Bruce Evans
6898f8c48e Fixed some minor style bugs. 2002-03-26 09:18:09 +00:00
David E. O'Brien
69160b1eb7 Remove __P() usage. 2002-03-21 23:54:04 +00:00
Jake Burkholder
fbeabbfad6 Add ifdef sparc64. 2002-01-02 06:54:18 +00:00