11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* @(#)s_ceil.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 13a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#include <sys/cdefs.h> 14a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes__FBSDID("$FreeBSD$"); 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ceil(x) 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Return x rounded toward -inf to integral value 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Method: 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Bit twiddling. 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Exception: 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Inexact flag raised if x not equal to ceil(x). 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 25a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#include <float.h> 26a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math.h" 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "math_private.h" 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const double huge = 1.0e300; 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdouble 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectceil(double x) 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int32_t i0,i1,j0; 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project u_int32_t i,j; 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project EXTRACT_WORDS(i0,i1,x); 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project j0 = ((i0>>20)&0x7ff)-0x3ff; 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(j0<20) { 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(j0<0) { /* raise inexact if x != 0 */ 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if(i0<0) {i0=0x80000000;i1=0;} 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if((i0|i1)!=0) { i0=0x3ff00000;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} 74a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes 75a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#if LDBL_MANT_DIG == 53 76a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes__weak_reference(ceil, ceill); 77a0ee07829a9ba7e99ef68e8c12551301cc797f0fElliott Hughes#endif 78