1 /*
2  * This file is part of the MicroPython project, http://micropython.org/
3  *
4  * These math functions are taken from newlib-nano-2, the newlib/libm/common
5  * directory, available from https://github.com/32bitmicro/newlib-nano-2.
6  *
7  * Appropriate copyright headers are reproduced below.
8  */
9 
10 /* sf_modf.c -- float version of s_modf.c.
11  * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
12  */
13 
14 /*
15  * ====================================================
16  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
17  *
18  * Developed at SunPro, a Sun Microsystems, Inc. business.
19  * Permission to use, copy, modify, and distribute this
20  * software is freely granted, provided that this notice
21  * is preserved.
22  * ====================================================
23  */
24 
25 #include "fdlibm.h"
26 
27 #ifdef __STDC__
28 static const float one = 1.0f;
29 #else
30 static float one = 1.0f;
31 #endif
32 
33 #ifdef __STDC__
modff(float x,float * iptr)34 	float modff(float x, float *iptr)
35 #else
36 	float modff(x, iptr)
37 	float x,*iptr;
38 #endif
39 {
40 	__int32_t i0,j0;
41 	__uint32_t i;
42 	GET_FLOAT_WORD(i0,x);
43 	j0 = ((i0>>23)&0xff)-0x7f;	/* exponent of x */
44 	if(j0<23) {			/* integer part in x */
45 	    if(j0<0) {			/* |x|<1 */
46 	        SET_FLOAT_WORD(*iptr,i0&0x80000000);	/* *iptr = +-0 */
47 		return x;
48 	    } else {
49 		i = (0x007fffff)>>j0;
50 		if((i0&i)==0) {			/* x is integral */
51 		    __uint32_t ix;
52 		    *iptr = x;
53 		    GET_FLOAT_WORD(ix,x);
54 		    SET_FLOAT_WORD(x,ix&0x80000000);	/* return +-0 */
55 		    return x;
56 		} else {
57 		    SET_FLOAT_WORD(*iptr,i0&(~i));
58 		    return x - *iptr;
59 		}
60 	    }
61 	} else {			/* no fraction part */
62 	    __uint32_t ix;
63 	    *iptr = x*one;
64 	    GET_FLOAT_WORD(ix,x);
65 	    SET_FLOAT_WORD(x,ix&0x80000000);	/* return +-0 */
66 	    return x;
67 	}
68 }
69 
70 #ifdef _DOUBLE_IS_32BITS
71 
72 #ifdef __STDC__
modf(double x,double * iptr)73 	double modf(double x, double *iptr)
74 #else
75 	double modf(x, iptr)
76 	double x,*iptr;
77 #endif
78 {
79 	return (double) modff((float) x, (float *) iptr);
80 }
81 
82 #endif /* defined(_DOUBLE_IS_32BITS) */
83