1 /* s_modff.c -- float version of s_modf.c.
2  */
3 
4 /*
5  * ====================================================
6  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
7  *
8  * Developed at SunPro, a Sun Microsystems, Inc. business.
9  * Permission to use, copy, modify, and distribute this
10  * software is freely granted, provided that this notice
11  * is preserved.
12  * ====================================================
13  */
14 
15 #include <math.h>
16 #include <math_private.h>
17 #include <libm-alias-float.h>
18 
19 static const float one = 1.0;
20 
21 float
__modff(float x,float * iptr)22 __modff(float x, float *iptr)
23 {
24 	int32_t i0,j0;
25 	uint32_t i;
26 	GET_FLOAT_WORD(i0,x);
27 	j0 = ((i0>>23)&0xff)-0x7f;	/* exponent of x */
28 	if(__builtin_expect(j0<23, 1)) {		/* integer part in x */
29 	    if(j0<0) {			/* |x|<1 */
30 		SET_FLOAT_WORD(*iptr,i0&0x80000000);	/* *iptr = +-0 */
31 		return x;
32 	    } else {
33 		i = (0x007fffff)>>j0;
34 		if((i0&i)==0) {			/* x is integral */
35 		    uint32_t ix;
36 		    *iptr = x;
37 		    GET_FLOAT_WORD(ix,x);
38 		    SET_FLOAT_WORD(x,ix&0x80000000);	/* return +-0 */
39 		    return x;
40 		} else {
41 		    SET_FLOAT_WORD(*iptr,i0&(~i));
42 		    return x - *iptr;
43 		}
44 	    }
45 	} else {			/* no fraction part */
46 	    *iptr = x*one;
47 	    /* We must handle NaNs separately.  */
48 	    if (j0 == 0x80 && (i0 & 0x7fffff))
49 	      return x*one;
50 	    SET_FLOAT_WORD(x,i0&0x80000000);	/* return +-0 */
51 	    return x;
52 	}
53 }
54 libm_alias_float (__modf, modf)
55