| 1 |  |  | /* @(#)s_ceil.c 5.1 93/09/24 */ | 
    
    | 2 |  |  | /* | 
    
    | 3 |  |  |  * ==================================================== | 
    
    | 4 |  |  |  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. | 
    
    | 5 |  |  |  * | 
    
    | 6 |  |  |  * Developed at SunPro, a Sun Microsystems, Inc. business. | 
    
    | 7 |  |  |  * Permission to use, copy, modify, and distribute this | 
    
    | 8 |  |  |  * software is freely granted, provided that this notice | 
    
    | 9 |  |  |  * is preserved. | 
    
    | 10 |  |  |  * ==================================================== | 
    
    | 11 |  |  |  */ | 
    
    | 12 |  |  |  | 
    
    | 13 |  |  | /* | 
    
    | 14 |  |  |  * ceill(x) | 
    
    | 15 |  |  |  * Return x rounded toward -inf to integral value | 
    
    | 16 |  |  |  * Method: | 
    
    | 17 |  |  |  *	Bit twiddling. | 
    
    | 18 |  |  |  * Exception: | 
    
    | 19 |  |  |  *	Inexact flag raised if x not equal to ceil(x). | 
    
    | 20 |  |  |  */ | 
    
    | 21 |  |  |  | 
    
    | 22 |  |  | #include <math.h> | 
    
    | 23 |  |  |  | 
    
    | 24 |  |  | #include "math_private.h" | 
    
    | 25 |  |  |  | 
    
    | 26 |  |  | static const long double huge = 1.0e4930L; | 
    
    | 27 |  |  |  | 
    
    | 28 |  |  | long double | 
    
    | 29 |  |  | ceill(long double x) | 
    
    | 30 |  |  | { | 
    
    | 31 |  |  | 	int32_t i1,jj0; | 
    
    | 32 |  |  | 	u_int32_t i,j,se,i0,sx; | 
    
    | 33 |  |  | 	GET_LDOUBLE_WORDS(se,i0,i1,x); | 
    
    | 34 |  |  | 	sx = (se>>15)&1; | 
    
    | 35 |  |  | 	jj0 = (se&0x7fff)-0x3fff; | 
    
    | 36 |  |  | 	if(jj0<31) { | 
    
    | 37 |  |  | 	    if(jj0<0) {	/* raise inexact if x != 0 */ | 
    
    | 38 |  |  | 		if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */ | 
    
    | 39 |  |  | 		    if(sx) {se=0x8000;i0=0;i1=0;} | 
    
    | 40 |  |  | 		    else if((i0|i1)!=0) { se=0x3fff;i0=0x80000000;i1=0;} | 
    
    | 41 |  |  | 		} | 
    
    | 42 |  |  | 	    } else { | 
    
    | 43 |  |  | 		i = (0x7fffffff)>>jj0; | 
    
    | 44 |  |  | 		if(((i0&i)|i1)==0) return x; /* x is integral */ | 
    
    | 45 |  |  | 		if(huge+x>0.0) {	/* raise inexact flag */ | 
    
    | 46 |  |  | 		    if(sx==0) { | 
    
    | 47 |  |  | 			if (jj0>0 && (i0+(0x80000000>>jj0))>i0) | 
    
    | 48 |  |  | 			  i0+=0x80000000>>jj0; | 
    
    | 49 |  |  | 			else | 
    
    | 50 |  |  | 			  { | 
    
    | 51 |  |  | 			    i = 0x7fffffff; | 
    
    | 52 |  |  | 			    ++se; | 
    
    | 53 |  |  | 			  } | 
    
    | 54 |  |  | 		    } | 
    
    | 55 |  |  | 		    i0 &= (~i); i1=0; | 
    
    | 56 |  |  | 		} | 
    
    | 57 |  |  | 	    } | 
    
    | 58 |  |  | 	} else if (jj0>62) { | 
    
    | 59 |  |  | 	    if(jj0==0x4000) return x+x;	/* inf or NaN */ | 
    
    | 60 |  |  | 	    else return x;		/* x is integral */ | 
    
    | 61 |  |  | 	} else { | 
    
    | 62 |  |  | 	    i = ((u_int32_t)(0xffffffff))>>(jj0-31); | 
    
    | 63 |  |  | 	    if((i1&i)==0) return x;	/* x is integral */ | 
    
    | 64 |  |  | 	    if(huge+x>0.0) {		/* raise inexact flag */ | 
    
    | 65 |  |  | 		if(sx==0) { | 
    
    | 66 |  |  | 		    if(jj0==31) i0+=1; | 
    
    | 67 |  |  | 		    else { | 
    
    | 68 |  |  | 			j = i1 + (1<<(63-jj0)); | 
    
    | 69 |  |  | 			if(j<i1) i0+=1;	/* got a carry */ | 
    
    | 70 |  |  | 			i1 = j; | 
    
    | 71 |  |  | 		    } | 
    
    | 72 |  |  | 		} | 
    
    | 73 |  |  | 		i1 &= (~i); | 
    
    | 74 |  |  | 	    } | 
    
    | 75 |  |  | 	} | 
    
    | 76 |  |  | 	SET_LDOUBLE_WORDS(x,se,i0,i1); | 
    
    | 77 |  |  | 	return x; | 
    
    | 78 |  |  | } |