ReactOS 0.4.15-dev-7934-g1dc8d80
remainderf.c File Reference
#include "libm.h"
#include "libm_util.h"
#include "libm_inlines.h"
#include "libm_errno.h"
Include dependency graph for remainderf.c:

Go to the source code of this file.

Macros

#define USE_NANF_WITH_FLAGS
 
#define USE_SCALEDOUBLE_1
 
#define USE_GET_FPSW_INLINE
 
#define USE_SET_FPSW_INLINE
 
#define USE_HANDLE_ERRORF
 
#define _CRTBLD_C9X
 
#define _FUNCNAME   "remainderf"
 
#define _OPERATION   OP_REM
 

Functions

float remainderf (float x, float y)
 

Macro Definition Documentation

◆ _CRTBLD_C9X

#define _CRTBLD_C9X

Definition at line 43 of file remainderf.c.

◆ _FUNCNAME

#define _FUNCNAME   "remainderf"

◆ _OPERATION

#define _OPERATION   OP_REM

◆ USE_GET_FPSW_INLINE

#define USE_GET_FPSW_INLINE

Definition at line 32 of file remainderf.c.

◆ USE_HANDLE_ERRORF

#define USE_HANDLE_ERRORF

Definition at line 34 of file remainderf.c.

◆ USE_NANF_WITH_FLAGS

#define USE_NANF_WITH_FLAGS

Definition at line 30 of file remainderf.c.

◆ USE_SCALEDOUBLE_1

#define USE_SCALEDOUBLE_1

Definition at line 31 of file remainderf.c.

◆ USE_SET_FPSW_INLINE

#define USE_SET_FPSW_INLINE

Definition at line 33 of file remainderf.c.

Function Documentation

◆ remainderf()

float remainderf ( float  x,
float  y 
)

Definition at line 60 of file remainderf.c.

64{
65 double dx, dy, scale, w, t;
66 int i, ntimes, xexp, yexp;
67 unsigned long long ux, uy, ax, ay;
68
69 unsigned int sw;
70
71 dx = x;
72 dy = y;
73
74
75 GET_BITS_DP64(dx, ux);
76 GET_BITS_DP64(dy, uy);
77 ax = ux & ~SIGNBIT_DP64;
78 ay = uy & ~SIGNBIT_DP64;
79 xexp = (int)((ux & EXPBITS_DP64) >> EXPSHIFTBITS_DP64);
80 yexp = (int)((uy & EXPBITS_DP64) >> EXPSHIFTBITS_DP64);
81
82 if (xexp < 1 || xexp > BIASEDEMAX_DP64 ||
83 yexp < 1 || yexp > BIASEDEMAX_DP64)
84 {
85 /* x or y is zero, NaN or infinity (neither x nor y can be
86 denormalized because we promoted from float to double) */
87 if (xexp > BIASEDEMAX_DP64)
88 {
89 /* x is NaN or infinity */
90 if (ux & MANTBITS_DP64)
91 {
92 /* x is NaN */
93 unsigned int ufx;
94 GET_BITS_SP32(x, ufx);
95 return _handle_errorf(_FUNCNAME, _OPERATION, ufx|0x00400000, _DOMAIN, 0,
96 EDOM, x, y, 2);
97 }
98 else
99 {
100 /* x is infinity; result is NaN */
102 AMD_F_INVALID, EDOM, x, y, 2);
103 }
104 }
105 else if (yexp > BIASEDEMAX_DP64)
106 {
107 /* y is NaN or infinity */
108 if (uy & MANTBITS_DP64)
109 {
110 /* y is NaN */
111 unsigned int ufy;
112 GET_BITS_SP32(y, ufy);
113 return _handle_errorf(_FUNCNAME, _OPERATION, ufy|0x00400000, _DOMAIN, 0,
114 EDOM, x, y, 2);
115 }
116 else
117 {
118#ifdef _CRTBLD_C9X
119 /* C99 return for y = +-inf is x */
120 return x;
121#else
122 /* y is infinity; result is indefinite */
124 AMD_F_INVALID, EDOM, x, y, 2);
125#endif
126 }
127 }
128 else if (xexp < 1)
129 {
130 /* x must be zero (cannot be denormalized) */
131 if (yexp < 1)
132 {
133 /* y must be zero (cannot be denormalized) */
135 AMD_F_INVALID, EDOM, x, y, 2);
136 }
137 else
138 /* C99 return for x = 0 must preserve sign */
139 return x;
140 }
141 else
142 {
143 /* y must be zero */
145 AMD_F_INVALID, EDOM, x, y, 2);
146 }
147 }
148 else if (ax == ay)
149 {
150 /* abs(x) == abs(y); return zero with the sign of x */
152 return (float)dx;
153 }
154
155 /* Set dx = abs(x), dy = abs(y) */
157 PUT_BITS_DP64(ay, dy);
158
159 if (ax < ay)
160 {
161 /* abs(x) < abs(y) */
162#if !defined(COMPILING_FMOD)
163 if (dx > 0.5*dy)
164 dx -= dy;
165#endif
166 return (float)(x < 0.0? -dx : dx);
167 }
168
169 /* Save the current floating-point status word. We need
170 to do this because the remainder function is always
171 exact for finite arguments, but our algorithm causes
172 the inexact flag to be raised. We therefore need to
173 restore the entry status before exiting. */
174 sw = get_fpsw_inline();
175
176 /* Set ntimes to the number of times we need to do a
177 partial remainder. If the exponent of x is an exact multiple
178 of 24 larger than the exponent of y, and the mantissa of x is
179 less than the mantissa of y, ntimes will be one too large
180 but it doesn't matter - it just means that we'll go round
181 the loop below one extra time. */
182 if (xexp <= yexp)
183 {
184 ntimes = 0;
185 w = dy;
186 scale = 1.0;
187 }
188 else
189 {
190 ntimes = (xexp - yexp) / 24;
191
192 /* Set w = y * 2^(24*ntimes) */
193 PUT_BITS_DP64((unsigned long long)(ntimes * 24 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64,
194 scale);
195 w = scale * dy;
196 /* Set scale = 2^(-24) */
197 PUT_BITS_DP64((unsigned long long)(-24 + EXPBIAS_DP64) << EXPSHIFTBITS_DP64,
198 scale);
199 }
200
201
202 /* Each time round the loop we compute a partial remainder.
203 This is done by subtracting a large multiple of w
204 from x each time, where w is a scaled up version of y.
205 The subtraction can be performed exactly when performed
206 in double precision, and the result at each stage can
207 fit exactly in a single precision number. */
208 for (i = 0; i < ntimes; i++)
209 {
210 /* t is the integer multiple of w that we will subtract.
211 We use a truncated value for t. */
212 t = (double)((int)(dx / w));
213 dx -= w * t;
214 /* Scale w down by 2^(-24) for the next iteration */
215 w *= scale;
216 }
217
218 /* One more time */
219#if defined(COMPILING_FMOD)
220 t = (double)((int)(dx / w));
221 dx -= w * t;
222#else
223 {
224 unsigned int todd;
225 /* Variable todd says whether the integer t is odd or not */
226 t = (double)((int)(dx / w));
227 todd = ((int)(dx / w)) & 1;
228 dx -= w * t;
229
230 /* At this point, dx lies in the range [0,dy) */
231 /* For the remainder function, we need to adjust dx
232 so that it lies in the range (-y/2, y/2] by carefully
233 subtracting w (== dy == y) if necessary. */
234 if (dx > 0.5 * w || ((dx == 0.5 * w) && todd))
235 dx -= w;
236 }
237#endif
238
239 /* **** N.B. for some reason this breaks the 32 bit version
240 of remainder when compiling with optimization. */
241 /* Restore the entry status flags */
242 set_fpsw_inline(sw);
243
244 /* Set the result sign according to input argument x */
245 return (float)(x < 0.0? -dx : dx);
246
247}
float __cdecl _handle_errorf(char *fname, int opcode, unsigned long long value, int type, int flags, int error, float arg1, float arg2, int nargs)
Definition: _handle_error.c:56
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define EDOM
Definition: errno.h:39
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLdouble GLdouble t
Definition: gl.h:2047
GLenum GLenum GLenum GLenum GLenum scale
Definition: glext.h:9032
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define _DOMAIN
Definition: math.h:39
#define AMD_F_INVALID
Definition: libm_new.h:86
#define INDEFBITPATT_SP32
Definition: libm_util.h:76
#define GET_BITS_SP32(x, ux)
Definition: libm_util.h:105
#define EXPSHIFTBITS_DP64
Definition: libm_util.h:56
#define GET_BITS_DP64(x, ux)
Definition: libm_util.h:118
#define BIASEDEMAX_DP64
Definition: libm_util.h:59
#define SIGNBIT_DP64
Definition: libm_util.h:44
#define EXPBITS_DP64
Definition: libm_util.h:45
#define EXPBIAS_DP64
Definition: libm_util.h:55
#define MANTBITS_DP64
Definition: libm_util.h:46
#define PUT_BITS_DP64(ux, x)
Definition: libm_util.h:124
GLint dy
Definition: linetemp.h:97
GLint dx
Definition: linetemp.h:97
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
#define _FUNCNAME
#define _OPERATION
ecx edi movl ebx edx edi decl ecx esi eax jecxz decl eax andl eax esi movl edx movl TEMP incl eax andl eax ecx incl ebx testl eax jnz xchgl ecx incl TEMP esp ecx subl ebx pushl ecx ecx edx ecx shrl ecx mm0 mm4 mm0 mm4 mm1 mm5 mm1 mm5 mm2 mm6 mm2 mm6 mm3 mm7 mm3 mm7 paddd mm0 paddd mm4 paddd mm0 paddd mm4 paddd mm0 paddd mm4 movq mm1 movq mm5 psrlq mm1 psrlq mm5 paddd mm0 paddd mm4 psrad mm0 psrad mm4 packssdw mm0 packssdw mm4 mm1 punpckldq mm0 pand mm1 pand mm0 por mm1 movq edi esi edx edi decl ecx jnz popl ecx andl ecx jecxz mm0 mm0 mm1 mm1 mm2 mm2 mm3 mm3 paddd mm0 paddd mm0 paddd mm0 movq mm1 psrlq mm1 paddd mm0 psrad mm0 packssdw mm0 movd eax movw ax
Definition: synth_sse3d.h:180