s_trunc.c revision 176280
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: head/lib/msun/src/s_trunc.c 176280 2008-02-14 15:10:34Z bde $"); 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 25130767Sdas#include "math.h" 26130767Sdas#include "math_private.h" 27130767Sdas 28130767Sdasstatic const double huge = 1.0e300; 29130767Sdas 30130767Sdasdouble 31130767Sdastrunc(double x) 32130767Sdas{ 33130767Sdas int32_t i0,i1,j0; 34130767Sdas u_int32_t i,j; 35130767Sdas EXTRACT_WORDS(i0,i1,x); 36130767Sdas j0 = ((i0>>20)&0x7ff)-0x3ff; 37130767Sdas if(j0<20) { 38130767Sdas if(j0<0) { /* raise inexact if x != 0 */ 39130767Sdas if(huge+x>0.0) {/* |x|<1, so return 0*sign(x) */ 40130767Sdas i0 &= 0x80000000U; 41130767Sdas i1 = 0; 42130767Sdas } 43130767Sdas } else { 44130767Sdas i = (0x000fffff)>>j0; 45130767Sdas if(((i0&i)|i1)==0) return x; /* x is integral */ 46130767Sdas if(huge+x>0.0) { /* raise inexact flag */ 47130767Sdas i0 &= (~i); i1=0; 48130767Sdas } 49130767Sdas } 50130767Sdas } else if (j0>51) { 51130767Sdas if(j0==0x400) return x+x; /* inf or NaN */ 52130767Sdas else return x; /* x is integral */ 53130767Sdas } else { 54130767Sdas i = ((u_int32_t)(0xffffffff))>>(j0-20); 55130767Sdas if((i1&i)==0) return x; /* x is integral */ 56130767Sdas if(huge+x>0.0) /* raise inexact flag */ 57130767Sdas i1 &= (~i); 58130767Sdas } 59130767Sdas INSERT_WORDS(x,i0,i1); 60130767Sdas return x; 61130767Sdas} 62176280Sbde 63176280Sbde#if LDBL_MANT_DIG == 53 64176280Sbde__weak_reference(trunc, truncl); 65176280Sbde#endif 66