1*c9945492SAndroid Build Coastguard Worker #include <math.h> 2*c9945492SAndroid Build Coastguard Worker #include <stdint.h> 3*c9945492SAndroid Build Coastguard Worker remquof(float x,float y,int * quo)4*c9945492SAndroid Build Coastguard Workerfloat remquof(float x, float y, int *quo) 5*c9945492SAndroid Build Coastguard Worker { 6*c9945492SAndroid Build Coastguard Worker union {float f; uint32_t i;} ux = {x}, uy = {y}; 7*c9945492SAndroid Build Coastguard Worker int ex = ux.i>>23 & 0xff; 8*c9945492SAndroid Build Coastguard Worker int ey = uy.i>>23 & 0xff; 9*c9945492SAndroid Build Coastguard Worker int sx = ux.i>>31; 10*c9945492SAndroid Build Coastguard Worker int sy = uy.i>>31; 11*c9945492SAndroid Build Coastguard Worker uint32_t q; 12*c9945492SAndroid Build Coastguard Worker uint32_t i; 13*c9945492SAndroid Build Coastguard Worker uint32_t uxi = ux.i; 14*c9945492SAndroid Build Coastguard Worker 15*c9945492SAndroid Build Coastguard Worker *quo = 0; 16*c9945492SAndroid Build Coastguard Worker if (uy.i<<1 == 0 || isnan(y) || ex == 0xff) 17*c9945492SAndroid Build Coastguard Worker return (x*y)/(x*y); 18*c9945492SAndroid Build Coastguard Worker if (ux.i<<1 == 0) 19*c9945492SAndroid Build Coastguard Worker return x; 20*c9945492SAndroid Build Coastguard Worker 21*c9945492SAndroid Build Coastguard Worker /* normalize x and y */ 22*c9945492SAndroid Build Coastguard Worker if (!ex) { 23*c9945492SAndroid Build Coastguard Worker for (i = uxi<<9; i>>31 == 0; ex--, i <<= 1); 24*c9945492SAndroid Build Coastguard Worker uxi <<= -ex + 1; 25*c9945492SAndroid Build Coastguard Worker } else { 26*c9945492SAndroid Build Coastguard Worker uxi &= -1U >> 9; 27*c9945492SAndroid Build Coastguard Worker uxi |= 1U << 23; 28*c9945492SAndroid Build Coastguard Worker } 29*c9945492SAndroid Build Coastguard Worker if (!ey) { 30*c9945492SAndroid Build Coastguard Worker for (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1); 31*c9945492SAndroid Build Coastguard Worker uy.i <<= -ey + 1; 32*c9945492SAndroid Build Coastguard Worker } else { 33*c9945492SAndroid Build Coastguard Worker uy.i &= -1U >> 9; 34*c9945492SAndroid Build Coastguard Worker uy.i |= 1U << 23; 35*c9945492SAndroid Build Coastguard Worker } 36*c9945492SAndroid Build Coastguard Worker 37*c9945492SAndroid Build Coastguard Worker q = 0; 38*c9945492SAndroid Build Coastguard Worker if (ex < ey) { 39*c9945492SAndroid Build Coastguard Worker if (ex+1 == ey) 40*c9945492SAndroid Build Coastguard Worker goto end; 41*c9945492SAndroid Build Coastguard Worker return x; 42*c9945492SAndroid Build Coastguard Worker } 43*c9945492SAndroid Build Coastguard Worker 44*c9945492SAndroid Build Coastguard Worker /* x mod y */ 45*c9945492SAndroid Build Coastguard Worker for (; ex > ey; ex--) { 46*c9945492SAndroid Build Coastguard Worker i = uxi - uy.i; 47*c9945492SAndroid Build Coastguard Worker if (i >> 31 == 0) { 48*c9945492SAndroid Build Coastguard Worker uxi = i; 49*c9945492SAndroid Build Coastguard Worker q++; 50*c9945492SAndroid Build Coastguard Worker } 51*c9945492SAndroid Build Coastguard Worker uxi <<= 1; 52*c9945492SAndroid Build Coastguard Worker q <<= 1; 53*c9945492SAndroid Build Coastguard Worker } 54*c9945492SAndroid Build Coastguard Worker i = uxi - uy.i; 55*c9945492SAndroid Build Coastguard Worker if (i >> 31 == 0) { 56*c9945492SAndroid Build Coastguard Worker uxi = i; 57*c9945492SAndroid Build Coastguard Worker q++; 58*c9945492SAndroid Build Coastguard Worker } 59*c9945492SAndroid Build Coastguard Worker if (uxi == 0) 60*c9945492SAndroid Build Coastguard Worker ex = -30; 61*c9945492SAndroid Build Coastguard Worker else 62*c9945492SAndroid Build Coastguard Worker for (; uxi>>23 == 0; uxi <<= 1, ex--); 63*c9945492SAndroid Build Coastguard Worker end: 64*c9945492SAndroid Build Coastguard Worker /* scale result and decide between |x| and |x|-|y| */ 65*c9945492SAndroid Build Coastguard Worker if (ex > 0) { 66*c9945492SAndroid Build Coastguard Worker uxi -= 1U << 23; 67*c9945492SAndroid Build Coastguard Worker uxi |= (uint32_t)ex << 23; 68*c9945492SAndroid Build Coastguard Worker } else { 69*c9945492SAndroid Build Coastguard Worker uxi >>= -ex + 1; 70*c9945492SAndroid Build Coastguard Worker } 71*c9945492SAndroid Build Coastguard Worker ux.i = uxi; 72*c9945492SAndroid Build Coastguard Worker x = ux.f; 73*c9945492SAndroid Build Coastguard Worker if (sy) 74*c9945492SAndroid Build Coastguard Worker y = -y; 75*c9945492SAndroid Build Coastguard Worker if (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) { 76*c9945492SAndroid Build Coastguard Worker x -= y; 77*c9945492SAndroid Build Coastguard Worker q++; 78*c9945492SAndroid Build Coastguard Worker } 79*c9945492SAndroid Build Coastguard Worker q &= 0x7fffffff; 80*c9945492SAndroid Build Coastguard Worker *quo = sx^sy ? -(int)q : (int)q; 81*c9945492SAndroid Build Coastguard Worker return sx ? -x : x; 82*c9945492SAndroid Build Coastguard Worker } 83