LCOV - code coverage report
Current view: top level - fdlibm - e_fmod.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 66 0.0 %
Date: 2017-07-14 10:03:36 Functions: 0 1 0.0 %

          Line data    Source code
       1             : 
       2             : /* @(#)e_fmod.c 1.3 95/01/18 */
       3             : /*
       4             :  * ====================================================
       5             :  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
       6             :  *
       7             :  * Developed at SunSoft, a Sun Microsystems, Inc. business.
       8             :  * Permission to use, copy, modify, and distribute this
       9             :  * software is freely granted, provided that this notice 
      10             :  * is preserved.
      11             :  * ====================================================
      12             :  */
      13             : 
      14             : /* 
      15             :  * __ieee754_fmod(x,y)
      16             :  * Return x mod y in exact arithmetic
      17             :  * Method: shift and subtract
      18             :  */
      19             : 
      20             : #include "fdlibm.h"
      21             : 
      22             : #ifndef _DOUBLE_IS_32BITS
      23             : 
      24             : #ifdef __STDC__
      25             : static const double one = 1.0, Zero[] = {0.0, -0.0,};
      26             : #else
      27             : static double one = 1.0, Zero[] = {0.0, -0.0,};
      28             : #endif
      29             : 
      30             : #ifdef __STDC__
      31           0 :         double __ieee754_fmod(double x, double y)
      32             : #else
      33             :         double __ieee754_fmod(x,y)
      34             :         double x,y ;
      35             : #endif
      36             : {
      37             :         int32_t n,hx,hy,hz,ix,iy,sx,i;
      38             :         uint32_t lx,ly,lz;
      39             : 
      40           0 :         EXTRACT_WORDS(hx,lx,x);
      41           0 :         EXTRACT_WORDS(hy,ly,y);
      42           0 :         sx = hx&0x80000000;         /* sign of x */
      43           0 :         hx ^=sx;                /* |x| */
      44           0 :         hy &= 0x7fffffff;   /* |y| */
      45             : 
      46             :     /* purge off exception values */
      47           0 :         if((hy|ly)==0||(hx>=0x7ff00000)||    /* y=0,or x not finite */
      48           0 :           ((hy|((ly|-ly)>>31))>0x7ff00000))    /* or y is NaN */
      49           0 :             return (x*y)/(x*y);
      50           0 :         if(hx<=hy) {
      51           0 :             if((hx<hy)||(lx<ly)) return x;        /* |x|<|y| return x */
      52           0 :             if(lx==ly) 
      53           0 :                 return Zero[(uint32_t)sx>>31];    /* |x|=|y| return x*0*/
      54             :         }
      55             : 
      56             :     /* determine ix = ilogb(x) */
      57           0 :         if(hx<0x00100000) {  /* subnormal x */
      58           0 :             if(hx==0) {
      59           0 :                 for (ix = -1043, i=lx; i>0; i<<=1) ix -=1;
      60             :             } else {
      61           0 :                 for (ix = -1022,i=(hx<<11); i>0; i<<=1) ix -=1;
      62             :             }
      63           0 :         } else ix = (hx>>20)-1023;
      64             : 
      65             :     /* determine iy = ilogb(y) */
      66           0 :         if(hy<0x00100000) {  /* subnormal y */
      67           0 :             if(hy==0) {
      68           0 :                 for (iy = -1043, i=ly; i>0; i<<=1) iy -=1;
      69             :             } else {
      70           0 :                 for (iy = -1022,i=(hy<<11); i>0; i<<=1) iy -=1;
      71             :             }
      72           0 :         } else iy = (hy>>20)-1023;
      73             : 
      74             :     /* set up {hx,lx}, {hy,ly} and align y to x */
      75           0 :         if(ix >= -1022) 
      76           0 :             hx = 0x00100000|(0x000fffff&hx);
      77             :         else {          /* subnormal x, shift x to normal */
      78           0 :             n = -1022-ix;
      79           0 :             if(n<=31) {
      80           0 :                 hx = (hx<<n)|(lx>>(32-n));
      81           0 :                 lx <<= n;
      82             :             } else {
      83           0 :                 hx = lx<<(n-32);
      84           0 :                 lx = 0;
      85             :             }
      86             :         }
      87           0 :         if(iy >= -1022) 
      88           0 :             hy = 0x00100000|(0x000fffff&hy);
      89             :         else {          /* subnormal y, shift y to normal */
      90           0 :             n = -1022-iy;
      91           0 :             if(n<=31) {
      92           0 :                 hy = (hy<<n)|(ly>>(32-n));
      93           0 :                 ly <<= n;
      94             :             } else {
      95           0 :                 hy = ly<<(n-32);
      96           0 :                 ly = 0;
      97             :             }
      98             :         }
      99             : 
     100             :     /* fix point fmod */
     101           0 :         n = ix - iy;
     102           0 :         while(n--) {
     103           0 :             hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
     104           0 :             if(hz<0){hx = hx+hx+(lx>>31); lx = lx+lx;}
     105             :             else {
     106           0 :                 if((hz|lz)==0)          /* return sign(x)*0 */
     107           0 :                     return Zero[(uint32_t)sx>>31];
     108           0 :                 hx = hz+hz+(lz>>31); lx = lz+lz;
     109             :             }
     110             :         }
     111           0 :         hz=hx-hy;lz=lx-ly; if(lx<ly) hz -= 1;
     112           0 :         if(hz>=0) {hx=hz;lx=lz;}
     113             : 
     114             :     /* convert back to floating value and restore the sign */
     115           0 :         if((hx|lx)==0)                  /* return sign(x)*0 */
     116           0 :             return Zero[(unsigned)sx>>31];        
     117           0 :         while(hx<0x00100000) {               /* normalize x */
     118           0 :             hx = hx+hx+(lx>>31); lx = lx+lx;
     119           0 :             iy -= 1;
     120             :         }
     121           0 :         if(iy>= -1022) {     /* normalize output */
     122           0 :             hx = ((hx-0x00100000)|((iy+1023)<<20));
     123           0 :             INSERT_WORDS(x,hx|sx,lx);
     124             :         } else {                /* subnormal output */
     125           0 :             n = -1022 - iy;
     126           0 :             if(n<=20) {
     127           0 :                 lx = (lx>>n)|((uint32_t)hx<<(32-n));
     128           0 :                 hx >>= n;
     129           0 :             } else if (n<=31) {
     130           0 :                 lx = (hx<<(32-n))|(lx>>n); hx = sx;
     131             :             } else {
     132           0 :                 lx = hx>>(n-32); hx = sx;
     133             :             }
     134           0 :             INSERT_WORDS(x,hx|sx,lx);
     135           0 :             x *= one;           /* create necessary signal */
     136             :         }
     137           0 :         return x;               /* exact output */
     138             : }
     139             : #endif /* defined(_DOUBLE_IS_32BITS) */

Generated by: LCOV version 1.11