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 634931Sbostic * provided that the above copyright notice and this paragraph are 734931Sbostic * duplicated in all such forms and that any documentation, 834931Sbostic * advertising materials, and other materials related to such 934931Sbostic * distribution and use acknowledge that the software was developed 1034931Sbostic * by the University of California, Berkeley. The name of the 1134931Sbostic * University may not be used to endorse or promote products derived 1234931Sbostic * from this software without specific prior written permission. 1334931Sbostic * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 1434931Sbostic * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 1534931Sbostic * 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*35679Sbostic static char sccsid[] = "@(#)floor.c 5.5 (Berkeley) 09/22/88"; 2534122Sbostic #endif /* not lint */ 2634122Sbostic 27*35679Sbostic #include "mathimpl.h" 2834401Sbostic 29*35679Sbostic vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */ 30*35679Sbostic 31*35679Sbostic ic(L, 4503599627370496.0E0, 52, 1.0) /* 2**52 */ 32*35679Sbostic 33*35679Sbostic #ifdef vccast 34*35679Sbostic #define L vccast(L) 35*35679Sbostic #endif 36*35679Sbostic 37*35679Sbostic 38*35679Sbostic double ceil(); 39*35679Sbostic double floor(); 40*35679Sbostic 4124596Szliu /* 4234401Sbostic * floor(x) := the largest integer no larger than x; 4334401Sbostic * ceil(x) := -floor(-x), for all real x. 4434401Sbostic * 4534401Sbostic * Note: Inexact will be signaled if x is not an integer, as is 4634401Sbostic * customary for IEEE 754. No other signal can be emitted. 4724596Szliu */ 4824596Szliu double 4934401Sbostic floor(x) 5034401Sbostic double x; 5124596Szliu { 52*35679Sbostic double y; 5324596Szliu 5434401Sbostic if ( 5534401Sbostic #if !defined(vax)&&!defined(tahoe) 5634401Sbostic x != x || /* NaN */ 5734401Sbostic #endif /* !defined(vax)&&!defined(tahoe) */ 5834401Sbostic x >= L) /* already an even integer */ 5934401Sbostic return x; 6034401Sbostic else if (x < (double)0) 6134401Sbostic return -ceil(-x); 6234401Sbostic else { /* now 0 <= x < L */ 6334401Sbostic y = L+x; /* destructive store must be forced */ 6434401Sbostic y -= L; /* an integer, and |x-y| < 1 */ 6534401Sbostic return x < y ? y-(double)1 : y; 6634401Sbostic } 6724596Szliu } 6824596Szliu 6924596Szliu double 7034401Sbostic ceil(x) 7134401Sbostic double x; 7224596Szliu { 73*35679Sbostic double y; 7434401Sbostic 7534401Sbostic if ( 7634401Sbostic #if !defined(vax)&&!defined(tahoe) 7734401Sbostic x != x || /* NaN */ 7834401Sbostic #endif /* !defined(vax)&&!defined(tahoe) */ 7934401Sbostic x >= L) /* already an even integer */ 8034401Sbostic return x; 8134401Sbostic else if (x < (double)0) 8234401Sbostic return -floor(-x); 8334401Sbostic else { /* now 0 <= x < L */ 8434401Sbostic y = L+x; /* destructive store must be forced */ 8534401Sbostic y -= L; /* an integer, and |x-y| < 1 */ 8634401Sbostic return x > y ? y+(double)1 : y; 8734401Sbostic } 8824596Szliu } 8924596Szliu 9031853Szliu #ifndef national /* rint() is in ./NATIONAL/support.s */ 9124596Szliu /* 9224596Szliu * algorithm for rint(x) in pseudo-pascal form ... 9324596Szliu * 9424596Szliu * real rint(x): real x; 9524596Szliu * ... delivers integer nearest x in direction of prevailing rounding 9624596Szliu * ... mode 9724596Szliu * const L = (last consecutive integer)/2 9824596Szliu * = 2**55; for VAX D 9924596Szliu * = 2**52; for IEEE 754 Double 10024596Szliu * real s,t; 10124596Szliu * begin 10224596Szliu * if x != x then return x; ... NaN 10324596Szliu * if |x| >= L then return x; ... already an integer 10424596Szliu * s := copysign(L,x); 10524596Szliu * t := x + s; ... = (x+s) rounded to integer 10624596Szliu * return t - s 10724596Szliu * end; 10824596Szliu * 10924596Szliu * Note: Inexact will be signaled if x is not an integer, as is 11024596Szliu * customary for IEEE 754. No other signal can be emitted. 11124596Szliu */ 11224596Szliu double 11324596Szliu rint(x) 11424596Szliu double x; 11524596Szliu { 116*35679Sbostic double s,t; 117*35679Sbostic const double one = 1.0; 118*35679Sbostic 11931853Szliu #if !defined(vax)&&!defined(tahoe) 12024596Szliu if (x != x) /* NaN */ 12124596Szliu return (x); 12231853Szliu #endif /* !defined(vax)&&!defined(tahoe) */ 12324596Szliu if (copysign(x,one) >= L) /* already an integer */ 12424596Szliu return (x); 12524596Szliu s = copysign(L,x); 12624596Szliu t = x + s; /* x+s rounded to integer */ 12724596Szliu return (t - s); 12824596Szliu } 12931853Szliu #endif /* not national */ 130