11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* @(#)s_floor.c 5.1 93/09/24 */ 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ==================================================== 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Developed at SunPro, a Sun Microsystems, Inc. business. 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * software is freely granted, provided that this notice 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * is preserved. 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ==================================================== 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef lint 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic char rcsid[] = "$FreeBSD: src/lib/msun/src/s_floor.c,v 1.9 2003/07/23 04:53:46 peter Exp $"; 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * floor(x) 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Return x rounded toward -inf to integral value 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Method: 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Bit twiddling. 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Exception: 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Inexact flag raised if x not equal to floor(x). 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math.h" 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math_private.h" 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const double huge = 1.0e300; 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdouble 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectfloor(double x) 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int32_t i0,i1,j0; 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_int32_t i,j; 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXTRACT_WORDS(i0,i1,x); 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project j0 = ((i0>>20)&0x7ff)-0x3ff; 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(j0<20) { 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(j0<0) { /* raise inexact if x != 0 */ 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(i0>=0) {i0=i1=0;} 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if(((i0&0x7fffffff)|i1)!=0) 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project { i0=0xbff00000;i1=0;} 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project i = (0x000fffff)>>j0; 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(((i0&i)|i1)==0) return x; /* x is integral */ 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(huge+x>0.0) { /* raise inexact flag */ 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(i0<0) i0 += (0x00100000)>>j0; 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project i0 &= (~i); i1=0; 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else if (j0>51) { 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(j0==0x400) return x+x; /* inf or NaN */ 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else return x; /* x is integral */ 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } else { 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project i = ((u_int32_t)(0xffffffff))>>(j0-20); 581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if((i1&i)==0) return x; /* x is integral */ 591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(huge+x>0.0) { /* raise inexact flag */ 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(i0<0) { 611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(j0==20) i0+=1; 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else { 631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project j = i1+(1<<(52-j0)); 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(j<i1) i0 +=1 ; /* got a carry */ 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project i1=j; 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project i1 &= (~i); 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project INSERT_WORDS(x,i0,i1); 721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return x; 731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 74