Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / libcc.ansi / math / fmod.c
1 /* fmod function */
2 /* Author Robert R. Hall (hall@crach.cts.com) */
3
4 /* $Id: fmod.c,v 1.4 1994/06/24 11:43:40 ceriel Exp $ */
5
6 #include <math.h>
7 #include <errno.h>
8
9 double
10 (fmod)(double x, double y)
11 {                               /* compute fmod(x, y) */
12         double t;
13         int n, neg;
14         int ychar, xchar;
15
16         if (y == 0.0) {
17                 errno = EDOM;
18                 return 0.0;
19         }
20                                 /* fmod(finite, finite) */
21         if (y < 0.0) y = -y;
22         if (x < 0.0) x = -x, neg = 1;
23         else neg = 0;
24         t = frexp(y, &ychar);
25                                 /* substract |y| until |x| < |y| */
26
27         t = frexp(x, &xchar);
28         for (n = xchar - ychar; 0 <= n; --n) {
29                                 /* try to substract |y|*2^n */
30             t = ldexp(y, n);
31             if (t <= x) x -= t;
32         }
33         return (neg ? -x : x);
34 }