1*37da2899SCharles.Forsyth /* derived from /netlib/fdlibm */ 2*37da2899SCharles.Forsyth 3*37da2899SCharles.Forsyth /* @(#)e_remainder.c 1.3 95/01/18 */ 4*37da2899SCharles.Forsyth /* 5*37da2899SCharles.Forsyth * ==================================================== 6*37da2899SCharles.Forsyth * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 7*37da2899SCharles.Forsyth * 8*37da2899SCharles.Forsyth * Developed at SunSoft, a Sun Microsystems, Inc. business. 9*37da2899SCharles.Forsyth * Permission to use, copy, modify, and distribute this 10*37da2899SCharles.Forsyth * software is freely granted, provided that this notice 11*37da2899SCharles.Forsyth * is preserved. 12*37da2899SCharles.Forsyth * ==================================================== 13*37da2899SCharles.Forsyth */ 14*37da2899SCharles.Forsyth 15*37da2899SCharles.Forsyth /* __ieee754_remainder(x,p) 16*37da2899SCharles.Forsyth * Return : 17*37da2899SCharles.Forsyth * returns x REM p = x - [x/p]*p as if in infinite 18*37da2899SCharles.Forsyth * precise arithmetic, where [x/p] is the (infinite bit) 19*37da2899SCharles.Forsyth * integer nearest x/p (in half way case choose the even one). 20*37da2899SCharles.Forsyth * Method : 21*37da2899SCharles.Forsyth * Based on fmod() return x-[x/p]chopped*p exactlp. 22*37da2899SCharles.Forsyth */ 23*37da2899SCharles.Forsyth 24*37da2899SCharles.Forsyth #include "fdlibm.h" 25*37da2899SCharles.Forsyth 26*37da2899SCharles.Forsyth static const double zero = 0.0; 27*37da2899SCharles.Forsyth 28*37da2899SCharles.Forsyth __ieee754_remainder(double x,double p)29*37da2899SCharles.Forsyth double __ieee754_remainder(double x, double p) 30*37da2899SCharles.Forsyth { 31*37da2899SCharles.Forsyth int hx,hp; 32*37da2899SCharles.Forsyth unsigned sx,lx,lp; 33*37da2899SCharles.Forsyth double p_half; 34*37da2899SCharles.Forsyth 35*37da2899SCharles.Forsyth hx = __HI(x); /* high word of x */ 36*37da2899SCharles.Forsyth lx = __LO(x); /* low word of x */ 37*37da2899SCharles.Forsyth hp = __HI(p); /* high word of p */ 38*37da2899SCharles.Forsyth lp = __LO(p); /* low word of p */ 39*37da2899SCharles.Forsyth sx = hx&0x80000000; 40*37da2899SCharles.Forsyth hp &= 0x7fffffff; 41*37da2899SCharles.Forsyth hx &= 0x7fffffff; 42*37da2899SCharles.Forsyth 43*37da2899SCharles.Forsyth /* purge off exception values */ 44*37da2899SCharles.Forsyth if((hp|lp)==0) return (x*p)/(x*p); /* p = 0 */ 45*37da2899SCharles.Forsyth if((hx>=0x7ff00000)|| /* x not finite */ 46*37da2899SCharles.Forsyth ((hp>=0x7ff00000)&& /* p is NaN */ 47*37da2899SCharles.Forsyth (((hp-0x7ff00000)|lp)!=0))) 48*37da2899SCharles.Forsyth return (x*p)/(x*p); 49*37da2899SCharles.Forsyth 50*37da2899SCharles.Forsyth 51*37da2899SCharles.Forsyth if (hp<=0x7fdfffff) x = __ieee754_fmod(x,p+p); /* now x < 2p */ 52*37da2899SCharles.Forsyth if (((hx-hp)|(lx-lp))==0) return zero*x; 53*37da2899SCharles.Forsyth x = fabs(x); 54*37da2899SCharles.Forsyth p = fabs(p); 55*37da2899SCharles.Forsyth if (hp<0x00200000) { 56*37da2899SCharles.Forsyth if(x+x>p) { 57*37da2899SCharles.Forsyth x-=p; 58*37da2899SCharles.Forsyth if(x+x>=p) x -= p; 59*37da2899SCharles.Forsyth } 60*37da2899SCharles.Forsyth } else { 61*37da2899SCharles.Forsyth p_half = 0.5*p; 62*37da2899SCharles.Forsyth if(x>p_half) { 63*37da2899SCharles.Forsyth x-=p; 64*37da2899SCharles.Forsyth if(x>=p_half) x -= p; 65*37da2899SCharles.Forsyth } 66*37da2899SCharles.Forsyth } 67*37da2899SCharles.Forsyth __HI(x) ^= sx; 68*37da2899SCharles.Forsyth return x; 69*37da2899SCharles.Forsyth } 70