diff --git a/reactos/lib/crt/crt.rbuild b/reactos/lib/crt/crt.rbuild index 2db3f46fe95..c12c110cf71 100644 --- a/reactos/lib/crt/crt.rbuild +++ b/reactos/lib/crt/crt.rbuild @@ -119,7 +119,7 @@ jn_yn.c ldexp.c log10.c - modf.c + s_modf.c pow.c sinh.c stubs.c diff --git a/reactos/lib/crt/math/fmod.c b/reactos/lib/crt/math/fmod.c deleted file mode 100644 index 7a1f0cef180..00000000000 --- a/reactos/lib/crt/math/fmod.c +++ /dev/null @@ -1,39 +0,0 @@ -/* Math functions for i387. - Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by John C. Bowman , 1995. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include - -double fmod (double __x, double __y); - -double fmod (double __x, double __y) -{ - register double __val; -#ifdef __GNUC__ - __asm __volatile__ - ("1: fprem\n\t" - "fstsw %%ax\n\t" - "sahf\n\t" - "jp 1b" - : "=t" (__val) : "0" (__x), "u" (__y) : "ax", "cc"); -#else - __val = linkme_fmod(__x, __y); -#endif /*__GNUC__*/ - return __val; -} diff --git a/reactos/lib/crt/math/math.c b/reactos/lib/crt/math/math.c index ff1d0e266f9..dd5521ac9cd 100644 --- a/reactos/lib/crt/math/math.c +++ b/reactos/lib/crt/math/math.c @@ -33,10 +33,6 @@ double linkme_log2(double __x) return 0; } -double linkme_fmod(double __x, double __y) -{ - return fmod(__x, __y); -} double linkme_sqrt(double __x) { diff --git a/reactos/lib/crt/math/s_modf.c b/reactos/lib/crt/math/s_modf.c new file mode 100644 index 00000000000..bcde557c550 --- /dev/null +++ b/reactos/lib/crt/math/s_modf.c @@ -0,0 +1,194 @@ + + +/* @(#)s_modf.c 5.1 93/09/24 */ +/* + * ==================================================== + * 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. + * ==================================================== + */ + +/* +FUNCTION + <>, <>---split fractional and integer parts + +INDEX + modf +INDEX + modff + +ANSI_SYNOPSIS + #include + double modf(double <[val]>, double *<[ipart]>); + float modff(float <[val]>, float *<[ipart]>); + +TRAD_SYNOPSIS + #include + double modf(<[val]>, <[ipart]>) + double <[val]>; + double *<[ipart]>; + + float modff(<[val]>, <[ipart]>) + float <[val]>; + float *<[ipart]>; + +DESCRIPTION + <> splits the double <[val]> apart into an integer part + and a fractional part, returning the fractional part and + storing the integer part in <<*<[ipart]>>>. No rounding + whatsoever is done; the sum of the integer and fractional + parts is guaranteed to be exactly equal to <[val]>. That + is, if . <[realpart]> = modf(<[val]>, &<[intpart]>); then + `<<<[realpart]>+<[intpart]>>>' is the same as <[val]>. + <> is identical, save that it takes and returns + <> rather than <> values. + +RETURNS + The fractional part is returned. Each result has the same + sign as the supplied argument <[val]>. + +PORTABILITY + <> is ANSI C. <> is an extension. + +QUICKREF + modf ansi pure + modff - pure + +*/ + +/* + * modf(double x, double *iptr) + * return fraction part of x, and return x's integral part in *iptr. + * Method: + * Bit twiddling. + * + * Exception: + * No exception. + */ + + +static const double one = 1.0; + +#define __int32_t long +#define __uint32_t unsigned long +#define __IEEE_LITTLE_ENDIAN + +#ifdef __IEEE_BIG_ENDIAN + +typedef union +{ + struct + { + __uint32_t msw; + __uint32_t lsw; + } parts; + double value; +} ieee_double_shape_type; + +#endif + +#ifdef __IEEE_LITTLE_ENDIAN + +typedef union +{ + struct + { + __uint32_t lsw; + __uint32_t msw; + } parts; + double value; +} ieee_double_shape_type; + +#endif + + +/* Get two 32 bit ints from a double. */ + +#define EXTRACT_WORDS(ix0,ix1,d) \ +do { \ + ieee_double_shape_type ew_u; \ + ew_u.value = (d); \ + (ix0) = ew_u.parts.msw; \ + (ix1) = ew_u.parts.lsw; \ +} while (0) + +/* Get the more significant 32 bit int from a double. */ + +#define GET_HIGH_WORD(i,d) \ +do { \ + ieee_double_shape_type gh_u; \ + gh_u.value = (d); \ + (i) = gh_u.parts.msw; \ +} while (0) + +/* Get the less significant 32 bit int from a double. */ + +#define GET_LOW_WORD(i,d) \ +do { \ + ieee_double_shape_type gl_u; \ + gl_u.value = (d); \ + (i) = gl_u.parts.lsw; \ +} while (0) + +/* Set a double from two 32 bit ints. */ + +#define INSERT_WORDS(d,ix0,ix1) \ +do { \ + ieee_double_shape_type iw_u; \ + iw_u.parts.msw = (ix0); \ + iw_u.parts.lsw = (ix1); \ + (d) = iw_u.value; \ +} while (0) + + + + +double modf(double x, double *iptr) +{ + __int32_t i0,i1,j_0; + __uint32_t i; + EXTRACT_WORDS(i0,i1,x); + j_0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ + if(j_0<20) { /* integer part in high x */ + if(j_0<0) { /* |x|<1 */ + INSERT_WORDS(*iptr,i0&0x80000000U,0); /* *iptr = +-0 */ + return x; + } else { + i = (0x000fffff)>>j_0; + if(((i0&i)|i1)==0) { /* x is integral */ + __uint32_t high; + *iptr = x; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000U,0); /* return +-0 */ + return x; + } else { + INSERT_WORDS(*iptr,i0&(~i),0); + return x - *iptr; + } + } + } else if (j_0>51) { /* no fraction part */ + __uint32_t high; + *iptr = x*one; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000U,0); /* return +-0 */ + return x; + } else { /* fraction part in low x */ + i = ((__uint32_t)(0xffffffffU))>>(j_0-20); + if((i1&i)==0) { /* x is integral */ + __uint32_t high; + *iptr = x; + GET_HIGH_WORD(high,x); + INSERT_WORDS(x,high&0x80000000U,0); /* return +-0 */ + return x; + } else { + INSERT_WORDS(*iptr,i0,i1&(~i)); + return x - *iptr; + } + } +} + +//#endif /* _DOUBLE_IS_32BITS */