1130767Sdas/* @(#)s_floor.c 5.1 93/09/24 */ 2130767Sdas/* 3130767Sdas * ==================================================== 4130767Sdas * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 5130767Sdas * 6130767Sdas * Developed at SunPro, a Sun Microsystems, Inc. business. 7130767Sdas * Permission to use, copy, modify, and distribute this 8130767Sdas * software is freely granted, provided that this notice 9130767Sdas * is preserved. 10130767Sdas * ==================================================== 11130767Sdas */ 12130767Sdas 13130767Sdas#include <sys/cdefs.h> 14130767Sdas__FBSDID("$FreeBSD$"); 15130767Sdas 16130767Sdas/* 17130767Sdas * trunc(x) 18130767Sdas * Return x rounded toward 0 to integral value 19130767Sdas * Method: 20130767Sdas * Bit twiddling. 21130767Sdas * Exception: 22130767Sdas * Inexact flag raised if x not equal to trunc(x). 23130767Sdas */ 24130767Sdas 25176305Sbde#include <float.h> 26176305Sbde 27130767Sdas#include "math.h" 28130767Sdas#include "math_private.h" 29130767Sdas 30130767Sdasstatic const double huge = 1.0e300; 31130767Sdas 32130767Sdasdouble 33130767Sdastrunc(double x) 34130767Sdas{ 35130767Sdas int32_t i0,i1,j0; 36176450Sdas u_int32_t i; 37130767Sdas EXTRACT_WORDS(i0,i1,x); 38130767Sdas j0 = ((i0>>20)&0x7ff)-0x3ff; 39130767Sdas if(j0<20) { 40130767Sdas if(j0<0) { /* raise inexact if x != 0 */ 41130767Sdas if(huge+x>0.0) {/* |x|<1, so return 0*sign(x) */ 42130767Sdas i0 &= 0x80000000U; 43130767Sdas i1 = 0; 44130767Sdas } 45130767Sdas } else { 46130767Sdas i = (0x000fffff)>>j0; 47130767Sdas if(((i0&i)|i1)==0) return x; /* x is integral */ 48130767Sdas if(huge+x>0.0) { /* raise inexact flag */ 49130767Sdas i0 &= (~i); i1=0; 50130767Sdas } 51130767Sdas } 52130767Sdas } else if (j0>51) { 53130767Sdas if(j0==0x400) return x+x; /* inf or NaN */ 54130767Sdas else return x; /* x is integral */ 55130767Sdas } else { 56130767Sdas i = ((u_int32_t)(0xffffffff))>>(j0-20); 57130767Sdas if((i1&i)==0) return x; /* x is integral */ 58130767Sdas if(huge+x>0.0) /* raise inexact flag */ 59130767Sdas i1 &= (~i); 60130767Sdas } 61130767Sdas INSERT_WORDS(x,i0,i1); 62130767Sdas return x; 63130767Sdas} 64176280Sbde 65176280Sbde#if LDBL_MANT_DIG == 53 66176280Sbde__weak_reference(trunc, truncl); 67176280Sbde#endif 68