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