17ffaea80SDavid Schultz /* @(#)s_floor.c 5.1 93/09/24 */ 27ffaea80SDavid Schultz /* 37ffaea80SDavid Schultz * ==================================================== 47ffaea80SDavid Schultz * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 57ffaea80SDavid Schultz * 67ffaea80SDavid Schultz * Developed at SunPro, a Sun Microsystems, Inc. business. 77ffaea80SDavid Schultz * Permission to use, copy, modify, and distribute this 87ffaea80SDavid Schultz * software is freely granted, provided that this notice 97ffaea80SDavid Schultz * is preserved. 107ffaea80SDavid Schultz * ==================================================== 117ffaea80SDavid Schultz */ 127ffaea80SDavid Schultz 137ffaea80SDavid Schultz #include <sys/cdefs.h> 147ffaea80SDavid Schultz __FBSDID("$FreeBSD$"); 157ffaea80SDavid Schultz 167ffaea80SDavid Schultz /* 177ffaea80SDavid Schultz * trunc(x) 187ffaea80SDavid Schultz * Return x rounded toward 0 to integral value 197ffaea80SDavid Schultz * Method: 207ffaea80SDavid Schultz * Bit twiddling. 217ffaea80SDavid Schultz * Exception: 227ffaea80SDavid Schultz * Inexact flag raised if x not equal to trunc(x). 237ffaea80SDavid Schultz */ 247ffaea80SDavid Schultz 2563b4a1f8SBruce Evans #include <float.h> 2663b4a1f8SBruce Evans 277ffaea80SDavid Schultz #include "math.h" 287ffaea80SDavid Schultz #include "math_private.h" 297ffaea80SDavid Schultz 307ffaea80SDavid Schultz static const double huge = 1.0e300; 317ffaea80SDavid Schultz 327ffaea80SDavid Schultz double 337ffaea80SDavid Schultz trunc(double x) 347ffaea80SDavid Schultz { 357ffaea80SDavid Schultz int32_t i0,i1,j0; 367ffaea80SDavid Schultz u_int32_t i,j; 377ffaea80SDavid Schultz EXTRACT_WORDS(i0,i1,x); 387ffaea80SDavid Schultz j0 = ((i0>>20)&0x7ff)-0x3ff; 397ffaea80SDavid Schultz if(j0<20) { 407ffaea80SDavid Schultz if(j0<0) { /* raise inexact if x != 0 */ 417ffaea80SDavid Schultz if(huge+x>0.0) {/* |x|<1, so return 0*sign(x) */ 427ffaea80SDavid Schultz i0 &= 0x80000000U; 437ffaea80SDavid Schultz i1 = 0; 447ffaea80SDavid Schultz } 457ffaea80SDavid Schultz } else { 467ffaea80SDavid Schultz i = (0x000fffff)>>j0; 477ffaea80SDavid Schultz if(((i0&i)|i1)==0) return x; /* x is integral */ 487ffaea80SDavid Schultz if(huge+x>0.0) { /* raise inexact flag */ 497ffaea80SDavid Schultz i0 &= (~i); i1=0; 507ffaea80SDavid Schultz } 517ffaea80SDavid Schultz } 527ffaea80SDavid Schultz } else if (j0>51) { 537ffaea80SDavid Schultz if(j0==0x400) return x+x; /* inf or NaN */ 547ffaea80SDavid Schultz else return x; /* x is integral */ 557ffaea80SDavid Schultz } else { 567ffaea80SDavid Schultz i = ((u_int32_t)(0xffffffff))>>(j0-20); 577ffaea80SDavid Schultz if((i1&i)==0) return x; /* x is integral */ 587ffaea80SDavid Schultz if(huge+x>0.0) /* raise inexact flag */ 597ffaea80SDavid Schultz i1 &= (~i); 607ffaea80SDavid Schultz } 617ffaea80SDavid Schultz INSERT_WORDS(x,i0,i1); 627ffaea80SDavid Schultz return x; 637ffaea80SDavid Schultz } 645014f8deSBruce Evans 655014f8deSBruce Evans #if LDBL_MANT_DIG == 53 665014f8deSBruce Evans __weak_reference(trunc, truncl); 675014f8deSBruce Evans #endif 68