Skip to content

Commit eec0240

Browse files
committed
Add fmod function to the fdlibm
JerryScript-DCO-1.0-Signed-off-by: Szilard Ledan [email protected]
1 parent 2ee469e commit eec0240

File tree

3 files changed

+180
-0
lines changed

3 files changed

+180
-0
lines changed

third-party/fdlibm/e_fmod.c

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
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+
/*
15+
* __ieee754_fmod(x,y)
16+
* Return x mod y in exact arithmetic
17+
* Method: shift and subtract
18+
*/
19+
20+
#include "fdlibm.h"
21+
22+
#ifdef __STDC__
23+
static const double one = 1.0, Zero[] = {0.0, -0.0,};
24+
#else
25+
static double one = 1.0, Zero[] = {0.0, -0.0,};
26+
#endif
27+
28+
#ifdef __STDC__
29+
double __ieee754_fmod(double x, double y)
30+
#else
31+
double __ieee754_fmod(x,y)
32+
double x,y ;
33+
#endif
34+
{
35+
int n,hx,hy,hz,ix,iy,sx,i;
36+
unsigned lx,ly,lz;
37+
38+
hx = __HI(x); /* high word of x */
39+
lx = __LO(x); /* low word of x */
40+
hy = __HI(y); /* high word of y */
41+
ly = __LO(y); /* low word of y */
42+
sx = hx&0x80000000; /* sign of x */
43+
hx ^=sx; /* |x| */
44+
hy &= 0x7fffffff; /* |y| */
45+
46+
/* purge off exception values */
47+
if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */
48+
((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */
49+
return (x*y)/(x*y);
50+
if(hx<=hy) {
51+
if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */
52+
if(lx==ly)
53+
return Zero[(unsigned)sx>>31]; /* |x|=|y| return x*0*/
54+
}
55+
56+
/* determine ix = ilogb(x) */
57+
if(hx<0x00100000) { /* subnormal x */
58+
if(hx==0) {
59+
for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
60+
} else {
61+
for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
62+
}
63+
} else ix = (hx>>20)-1023;
64+
65+
/* determine iy = ilogb(y) */
66+
if(hy<0x00100000) { /* subnormal y */
67+
if(hy==0) {
68+
for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
69+
} else {
70+
for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
71+
}
72+
} else iy = (hy>>20)-1023;
73+
74+
/* set up {hx,lx}, {hy,ly} and align y to x */
75+
if(ix >= -1022)
76+
hx = 0x00100000|(0x000fffff&hx);
77+
else { /* subnormal x, shift x to normal */
78+
n = -1022-ix;
79+
if(n<=31) {
80+
hx = (hx<<n)|(lx>>(32-n));
81+
lx <<= n;
82+
} else {
83+
hx = lx<<(n-32);
84+
lx = 0;
85+
}
86+
}
87+
if(iy >= -1022)
88+
hy = 0x00100000|(0x000fffff&hy);
89+
else { /* subnormal y, shift y to normal */
90+
n = -1022-iy;
91+
if(n<=31) {
92+
hy = (hy<<n)|(ly>>(32-n));
93+
ly <<= n;
94+
} else {
95+
hy = ly<<(n-32);
96+
ly = 0;
97+
}
98+
}
99+
100+
/* fix point fmod */
101+
n = ix - iy;
102+
while(n--) {
103+
hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
104+
if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
105+
else {
106+
if((hz|lz)==0) /* return sign(x)*0 */
107+
return Zero[(unsigned)sx>>31];
108+
hx = hz+hz+(lz>>31); lx = lz+lz;
109+
}
110+
}
111+
hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
112+
if(hz>=0) {hx=hz;lx=lz;}
113+
114+
/* convert back to floating value and restore the sign */
115+
if((hx|lx)==0) /* return sign(x)*0 */
116+
return Zero[(unsigned)sx>>31];
117+
while(hx<0x00100000) { /* normalize x */
118+
hx = hx+hx+(lx>>31); lx = lx+lx;
119+
iy -= 1;
120+
}
121+
if(iy>= -1022) { /* normalize output */
122+
hx = ((hx-0x00100000)|((iy+1023)<<20));
123+
__HI(x) = hx|sx;
124+
__LO(x) = lx;
125+
} else { /* subnormal output */
126+
n = -1022 - iy;
127+
if(n<=20) {
128+
lx = (lx>>n)|((unsigned)hx<<(32-n));
129+
hx >>= n;
130+
} else if (n<=31) {
131+
lx = (hx<<(32-n))|(lx>>n); hx = sx;
132+
} else {
133+
lx = hx>>(n-32); hx = sx;
134+
}
135+
__HI(x) = hx|sx;
136+
__LO(x) = lx;
137+
x *= one; /* create necessary signal */
138+
}
139+
return x; /* exact output */
140+
}

third-party/fdlibm/include/fdlibm-math.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,6 @@ extern EXTERN_C double floor(double);
7575

7676
// Other functions
7777
extern EXTERN_C double fabs(double);
78+
extern EXTERN_C double fmod(double, double);
7879

7980
#endif /* !JERRY_FDLIBM_MATH_H */

third-party/fdlibm/w_fmod.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
/* @(#)w_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+
/*
15+
* wrapper fmod(x,y)
16+
*/
17+
18+
#include "fdlibm.h"
19+
20+
21+
#ifdef __STDC__
22+
double fmod(double x, double y) /* wrapper fmod */
23+
#else
24+
double fmod(x,y) /* wrapper fmod */
25+
double x,y;
26+
#endif
27+
{
28+
#ifdef _IEEE_LIBM
29+
return __ieee754_fmod(x,y);
30+
#else
31+
double z;
32+
z = __ieee754_fmod(x,y);
33+
if(_LIB_VERSION == _IEEE_ ||isnan(y)||isnan(x)) return z;
34+
if(y==0.0) {
35+
return __kernel_standard(x,y,27); /* fmod(x,0) */
36+
} else
37+
return z;
38+
#endif
39+
}

0 commit comments

Comments
 (0)