1 /* $NetBSD: n_floor.c,v 1.9 2024/05/08 02:08:11 riastradh 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. Neither the name of the University nor the names of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #ifndef lint 32 #if 0 33 static char sccsid[] = "@(#)floor.c 8.1 (Berkeley) 6/4/93"; 34 #endif 35 #endif /* not lint */ 36 37 #define _LIBM_STATIC 38 #include "mathimpl.h" 39 40 vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */ 41 42 ic(L, 4503599627370496.0E0, 52, 1.0) /* 2**52 */ 43 44 #ifdef vccast 45 #define L vccast(L) 46 #endif 47 48 __weak_alias(ceill, ceil) 49 __weak_alias(floorl, floor) 50 __weak_alias(truncl, trunc) 51 __weak_alias(rintl, rint) 52 53 /* 54 * floor(x) := the largest integer no larger than x; 55 * ceil(x) := -floor(-x), for all real x. 56 * 57 * Note: Inexact will be signaled if x is not an integer, as is 58 * customary for IEEE 754. No other signal can be emitted. 59 */ 60 double 61 floor(double x) 62 { 63 volatile double y; 64 65 if ( 66 #if !defined(__vax__)&&!defined(tahoe) 67 x != x || /* NaN */ 68 #endif /* !defined(__vax__)&&!defined(tahoe) */ 69 x >= L) /* already an even integer */ 70 return x; 71 else if (x < (double)0) 72 return -ceil(-x); 73 else { /* now 0 <= x < L */ 74 y = L+x; /* destructive store must be forced */ 75 y -= L; /* an integer, and |x-y| < 1 */ 76 return x < y ? y-(double)1 : y; 77 } 78 } 79 80 float 81 floorf(float x) 82 { 83 return floor((double)x); 84 } 85 86 double 87 ceil(double x) 88 { 89 volatile double y; 90 91 if ( 92 #if !defined(__vax__)&&!defined(tahoe) 93 x != x || /* NaN */ 94 #endif /* !defined(__vax__)&&!defined(tahoe) */ 95 x >= L) /* already an even integer */ 96 return x; 97 else if (x < (double)0) 98 return -floor(-x); 99 else { /* now 0 <= x < L */ 100 y = L+x; /* destructive store must be forced */ 101 y -= L; /* an integer, and |x-y| < 1 */ 102 return x > y ? y+(double)1 : y; 103 } 104 } 105 106 float 107 ceilf(float x) 108 { 109 return ceil((double)x); 110 } 111 112 /* 113 * algorithm for rint(x) in pseudo-pascal form ... 114 * 115 * real rint(x): real x; 116 * ... delivers integer nearest x in direction of prevailing rounding 117 * ... mode 118 * const L = (last consecutive integer)/2 119 * = 2**55; for VAX D 120 * = 2**52; for IEEE 754 Double 121 * real s,t; 122 * begin 123 * if x != x then return x; ... NaN 124 * if |x| >= L then return x; ... already an integer 125 * s := copysign(L,x); 126 * t := x + s; ... = (x+s) rounded to integer 127 * return t - s 128 * end; 129 * 130 * Note: Inexact will be signaled if x is not an integer, as is 131 * customary for IEEE 754. No other signal can be emitted. 132 */ 133 double 134 rint(double x) 135 { 136 double s; 137 volatile double t; 138 const double one = 1.0; 139 140 #if !defined(__vax__)&&!defined(tahoe) 141 if (x != x) /* NaN */ 142 return (x); 143 #endif /* !defined(__vax__)&&!defined(tahoe) */ 144 if (copysign(x,one) >= L) /* already an integer */ 145 return (x); 146 s = copysign(L,x); 147 t = x + s; /* x+s rounded to integer */ 148 return (t - s); 149 } 150 151 float 152 rintf(float x) 153 { 154 return rint((double)x); 155 } 156 157 long 158 lrint(double x) 159 { 160 double s; 161 volatile double t; 162 const double one = 1.0; 163 164 #if !defined(__vax__)&&!defined(tahoe) 165 if (x != x) /* NaN */ 166 return (x); 167 #endif /* !defined(__vax__)&&!defined(tahoe) */ 168 if (copysign(x,one) >= L) /* already an integer */ 169 return (x); 170 s = copysign(L,x); 171 t = x + s; /* x+s rounded to integer */ 172 return (t - s); 173 } 174 175 long long 176 llrint(double x) 177 { 178 double s; 179 volatile double t; 180 const double one = 1.0; 181 182 #if !defined(__vax__)&&!defined(tahoe) 183 if (x != x) /* NaN */ 184 return (x); 185 #endif /* !defined(__vax__)&&!defined(tahoe) */ 186 if (copysign(x,one) >= L) /* already an integer */ 187 return (x); 188 s = copysign(L,x); 189 t = x + s; /* x+s rounded to integer */ 190 return (t - s); 191 } 192 193 long 194 lrintf(float x) 195 { 196 float s; 197 volatile float t; 198 const float one = 1.0; 199 200 #if !defined(__vax__)&&!defined(tahoe) 201 if (x != x) /* NaN */ 202 return (x); 203 #endif /* !defined(__vax__)&&!defined(tahoe) */ 204 if (copysign(x,one) >= L) /* already an integer */ 205 return (x); 206 s = copysign(L,x); 207 t = x + s; /* x+s rounded to integer */ 208 return (t - s); 209 } 210 211 long long 212 llrintf(float x) 213 { 214 float s; 215 volatile float t; 216 const float one = 1.0; 217 218 #if !defined(__vax__)&&!defined(tahoe) 219 if (x != x) /* NaN */ 220 return (x); 221 #endif /* !defined(__vax__)&&!defined(tahoe) */ 222 if (copysign(x,one) >= L) /* already an integer */ 223 return (x); 224 s = copysign(L,x); 225 t = x + s; /* x+s rounded to integer */ 226 return (t - s); 227 } 228 229 double 230 trunc(double x) 231 { 232 return x < 0 ? ceil(x) : floor(x); 233 } 234 235 float 236 truncf(float x) 237 { 238 return x < 0 ? ceilf(x) : floorf(x); 239 } 240