1 /* $NetBSD: n_floor.c,v 1.3 1998/10/20 02:26:11 matt Exp $ */ 2 /* 3 * Copyright (c) 1985, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. All advertising materials mentioning features or use of this software 15 * must display the following acknowledgement: 16 * This product includes software developed by the University of 17 * California, Berkeley and its contributors. 18 * 4. Neither the name of the University nor the names of its contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #ifndef lint 36 #if 0 37 static char sccsid[] = "@(#)floor.c 8.1 (Berkeley) 6/4/93"; 38 #endif 39 #endif /* not lint */ 40 41 #include "mathimpl.h" 42 43 vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */ 44 45 ic(L, 4503599627370496.0E0, 52, 1.0) /* 2**52 */ 46 47 #ifdef vccast 48 #define L vccast(L) 49 #endif 50 51 /* 52 * floor(x) := the largest integer no larger than x; 53 * ceil(x) := -floor(-x), for all real x. 54 * 55 * Note: Inexact will be signaled if x is not an integer, as is 56 * customary for IEEE 754. No other signal can be emitted. 57 */ 58 double 59 floor(x) 60 double x; 61 { 62 volatile double y; 63 64 if ( 65 #if !defined(__vax__)&&!defined(tahoe) 66 x != x || /* NaN */ 67 #endif /* !defined(__vax__)&&!defined(tahoe) */ 68 x >= L) /* already an even integer */ 69 return x; 70 else if (x < (double)0) 71 return -ceil(-x); 72 else { /* now 0 <= x < L */ 73 y = L+x; /* destructive store must be forced */ 74 y -= L; /* an integer, and |x-y| < 1 */ 75 return x < y ? y-(double)1 : y; 76 } 77 } 78 79 double 80 ceil(x) 81 double x; 82 { 83 volatile double y; 84 85 if ( 86 #if !defined(__vax__)&&!defined(tahoe) 87 x != x || /* NaN */ 88 #endif /* !defined(__vax__)&&!defined(tahoe) */ 89 x >= L) /* already an even integer */ 90 return x; 91 else if (x < (double)0) 92 return -floor(-x); 93 else { /* now 0 <= x < L */ 94 y = L+x; /* destructive store must be forced */ 95 y -= L; /* an integer, and |x-y| < 1 */ 96 return x > y ? y+(double)1 : y; 97 } 98 } 99 100 #ifndef ns32000 /* rint() is in ./NATIONAL/support.s */ 101 /* 102 * algorithm for rint(x) in pseudo-pascal form ... 103 * 104 * real rint(x): real x; 105 * ... delivers integer nearest x in direction of prevailing rounding 106 * ... mode 107 * const L = (last consecutive integer)/2 108 * = 2**55; for VAX D 109 * = 2**52; for IEEE 754 Double 110 * real s,t; 111 * begin 112 * if x != x then return x; ... NaN 113 * if |x| >= L then return x; ... already an integer 114 * s := copysign(L,x); 115 * t := x + s; ... = (x+s) rounded to integer 116 * return t - s 117 * end; 118 * 119 * Note: Inexact will be signaled if x is not an integer, as is 120 * customary for IEEE 754. No other signal can be emitted. 121 */ 122 double 123 rint(x) 124 double x; 125 { 126 double s; 127 volatile double t; 128 const double one = 1.0; 129 130 #if !defined(__vax__)&&!defined(tahoe) 131 if (x != x) /* NaN */ 132 return (x); 133 #endif /* !defined(__vax__)&&!defined(tahoe) */ 134 if (copysign(x,one) >= L) /* already an integer */ 135 return (x); 136 s = copysign(L,x); 137 t = x + s; /* x+s rounded to integer */ 138 return (t - s); 139 } 140 #endif /* not national */ 141