134122Sbostic /*
2*61291Sbostic * Copyright (c) 1985, 1993
3*61291Sbostic * The Regents of the University of California. All rights reserved.
434401Sbostic *
542657Sbostic * %sccs.include.redist.c%
634122Sbostic */
724596Szliu
834122Sbostic #ifndef lint
9*61291Sbostic static char sccsid[] = "@(#)floor.c 8.1 (Berkeley) 06/04/93";
1034122Sbostic #endif /* not lint */
1134122Sbostic
1235679Sbostic #include "mathimpl.h"
1334401Sbostic
1435679Sbostic vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */
1535679Sbostic
1635679Sbostic ic(L, 4503599627370496.0E0, 52, 1.0) /* 2**52 */
1735679Sbostic
1835679Sbostic #ifdef vccast
1935679Sbostic #define L vccast(L)
2035679Sbostic #endif
2135679Sbostic
2224596Szliu /*
2334401Sbostic * floor(x) := the largest integer no larger than x;
2434401Sbostic * ceil(x) := -floor(-x), for all real x.
2534401Sbostic *
2634401Sbostic * Note: Inexact will be signaled if x is not an integer, as is
2734401Sbostic * customary for IEEE 754. No other signal can be emitted.
2824596Szliu */
2924596Szliu double
3034401Sbostic floor(x)
3134401Sbostic double x;
3224596Szliu {
3356371Sbostic volatile double y;
3424596Szliu
3534401Sbostic if (
3634401Sbostic #if !defined(vax)&&!defined(tahoe)
3734401Sbostic x != x || /* NaN */
3834401Sbostic #endif /* !defined(vax)&&!defined(tahoe) */
3934401Sbostic x >= L) /* already an even integer */
4034401Sbostic return x;
4134401Sbostic else if (x < (double)0)
4234401Sbostic return -ceil(-x);
4334401Sbostic else { /* now 0 <= x < L */
4434401Sbostic y = L+x; /* destructive store must be forced */
4534401Sbostic y -= L; /* an integer, and |x-y| < 1 */
4634401Sbostic return x < y ? y-(double)1 : y;
4734401Sbostic }
4824596Szliu }
4924596Szliu
5024596Szliu double
ceil(x)5134401Sbostic ceil(x)
5234401Sbostic double x;
5324596Szliu {
5456371Sbostic volatile double y;
5534401Sbostic
5634401Sbostic if (
5734401Sbostic #if !defined(vax)&&!defined(tahoe)
5834401Sbostic x != x || /* NaN */
5934401Sbostic #endif /* !defined(vax)&&!defined(tahoe) */
6034401Sbostic x >= L) /* already an even integer */
6134401Sbostic return x;
6234401Sbostic else if (x < (double)0)
6334401Sbostic return -floor(-x);
6434401Sbostic else { /* now 0 <= x < L */
6534401Sbostic y = L+x; /* destructive store must be forced */
6634401Sbostic y -= L; /* an integer, and |x-y| < 1 */
6734401Sbostic return x > y ? y+(double)1 : y;
6834401Sbostic }
6924596Szliu }
7024596Szliu
7156371Sbostic #ifndef ns32000 /* rint() is in ./NATIONAL/support.s */
7224596Szliu /*
7324596Szliu * algorithm for rint(x) in pseudo-pascal form ...
7424596Szliu *
7524596Szliu * real rint(x): real x;
7624596Szliu * ... delivers integer nearest x in direction of prevailing rounding
7724596Szliu * ... mode
7824596Szliu * const L = (last consecutive integer)/2
7924596Szliu * = 2**55; for VAX D
8024596Szliu * = 2**52; for IEEE 754 Double
8124596Szliu * real s,t;
8224596Szliu * begin
8324596Szliu * if x != x then return x; ... NaN
8424596Szliu * if |x| >= L then return x; ... already an integer
8524596Szliu * s := copysign(L,x);
8624596Szliu * t := x + s; ... = (x+s) rounded to integer
8724596Szliu * return t - s
8824596Szliu * end;
8924596Szliu *
9024596Szliu * Note: Inexact will be signaled if x is not an integer, as is
9124596Szliu * customary for IEEE 754. No other signal can be emitted.
9224596Szliu */
9324596Szliu double
rint(x)9424596Szliu rint(x)
9524596Szliu double x;
9624596Szliu {
9756371Sbostic double s;
9856371Sbostic volatile double t;
9935679Sbostic const double one = 1.0;
10035679Sbostic
10131853Szliu #if !defined(vax)&&!defined(tahoe)
10224596Szliu if (x != x) /* NaN */
10324596Szliu return (x);
10431853Szliu #endif /* !defined(vax)&&!defined(tahoe) */
10524596Szliu if (copysign(x,one) >= L) /* already an integer */
10624596Szliu return (x);
10724596Szliu s = copysign(L,x);
10824596Szliu t = x + s; /* x+s rounded to integer */
10924596Szliu return (t - s);
11024596Szliu }
11131853Szliu #endif /* not national */
112