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-ldouble.h>
      23  #include "mathimpl.h"
      24  
      25  long long int
      26  __llrintl (long double x)
      27  {
      28    int32_t e, s;
      29    uint32_t h, l;
      30    long long int result;
      31  
      32    x = __m81_u(__rintl) (x);
      33  
      34    GET_LDOUBLE_WORDS (e, h, l, x);
      35  
      36    s = e;
      37    e = (e & 0x7fff) - 0x3fff;
      38    if (e < 0)
      39      return 0;
      40  
      41    if (e < 63)
      42      {
      43        if (e > 31)
      44  	{
      45  	  l >>= 63 - e;
      46  	  l |= h << (e - 31);
      47  	  h >>= 63 - e;
      48  	  result = ((long long int) h << 32) | l;
      49  	}
      50        else
      51  	result = h >> (31 - e);
      52        if (s & 0x8000)
      53  	result = -result;
      54      }
      55    else
      56      /* The number is too large or not finite.  The standard leaves it
      57         undefined what to return when the number is too large to fit in a
      58         `long long int'.  */
      59      result = -1LL;
      60  
      61    return result;
      62  }
      63  
      64  libm_alias_ldouble (__llrint, llrint)