xref: /netbsd/lib/libm/src/s_truncf.c (revision 98e7e8e9)
1f1336fbdSxtraeme /* @(#)s_floor.c 5.1 93/09/24 */
2f1336fbdSxtraeme /*
3f1336fbdSxtraeme  * ====================================================
4f1336fbdSxtraeme  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5f1336fbdSxtraeme  *
6f1336fbdSxtraeme  * Developed at SunPro, a Sun Microsystems, Inc. business.
7f1336fbdSxtraeme  * Permission to use, copy, modify, and distribute this
8f1336fbdSxtraeme  * software is freely granted, provided that this notice
9f1336fbdSxtraeme  * is preserved.
10f1336fbdSxtraeme  * ====================================================
11f1336fbdSxtraeme  */
12f1336fbdSxtraeme 
13f1336fbdSxtraeme #include <sys/cdefs.h>
1455ac93d3Shubertf #if 0
15f1336fbdSxtraeme __FBSDID("$FreeBSD: src/lib/msun/src/s_truncf.c,v 1.1 2004/06/20 09:25:43 das Exp $");
16f1336fbdSxtraeme #endif
173e96ddc1Sxtraeme #if defined(LIBM_SCCS) && !defined(lint)
18*98e7e8e9Schristos __RCSID("$NetBSD: s_truncf.c,v 1.4 2008/04/25 22:21:53 christos Exp $");
193e96ddc1Sxtraeme #endif
20f1336fbdSxtraeme 
21f1336fbdSxtraeme /*
22f1336fbdSxtraeme  * truncf(x)
23f1336fbdSxtraeme  * Return x rounded toward 0 to integral value
24f1336fbdSxtraeme  * Method:
25f1336fbdSxtraeme  *	Bit twiddling.
26f1336fbdSxtraeme  * Exception:
27f1336fbdSxtraeme  *	Inexact flag raised if x not equal to truncf(x).
28f1336fbdSxtraeme  */
29f1336fbdSxtraeme 
30f1336fbdSxtraeme #include "math.h"
31f1336fbdSxtraeme #include "math_private.h"
32f1336fbdSxtraeme 
33f1336fbdSxtraeme static const float huge = 1.0e30F;
34f1336fbdSxtraeme 
35f1336fbdSxtraeme float
truncf(float x)36f1336fbdSxtraeme truncf(float x)
37f1336fbdSxtraeme {
38*98e7e8e9Schristos 	int32_t i0,jj0;
393e96ddc1Sxtraeme 	uint32_t i;
40f1336fbdSxtraeme 	GET_FLOAT_WORD(i0,x);
41*98e7e8e9Schristos 	jj0 = ((i0>>23)&0xff)-0x7f;
42*98e7e8e9Schristos 	if(jj0<23) {
43*98e7e8e9Schristos 	    if(jj0<0) { 	/* raise inexact if x != 0 */
44f1336fbdSxtraeme 		if(huge+x>0.0F)		/* |x|<1, so return 0*sign(x) */
45f1336fbdSxtraeme 		    i0 &= 0x80000000;
46f1336fbdSxtraeme 	    } else {
47*98e7e8e9Schristos 		i = (0x007fffff)>>jj0;
48f1336fbdSxtraeme 		if((i0&i)==0) return x; /* x is integral */
49f1336fbdSxtraeme 		if(huge+x>0.0F)		/* raise inexact flag */
50f1336fbdSxtraeme 		    i0 &= (~i);
51f1336fbdSxtraeme 	    }
52f1336fbdSxtraeme 	} else {
53*98e7e8e9Schristos 	    if(jj0==0x80) return x+x;	/* inf or NaN */
54f1336fbdSxtraeme 	    else return x;		/* x is integral */
55f1336fbdSxtraeme 	}
56f1336fbdSxtraeme 	SET_FLOAT_WORD(x,i0);
57f1336fbdSxtraeme 	return x;
58f1336fbdSxtraeme }
59