134122Sbostic /* 234122Sbostic * Copyright (c) 1985 Regents of the University of California. 334401Sbostic * All rights reserved. 434401Sbostic * 534401Sbostic * Redistribution and use in source and binary forms are permitted 6*34931Sbostic * provided that the above copyright notice and this paragraph are 7*34931Sbostic * duplicated in all such forms and that any documentation, 8*34931Sbostic * advertising materials, and other materials related to such 9*34931Sbostic * distribution and use acknowledge that the software was developed 10*34931Sbostic * by the University of California, Berkeley. The name of the 11*34931Sbostic * University may not be used to endorse or promote products derived 12*34931Sbostic * from this software without specific prior written permission. 13*34931Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14*34931Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15*34931Sbostic * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 1634401Sbostic * 1734401Sbostic * All recipients should regard themselves as participants in an ongoing 1834401Sbostic * research project and hence should feel obligated to report their 1934401Sbostic * experiences (good or bad) with these elementary function codes, using 2034401Sbostic * the sendbug(8) program, to the authors. 2134122Sbostic */ 2224596Szliu 2334122Sbostic #ifndef lint 24*34931Sbostic static char sccsid[] = "@(#)floor.c 5.4 (Berkeley) 06/30/88"; 2534122Sbostic #endif /* not lint */ 2634122Sbostic 2734401Sbostic #if defined(vax)||defined(tahoe) 2834401Sbostic #ifdef vax 2934401Sbostic #define _0x(A,B) 0x/**/A/**/B 3034401Sbostic #else /* vax */ 3134401Sbostic #define _0x(A,B) 0x/**/B/**/A 3234401Sbostic #endif /* vax */ 3334401Sbostic static long Lx[] = {_0x(0000,5c00),_0x(0000,0000)}; /* 2**55 */ 3434401Sbostic #define L *(double *) Lx 3534401Sbostic #else /* defined(vax)||defined(tahoe) */ 3634401Sbostic static double L = 4503599627370496.0E0; /* 2**52 */ 3734401Sbostic #endif /* defined(vax)||defined(tahoe) */ 3834401Sbostic 3924596Szliu /* 4034401Sbostic * floor(x) := the largest integer no larger than x; 4134401Sbostic * ceil(x) := -floor(-x), for all real x. 4234401Sbostic * 4334401Sbostic * Note: Inexact will be signaled if x is not an integer, as is 4434401Sbostic * customary for IEEE 754. No other signal can be emitted. 4524596Szliu */ 4624596Szliu double 4734401Sbostic floor(x) 4834401Sbostic double x; 4924596Szliu { 5034401Sbostic double y,ceil(); 5124596Szliu 5234401Sbostic if ( 5334401Sbostic #if !defined(vax)&&!defined(tahoe) 5434401Sbostic x != x || /* NaN */ 5534401Sbostic #endif /* !defined(vax)&&!defined(tahoe) */ 5634401Sbostic x >= L) /* already an even integer */ 5734401Sbostic return x; 5834401Sbostic else if (x < (double)0) 5934401Sbostic return -ceil(-x); 6034401Sbostic else { /* now 0 <= x < L */ 6134401Sbostic y = L+x; /* destructive store must be forced */ 6234401Sbostic y -= L; /* an integer, and |x-y| < 1 */ 6334401Sbostic return x < y ? y-(double)1 : y; 6434401Sbostic } 6524596Szliu } 6624596Szliu 6724596Szliu double 6834401Sbostic ceil(x) 6934401Sbostic double x; 7024596Szliu { 7134401Sbostic double y,floor(); 7234401Sbostic 7334401Sbostic if ( 7434401Sbostic #if !defined(vax)&&!defined(tahoe) 7534401Sbostic x != x || /* NaN */ 7634401Sbostic #endif /* !defined(vax)&&!defined(tahoe) */ 7734401Sbostic x >= L) /* already an even integer */ 7834401Sbostic return x; 7934401Sbostic else if (x < (double)0) 8034401Sbostic return -floor(-x); 8134401Sbostic else { /* now 0 <= x < L */ 8234401Sbostic y = L+x; /* destructive store must be forced */ 8334401Sbostic y -= L; /* an integer, and |x-y| < 1 */ 8434401Sbostic return x > y ? y+(double)1 : y; 8534401Sbostic } 8624596Szliu } 8724596Szliu 8831853Szliu #ifndef national /* rint() is in ./NATIONAL/support.s */ 8924596Szliu /* 9024596Szliu * algorithm for rint(x) in pseudo-pascal form ... 9124596Szliu * 9224596Szliu * real rint(x): real x; 9324596Szliu * ... delivers integer nearest x in direction of prevailing rounding 9424596Szliu * ... mode 9524596Szliu * const L = (last consecutive integer)/2 9624596Szliu * = 2**55; for VAX D 9724596Szliu * = 2**52; for IEEE 754 Double 9824596Szliu * real s,t; 9924596Szliu * begin 10024596Szliu * if x != x then return x; ... NaN 10124596Szliu * if |x| >= L then return x; ... already an integer 10224596Szliu * s := copysign(L,x); 10324596Szliu * t := x + s; ... = (x+s) rounded to integer 10424596Szliu * return t - s 10524596Szliu * end; 10624596Szliu * 10724596Szliu * Note: Inexact will be signaled if x is not an integer, as is 10824596Szliu * customary for IEEE 754. No other signal can be emitted. 10924596Szliu */ 11024596Szliu double 11124596Szliu rint(x) 11224596Szliu double x; 11324596Szliu { 11424596Szliu double s,t,one = 1.0,copysign(); 11531853Szliu #if !defined(vax)&&!defined(tahoe) 11624596Szliu if (x != x) /* NaN */ 11724596Szliu return (x); 11831853Szliu #endif /* !defined(vax)&&!defined(tahoe) */ 11924596Szliu if (copysign(x,one) >= L) /* already an integer */ 12024596Szliu return (x); 12124596Szliu s = copysign(L,x); 12224596Szliu t = x + s; /* x+s rounded to integer */ 12324596Szliu return (t - s); 12424596Szliu } 12531853Szliu #endif /* not national */ 126