1 /* Round float value to long int. 2 Copyright (C) 1997-2022 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19 #include <fenv.h> 20 #include <limits.h> 21 #include <math.h> 22 23 #include <math_private.h> 24 #include <libm-alias-float.h> 25 #include <fix-fp-int-convert-overflow.h> 26 27 28 long int __lroundf(float x)29__lroundf (float x) 30 { 31 int32_t j0; 32 uint32_t i; 33 long int result; 34 int sign; 35 36 GET_FLOAT_WORD (i, x); 37 j0 = ((i >> 23) & 0xff) - 0x7f; 38 sign = (i & 0x80000000) != 0 ? -1 : 1; 39 i &= 0x7fffff; 40 i |= 0x800000; 41 42 if (j0 < (int32_t) (8 * sizeof (long int)) - 1) 43 { 44 if (j0 < 0) 45 return j0 < -1 ? 0 : sign; 46 else if (j0 >= 23) 47 result = (long int) i << (j0 - 23); 48 else 49 { 50 i += 0x400000 >> j0; 51 52 result = i >> (23 - j0); 53 } 54 } 55 else 56 { 57 #ifdef FE_INVALID 58 /* The number is too large. Unless it rounds to LONG_MIN, 59 FE_INVALID must be raised and the return value is 60 unspecified. */ 61 if (FIX_FLT_LONG_CONVERT_OVERFLOW && x != (float) LONG_MIN) 62 { 63 feraiseexcept (FE_INVALID); 64 return sign == 1 ? LONG_MAX : LONG_MIN; 65 } 66 #endif 67 return (long int) x; 68 } 69 70 return sign * result; 71 } 72 73 libm_alias_float (__lround, lround) 74