Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/native/libfdlibm/e_fmod.c
41149 views
1
/*
2
* Copyright (c) 1998, 2001, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
/*
27
* __ieee754_fmod(x,y)
28
* Return x mod y in exact arithmetic
29
* Method: shift and subtract
30
*/
31
32
#include "fdlibm.h"
33
34
#ifdef __STDC__
35
static const double one = 1.0, Zero[] = {0.0, -0.0,};
36
#else
37
static double one = 1.0, Zero[] = {0.0, -0.0,};
38
#endif
39
40
#ifdef __STDC__
41
double __ieee754_fmod(double x, double y)
42
#else
43
double __ieee754_fmod(x,y)
44
double x,y ;
45
#endif
46
{
47
int n,hx,hy,hz,ix,iy,sx,i;
48
unsigned lx,ly,lz;
49
50
hx = __HI(x); /* high word of x */
51
lx = __LO(x); /* low word of x */
52
hy = __HI(y); /* high word of y */
53
ly = __LO(y); /* low word of y */
54
sx = hx&0x80000000; /* sign of x */
55
hx ^=sx; /* |x| */
56
hy &= 0x7fffffff; /* |y| */
57
58
/* purge off exception values */
59
if((hy|ly)==0||(hx>=0x7ff00000)|| /* y=0,or x not finite */
60
((hy|((ly|-ly)>>31))>0x7ff00000)) /* or y is NaN */
61
return (x*y)/(x*y);
62
if(hx<=hy) {
63
if((hx<hy)||(lx<ly)) return x; /* |x|<|y| return x */
64
if(lx==ly)
65
return Zero[(unsigned)sx>>31]; /* |x|=|y| return x*0*/
66
}
67
68
/* determine ix = ilogb(x) */
69
if(hx<0x00100000) { /* subnormal x */
70
if(hx==0) {
71
for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
72
} else {
73
for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
74
}
75
} else ix = (hx>>20)-1023;
76
77
/* determine iy = ilogb(y) */
78
if(hy<0x00100000) { /* subnormal y */
79
if(hy==0) {
80
for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
81
} else {
82
for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
83
}
84
} else iy = (hy>>20)-1023;
85
86
/* set up {hx,lx}, {hy,ly} and align y to x */
87
if(ix >= -1022)
88
hx = 0x00100000|(0x000fffff&hx);
89
else { /* subnormal x, shift x to normal */
90
n = -1022-ix;
91
if(n<=31) {
92
hx = (hx<<n)|(lx>>(32-n));
93
lx <<= n;
94
} else {
95
hx = lx<<(n-32);
96
lx = 0;
97
}
98
}
99
if(iy >= -1022)
100
hy = 0x00100000|(0x000fffff&hy);
101
else { /* subnormal y, shift y to normal */
102
n = -1022-iy;
103
if(n<=31) {
104
hy = (hy<<n)|(ly>>(32-n));
105
ly <<= n;
106
} else {
107
hy = ly<<(n-32);
108
ly = 0;
109
}
110
}
111
112
/* fix point fmod */
113
n = ix - iy;
114
while(n--) {
115
hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
116
if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
117
else {
118
if((hz|lz)==0) /* return sign(x)*0 */
119
return Zero[(unsigned)sx>>31];
120
hx = hz+hz+(lz>>31); lx = lz+lz;
121
}
122
}
123
hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
124
if(hz>=0) {hx=hz;lx=lz;}
125
126
/* convert back to floating value and restore the sign */
127
if((hx|lx)==0) /* return sign(x)*0 */
128
return Zero[(unsigned)sx>>31];
129
while(hx<0x00100000) { /* normalize x */
130
hx = hx+hx+(lx>>31); lx = lx+lx;
131
iy -= 1;
132
}
133
if(iy>= -1022) { /* normalize output */
134
hx = ((hx-0x00100000)|((iy+1023)<<20));
135
__HI(x) = hx|sx;
136
__LO(x) = lx;
137
} else { /* subnormal output */
138
n = -1022 - iy;
139
if(n<=20) {
140
lx = (lx>>n)|((unsigned)hx<<(32-n));
141
hx >>= n;
142
} else if (n<=31) {
143
lx = (hx<<(32-n))|(lx>>n); hx = sx;
144
} else {
145
lx = hx>>(n-32); hx = sx;
146
}
147
__HI(x) = hx|sx;
148
__LO(x) = lx;
149
x *= one; /* create necessary signal */
150
}
151
return x; /* exact output */
152
}
153
154