newlib-cygwin/newlib/libm/common/s_trunc.c

99 lines
2.5 KiB
C
Raw Normal View History

2002-06-08 05:59:57 +08:00
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
2009-03-25 Craig Howland <howland@LGSInnovations.com> * libc/include/math.h: (llround, llroundf): Declare. * libm/common/s_llround.c: New file, implementing llround(). * libm/common/sf_llround.c: New file, implementing llroundf(). * libm/common/sf_lround.c: Remove spurious cast in _DOUBLE_IS_32BITS version of function. * libm/common/sf_lrint.c: Ditto. * libm/common/sf_logb.c: Corrected return for subnormal argument by replacing existing function with a version created from sf_ilogb.c. * libm/common/s_logb.c: Ditto, except starting point s_ilogb.c. Also added documentation for logb() and logbf(). * libm/common/s_signbit.c: Add signbit() documentation. * libm/common/s_log2.c: Update return values to match what w_log2.c has, since log2 uses log(); add note about being derived instead of direct. * libm/common/sf_fma.c: Add casts to attempt to get correct results, as well as comments pointing out problems with the implementation. * libm/common/s_fma.c: Add fma() and fmaf() documentation. * libm/common/sf_remquo.c: Incorrect quotient returns for large values corrected by discarding existing function and replacing with Sun verion, with some enhancements. * libm/common/s_remquo.c: Ditto. Add remquo() and remquof() documentation. * libm/common/s_fmax.c: Add fmax() and fmaxf() documentation. * libm/common/s_fmin.c: Add fmin() and fminf() documentation. * libm/common/s_fdim.c: Return NAN for NAN arg, add fdim() and fdimf() documentation. * libm/common/sf_fdim.c: Return NAN for NAN arg, HUGE_VALF for inf arg. * libm/common/s_trunc.c: Add trunc() and truncf() documentation. * libm/common/s_rint.c: Add rint() and rintf() documentation. * libm/common/s_round.c: Add round() and roundf() documentation. * libm/common/s_scalbn.c: Add scalbln() and scalblnf() documentation. * libm/common/s_infinity.c: Add infinity() and infinityf() documentation. * libm/common/s_lround.c: Add lround(), lroundf(), llround(), and llroundf() documentation. * libm/common/s_lrint.c: Add lrint(), lrintf(), llrint(), and llrintf() documentation. * libm/common/isgreater.c: New file for documenting math.h function-like macros isgreater(), isgreaterequal(), isless(), islessequal(), islessgreater(), and isunordered(). * libm/common/s_isnan.c: Add documentation for function-like macros fpclassify(), isfinite(), isinf(), isnan(), and isnormal(). * libm/common/s_nearbyint.c: Add nearbyint() and nearbyintf() documentation. * libm/common/Makefile.am: Add s_llround.c (src); sf_llround.c (fsrc); s_fdim.def, s_fma.def, s_fmax.def, s_fmin.def, s_logb.def, s_lrint.def, s_lround.def, s_nearbyint.def, s_remquo.def, s_rint.def, s_round.def, s_signbit.def, s_trunc.def, and isgreater.def (chobj); re-name all existing chew files (chobj) to match source file base names (put in underscores), delete all special targets for chew files (leaving all to be generated by rule). * libm/common/Makefile.in: regenerate. * libm/math/w_exp2.c: Add "base 2" to documentation description (and delete TRAD_SYNOPSIS). * libm/math/w_gamma.c: Add tgamma() and tgammaf() documentation, along with some history behind the function names. * libm/math/math.tex: Add includes for newly-added documentation (see .def additions to common/Makefile.am and math/Makefile.am in this ChangeLog list), adjusted existing .def file names to match source file base names (added underscores); add mention of HUGE_VALF; rename "Version of library" section to "Error Handling" and add some text about floating-point exception; added section "Standards Compliance And Portability". * libm/math/Makefile.am: Add w_exp2.def (chobj); re-name all existing chew files (chobj) to match source file base names, delete all special targets for chew files (leaving all to be generated by rule). * libm/math/Makefile.in: regenerated * doc/makedoc.c: Change silent ignoring of commands < 5 characters to a failure when reading macro file for commands < 4 characters; add -v (verbose) option for printing some debugging information; get rid of spurious translation of "@*" to "*" (no source files used @*, so no existing doc pages were affected); clean up some compiler warnings. * doc/doc.str: add BUGS and SEEALSO sections (to match texi2pod.pl which has them); Remove ITEM command (redundant with makedoc built-in "o", not used in any present source file so nothing is lost, anyway). * HOWTO: New file to hold information for maintainers regarding how to do things. Initial sections on documentation and ELIX levels.
2009-03-26 03:13:24 +08:00
/*
FUNCTION
<<trunc>>, <<truncf>>--round to integer, towards zero
INDEX
trunc
INDEX
truncf
ANSI_SYNOPSIS
#include <math.h>
double trunc(double <[x]>);
float truncf(float <[x]>);
DESCRIPTION
The <<trunc>> functions round their argument to the integer value, in
floating format, nearest to but no larger in magnitude than the
argument, regardless of the current rounding direction. (While the
"inexact" floating-point exception behavior is unspecified by the C
standard, the <<trunc>> functions are written so that "inexact" is not
raised if the result does not equal the argument, which behavior is as
recommended by IEEE 754 for its related functions.)
RETURNS
<[x]> truncated to an integral value.
PORTABILITY
ANSI C, POSIX
*/
2002-06-08 05:59:57 +08:00
#include "fdlibm.h"
#ifndef _DOUBLE_IS_32BITS
#ifdef __STDC__
double trunc(double x)
#else
double trunc(x)
double x;
#endif
{
int signbit;
/* Most significant word, least significant word. */
int msw;
unsigned int lsw;
int exponent_less_1023;
EXTRACT_WORDS(msw, lsw, x);
/* Extract sign bit. */
signbit = msw & 0x80000000;
/* Extract exponent field. */
exponent_less_1023 = ((msw & 0x7ff00000) >> 20) - 1023;
if (exponent_less_1023 < 20)
{
/* All significant digits are in msw. */
if (exponent_less_1023 < 0)
{
/* -1 < x < 1, so result is +0 or -0. */
INSERT_WORDS(x, signbit, 0);
}
else
{
/* All relevant fraction bits are in msw, so lsw of the result is 0. */
INSERT_WORDS(x, signbit | (msw & ~(0x000fffff >> exponent_less_1023)), 0);
}
}
else if (exponent_less_1023 > 51)
{
if (exponent_less_1023 == 1024)
{
/* x is infinite, or not a number, so trigger an exception. */
return x + x;
}
/* All bits in the fraction fields of the msw and lsw are needed in the result. */
}
else
{
/* All fraction bits in msw are relevant. Truncate irrelevant
bits from lsw. */
INSERT_WORDS(x, msw, lsw & ~(0xffffffffu >> (exponent_less_1023 - 20)));
}
return x;
}
#endif /* _DOUBLE_IS_32BITS */