It does not appear to be possible to cross-build arm from i386 at the
moment, and I have no ARM hardware anyway. Thus, I'm sure there are
bugs. I will gladly fix these when the arm port is more mature.
Reviewed by: standards@
features appear to work, subject to the caveat that you tell gcc you
want standard rather than recklessly fast behavior
(-mieee-with-inexact -mfp-rounding-mode=d).
The non-standard feature of delivering a SIGFPE when an application
raises an unmasked exception does not work, presumably due to a kernel
bug. This isn't so bad given that floating-point exceptions on the
Alpha architecture are not precise, so making them useful in userland
requires a significant amount of wizardry.
Reviewed by: standards@
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.
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
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.
[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.
(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.
constants the wrong way on the VAX. Instead, use C99 hexadecimal
floating-point constants, which are guaranteed to be exact on binary
IEEE machines. (The correct hexadecimal values were already provided
in the source, but not used.) Also, convert the constants to
lowercase to work around a gcc bug that wasn't fixed until gcc 3.4.0.
Prompted by: stefanf
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>
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).
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
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.
binaries in /bin and /sbin installed in /lib. Only the versioned files
reside in /lib, the .so symlink continues to live /usr/lib so the
toolchain doesn't need to be modified.
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.
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.
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
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>
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)
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