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 */