(root)/
glibc-2.38/
sysdeps/
m68k/
m680x0/
fpu/
s_llrint.c
       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-double.h>
      23  #include "mathimpl.h"
      24  
      25  long long int
      26  __llrint (double x)
      27  {
      28    int32_t e;
      29    uint32_t h, l, s;
      30    long long int result;
      31  
      32    x = __m81_u(__rint) (x);
      33  
      34    /* We could use __fixxfdi from libgcc, but here we can take advantage of
      35       the known floating point format.  */
      36    EXTRACT_WORDS (h, l, x);
      37  
      38    e = ((h >> 20) & 0x7ff) - 0x3ff;
      39    if (e < 0)
      40      return 0;
      41    s = h;
      42    h &= 0xfffff;
      43    h |= 0x100000;
      44  
      45    if (e < 63)
      46      {
      47        if (e > 52)
      48  	{
      49  	  h <<= e - 52;
      50  	  h |= l >> (84 - e);
      51  	  l <<= e - 52;
      52  	  result = ((long long int) h << 32) | l;
      53  	}
      54        else if (e > 20)
      55  	{
      56  	  l >>= 52 - e;
      57  	  l |= h << (e - 20);
      58  	  h >>= 52 - e;
      59  	  result = ((long long int) h << 32) | l;
      60  	}
      61        else
      62  	result = h >> (20 - e);
      63        if (s & 0x80000000)
      64  	result = -result;
      65      }
      66    else
      67      /* The number is too large or not finite.  The standard leaves it
      68         undefined what to return when the number is too large to fit in a
      69         `long long int'.  */
      70      result = -1LL;
      71  
      72    return result;
      73  }
      74  
      75  libm_alias_double (__llrint, llrint)