#pragma weak __remquof = remquof
#include "libm.h"
#include "libm_protos.h"
#include <math.h>
extern float fabsf(float);
static const int
is = (int) 0x80000000,
im = 0x007fffff,
ii = 0x7f800000,
iu = 0x00800000;
static const float zero = 0.0F, half = 0.5F;
static float
fmodquof(float x, float y, int *quo) {
float w;
int hx, ix, iy, iz, k, ny, nd, m, sq;
hx = *(int *) &x;
ix = hx & 0x7fffffff;
iy = *(int *) &y;
sq = (iy ^ hx) & is;
iy &= 0x7fffffff;
*quo = 0;
if (ix >= ii || iy > ii || iy == 0) {
w = x * y;
w = w / w;
} else if (ix <= iy) {
if (ix < iy)
w = x;
else {
*quo = 1 + (sq >> 30);
w = zero * x;
}
} else {
ny = iy >> 23;
k = ix >> 23;
if (ny == 0) {
ny = 1;
while (iy < iu) {
ny -= 1;
iy += iy;
}
nd = k - ny;
if (k == 0) {
nd += 1;
while (ix < iu) {
nd -= 1;
ix += ix;
}
} else
ix = iu | (ix & im);
} else {
nd = k - ny;
ix = iu | (ix & im);
iy = iu | (iy & im);
}
m = 0;
k = nd >> 2;
nd -= (k << 2);
while (k--) {
iz = ix - iy;
if (iz >= 0) {
m += 1;
ix = iz + iz;
} else
ix += ix;
m += m;
iz = ix - iy;
if (iz >= 0) {
m += 1;
ix = iz + iz;
} else
ix += ix;
m += m;
iz = ix - iy;
if (iz >= 0) {
m += 1;
ix = iz + iz;
} else
ix += ix;
m += m;
iz = ix - iy;
if (iz >= 0) {
m += 1;
ix = iz + iz;
} else
ix += ix;
m += m;
if (iz == 0) {
iz = (k << 2) + nd;
if (iz < 32)
m <<= iz;
else
m = 0;
m &= 0x7fffffff;
*quo = sq >= 0 ? m : -m;
*(int *) &w = is & hx;
return (w);
}
}
while (nd--) {
iz = ix - iy;
if (iz >= 0) {
m += 1;
ix = iz + iz;
} else
ix += ix;
m += m;
}
iz = ix - iy;
if (iz >= 0) {
m += 1;
ix = iz;
}
m &= 0x7fffffff;
*quo = sq >= 0 ? m : -m;
if (ix == 0) {
*(int *) &w = is & hx;
return (w);
}
while (ix < iu) {
ix += ix;
ny -= 1;
}
while (ix > (iu + iu)) {
ny += 1;
ix >>= 1;
}
if (ny > 0)
*(int *) &w = (is & hx) | (ix & im) | (ny << 23);
else {
k = -ny + 1;
ix >>= k;
*(int *) &w = (is & hx) | ix;
}
}
return (w);
}
float
remquof(float x, float y, int *quo) {
int hx, hy, sx, sq;
float v;
hx = *(int *) &x;
hy = *(int *) &y;
sx = hx & is;
sq = (hx ^ hy) & is;
hx ^= sx;
hy &= 0x7fffffff;
*quo = 0;
if (hx >= ii || hy > ii || hy == 0) {
v = x * y;
return (v / v);
}
y = fabsf(y);
x = fabsf(x);
if (hy <= 0x7f7fffff) {
x = fmodquof(x, y + y, quo);
*quo = ((*quo) & 0x3fffffff) << 1;
}
if (hy < 0x01000000) {
if (x + x > y) {
*quo += 1;
if (x == y)
x = zero;
else
x -= y;
if (x + x >= y) {
x -= y;
*quo += 1;
}
}
} else {
v = half * y;
if (x > v) {
*quo += 1;
if (x == y)
x = zero;
else
x -= y;
if (x >= v) {
x -= y;
*quo += 1;
}
}
}
if (sq != 0)
*quo = -(*quo);
return (sx == 0 ? x : -x);
}