s_floorf.c revision 2117
152284Sobrien/* s_floorf.c -- float version of s_floor.c.
2132718Skan * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
352284Sobrien */
490075Sobrien
552284Sobrien/*
690075Sobrien * ====================================================
790075Sobrien * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
890075Sobrien *
990075Sobrien * Developed at SunPro, a Sun Microsystems, Inc. business.
1052284Sobrien * Permission to use, copy, modify, and distribute this
1190075Sobrien * software is freely granted, provided that this notice
1290075Sobrien * is preserved.
1390075Sobrien * ====================================================
1490075Sobrien */
1552284Sobrien
1652284Sobrien#ifndef lint
1790075Sobrienstatic char rcsid[] = "$Id: s_floorf.c,v 1.2 1994/08/18 23:06:48 jtc Exp $";
18169689Skan#endif
19169689Skan
2052284Sobrien/*
2152284Sobrien * floorf(x)
2252284Sobrien * Return x rounded toward -inf to integral value
23132718Skan * Method:
24132718Skan *	Bit twiddling.
2590075Sobrien * Exception:
2652284Sobrien *	Inexact flag raised if x not equal to floorf(x).
2790075Sobrien */
2852284Sobrien
29132718Skan#include "math.h"
30132718Skan#include "math_private.h"
31132718Skan
3252284Sobrien#ifdef __STDC__
33169689Skanstatic const float huge = 1.0e30;
34169689Skan#else
35169689Skanstatic float huge = 1.0e30;
36169689Skan#endif
3790075Sobrien
3890075Sobrien#ifdef __STDC__
3990075Sobrien	float floorf(float x)
4090075Sobrien#else
4190075Sobrien	float floorf(x)
4290075Sobrien	float x;
4390075Sobrien#endif
4490075Sobrien{
4590075Sobrien	int32_t i0,j0;
4690075Sobrien	u_int32_t i;
4790075Sobrien	GET_FLOAT_WORD(i0,x);
4890075Sobrien	j0 = ((i0>>23)&0xff)-0x7f;
4990075Sobrien	if(j0<23) {
5090075Sobrien	    if(j0<0) { 	/* raise inexact if x != 0 */
5190075Sobrien		if(huge+x>(float)0.0) {/* return 0*sign(x) if |x|<1 */
5290075Sobrien		    if(i0>=0) {i0=0;}
5390075Sobrien		    else if((i0&0x7fffffff)!=0)
5490075Sobrien			{ i0=0xbf800000;}
5590075Sobrien		}
5690075Sobrien	    } else {
5790075Sobrien		i = (0x007fffff)>>j0;
5890075Sobrien		if((i0&i)==0) return x; /* x is integral */
5990075Sobrien		if(huge+x>(float)0.0) {	/* raise inexact flag */
6090075Sobrien		    if(i0<0) i0 += (0x00800000)>>j0;
6190075Sobrien		    i0 &= (~i);
6290075Sobrien		}
6390075Sobrien	    }
64117395Skan	} else {
6590075Sobrien	    if(j0==0x80) return x+x;	/* inf or NaN */
6690075Sobrien	    else return x;		/* x is integral */
6790075Sobrien	}
6890075Sobrien	SET_FLOAT_WORD(x,i0);
6990075Sobrien	return x;
7090075Sobrien}
7190075Sobrien