1  /* Round argument to nearest integral value according to current rounding
       2     direction.
       3     Copyright (C) 1997-2023 Free Software Foundation, Inc.
       4     This file is part of the GNU C Library.
       5  
       6     The GNU C Library is free software; you can redistribute it and/or
       7     modify it under the terms of the GNU Lesser General Public
       8     License as published by the Free Software Foundation; either
       9     version 2.1 of the License, or (at your option) any later version.
      10  
      11     The GNU C Library is distributed in the hope that it will be useful,
      12     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14     Lesser General Public License for more details.
      15  
      16     You should have received a copy of the GNU Lesser General Public
      17     License along with the GNU C Library.  If not, see
      18     <https://www.gnu.org/licenses/>.  */
      19  
      20  #include <math.h>
      21  #include <math_private.h>
      22  #include <libm-alias-float.h>
      23  #include "mathimpl.h"
      24  
      25  long long int
      26  __llrintf (float x)
      27  {
      28    int32_t e;
      29    uint32_t i, s;
      30    long long int result;
      31  
      32    x = __m81_u(__rintf) (x);
      33  
      34    GET_FLOAT_WORD (i, x);
      35  
      36    e = ((i >> 23) & 0xff) - 0x7f;
      37    if (e < 0)
      38      return 0;
      39    s = i;
      40    i &= 0x7fffff;
      41    i |= 0x800000;
      42  
      43    if (e < 63)
      44      {
      45        if (e > 55)
      46  	result = (long long int) (i << (e - 55)) << 32;
      47        else if (e > 31)
      48  	result = (((long long int) (i >> (55 - e)) << 32) | (i << (e - 23)));
      49        else if (e > 23)
      50  	result = i << (e - 23);
      51        else
      52  	result = i >> (23 - e);
      53        if (s & 0x80000000)
      54  	result = -result;
      55      }
      56    else
      57      /* The number is too large or not finite.  The standard leaves it
      58         undefined what to return when the number is too large to fit in a
      59         `long long int'.  */
      60      result = -1LL;
      61  
      62    return result;
      63  }
      64  
      65  libm_alias_float (__llrint, llrint)