Coverage Report

Created: 2025-06-24 07:03

/src/moddable/xs/tools/fdlibm/e_fmod.c
Line
Count
Source (jump to first uncovered line)
1
2
/* @(#)e_fmod.c 1.3 95/01/18 */
3
/*
4
 * ====================================================
5
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6
 *
7
 * Developed at SunSoft, a Sun Microsystems, Inc. business.
8
 * Permission to use, copy, modify, and distribute this
9
 * software is freely granted, provided that this notice 
10
 * is preserved.
11
 * ====================================================
12
 */
13
14
//__FBSDID("$FreeBSD: src/lib/msun/src/e_fmod.c,v 1.10 2008/02/22 02:30:34 das Exp $");
15
16
/* 
17
 * __ieee754_fmod(x,y)
18
 * Return x mod y in exact arithmetic
19
 * Method: shift and subtract
20
 */
21
22
#include "math_private.h"
23
24
static const double one = 1.0, Zero[] = {0.0, -0.0,};
25
26
double
27
__ieee754_fmod(double x, double y)
28
22.0M
{
29
22.0M
  int32_t n,hx,hy,hz,ix,iy,sx,i;
30
22.0M
  u_int32_t lx,ly,lz;
31
32
22.0M
  EXTRACT_WORDS(hx,lx,x);
33
22.0M
  EXTRACT_WORDS(hy,ly,y);
34
22.0M
  sx = hx&0x80000000;   /* sign of x */
35
22.0M
  hx ^=sx;    /* |x| */
36
22.0M
  hy &= 0x7fffffff; /* |y| */
37
38
    /* purge off exception values */
39
22.0M
  if((hy|ly)==0||(hx>=0x7ff00000)||  /* y=0,or x not finite */
40
22.0M
    ((hy|((ly|-ly)>>31))>0x7ff00000))  /* or y is NaN */
41
758k
      return (x*y)/(x*y);
42
21.3M
  if(hx<=hy) {
43
4.10M
      if((hx<hy)||(lx<ly)) return x;  /* |x|<|y| return x */
44
133k
      if(lx==ly) 
45
133k
    return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/
46
133k
  }
47
48
    /* determine ix = ilogb(x) */
49
17.2M
  if(hx<0x00100000) { /* subnormal x */
50
0
      if(hx==0) {
51
0
    for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
52
0
      } else {
53
0
    for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
54
0
      }
55
17.2M
  } else ix = (hx>>20)-1023;
56
57
    /* determine iy = ilogb(y) */
58
17.2M
  if(hy<0x00100000) { /* subnormal y */
59
37
      if(hy==0) {
60
405
    for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
61
24
      } else {
62
135
    for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
63
13
      }
64
17.2M
  } else iy = (hy>>20)-1023;
65
66
    /* set up {hx,lx}, {hy,ly} and align y to x */
67
17.2M
  if(ix >= -1022) 
68
17.2M
      hx = 0x00100000|(0x000fffff&hx);
69
0
  else {   /* subnormal x, shift x to normal */
70
0
      n = -1022-ix;
71
0
      if(n<=31) {
72
0
          hx = (hx<<n)|(lx>>(32-n));
73
0
          lx <<= n;
74
0
      } else {
75
0
    hx = lx<<(n-32);
76
0
    lx = 0;
77
0
      }
78
0
  }
79
17.2M
  if(iy >= -1022) 
80
17.2M
      hy = 0x00100000|(0x000fffff&hy);
81
37
  else {   /* subnormal y, shift y to normal */
82
37
      n = -1022-iy;
83
37
      if(n<=31) {
84
21
          hy = (hy<<n)|(ly>>(32-n));
85
21
          ly <<= n;
86
21
      } else {
87
16
    hy = ly<<(n-32);
88
16
    ly = 0;
89
16
      }
90
37
  }
91
92
    /* fix point fmod */
93
17.2M
  n = ix - iy;
94
470M
  while(n--) {
95
456M
      hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
96
456M
      if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
97
236M
      else {
98
236M
        if((hz|lz)==0)    /* return sign(x)*0 */
99
3.11M
        return Zero[(u_int32_t)sx>>31];
100
232M
        hx = hz+hz+(lz>>31); lx = lz+lz;
101
232M
      }
102
456M
  }
103
14.0M
  hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
104
14.0M
  if(hz>=0) {hx=hz;lx=lz;}
105
106
    /* convert back to floating value and restore the sign */
107
14.0M
  if((hx|lx)==0)      /* return sign(x)*0 */
108
1.67M
      return Zero[(u_int32_t)sx>>31];
109
19.5M
  while(hx<0x00100000) {   /* normalize x */
110
7.10M
      hx = hx+hx+(lx>>31); lx = lx+lx;
111
7.10M
      iy -= 1;
112
7.10M
  }
113
12.4M
  if(iy>= -1022) { /* normalize output */
114
12.4M
      hx = ((hx-0x00100000)|((iy+1023)<<20));
115
12.4M
      INSERT_WORDS(x,hx|sx,lx);
116
12.4M
  } else {   /* subnormal output */
117
34
      n = -1022 - iy;
118
34
      if(n<=20) {
119
13
    lx = (lx>>n)|((u_int32_t)hx<<(32-n));
120
13
    hx >>= n;
121
21
      } else if (n<=31) {
122
6
    lx = (hx<<(32-n))|(lx>>n); hx = sx;
123
15
      } else {
124
15
    lx = hx>>(n-32); hx = sx;
125
15
      }
126
34
      INSERT_WORDS(x,hx|sx,lx);
127
34
      x *= one;   /* create necessary signal */
128
34
  }
129
12.4M
  return x;   /* exact output */
130
14.0M
}