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 33static 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 40vc(L, 4503599627370496.0E0 ,0000,5c00,0000,0000, 55, 1.0) /* 2**55 */ 41 42ic(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 */ 60double 61floor(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 80float 81floorf(float x) 82{ 83 return floor((double)x); 84} 85 86double 87ceil(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 106float 107ceilf(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 */ 133double 134rint(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 151float 152rintf(float x) 153{ 154 return rint((double)x); 155} 156 157long 158lrint(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 175long long 176llrint(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 193long 194lrintf(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 211long long 212llrintf(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 229double 230trunc(double x) 231{ 232 return x < 0 ? ceil(x) : floor(x); 233} 234 235float 236truncf(float x) 237{ 238 return x < 0 ? ceilf(x) : floorf(x); 239} 240