Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /* lround adapted to be llround for Newlib, 2009 by Craig Howland.  */
  2. /*
  3.  * ====================================================
  4.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  5.  *
  6.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software is freely granted, provided that this notice
  9.  * is preserved.
  10.  * ====================================================
  11.  */
  12.  
  13. #include "fdlibm.h"
  14.  
  15. #ifndef _DOUBLE_IS_32BITS
  16.  
  17. long long int
  18. llround(double x)
  19. {
  20.   __int32_t sign, exponent_less_1023;
  21.   /* Most significant word, least significant word. */
  22.   __uint32_t msw, lsw;
  23.   long long int result;
  24.  
  25.   EXTRACT_WORDS(msw, lsw, x);
  26.  
  27.   /* Extract sign. */
  28.   sign = ((msw & 0x80000000) ? -1 : 1);
  29.   /* Extract exponent field. */
  30.   exponent_less_1023 = ((msw & 0x7ff00000) >> 20) - 1023;
  31.   msw &= 0x000fffff;
  32.   msw |= 0x00100000;
  33.  
  34.   /* exponent_less_1023 in [-1023,1024] */
  35.   if (exponent_less_1023 < 20)
  36.     {
  37.       /* exponent_less_1023 in [-1023,19] */
  38.       if (exponent_less_1023 < 0)
  39.         {
  40.           if (exponent_less_1023 < -1)
  41.             return 0;
  42.           else
  43.             return sign;
  44.         }
  45.       else
  46.         {
  47.           /* exponent_less_1023 in [0,19] */
  48.           /* shift amt in [0,19] */
  49.           msw += 0x80000 >> exponent_less_1023;
  50.           /* shift amt in [20,1] */
  51.           result = msw >> (20 - exponent_less_1023);
  52.         }
  53.     }
  54.   else if (exponent_less_1023 < (8 * sizeof (long long int)) - 1)
  55.     {
  56.       /* 64bit longlong: exponent_less_1023 in [20,62] */
  57.       if (exponent_less_1023 >= 52)
  58.         /* 64bit longlong: exponent_less_1023 in [52,62] */
  59.         /* 64bit longlong: shift amt in [32,42] */
  60.         result = ((long long int) msw << (exponent_less_1023 - 20))
  61.                     /* 64bit longlong: shift amt in [0,10] */
  62.                     | (lsw << (exponent_less_1023 - 52));
  63.       else
  64.         {
  65.           /* 64bit longlong: exponent_less_1023 in [20,51] */
  66.           unsigned int tmp = lsw
  67.                     /* 64bit longlong: shift amt in [0,31] */
  68.                     + (0x80000000 >> (exponent_less_1023 - 20));
  69.           if (tmp < lsw)
  70.             ++msw;
  71.           /* 64bit longlong: shift amt in [0,31] */
  72.           result = ((long long int) msw << (exponent_less_1023 - 20))
  73.                     /* ***64bit longlong: shift amt in [32,1] */
  74.                     | SAFE_RIGHT_SHIFT (tmp, (52 - exponent_less_1023));
  75.         }
  76.     }
  77.   else
  78.     /* Result is too large to be represented by a long long int. */
  79.     return (long long int)x;
  80.  
  81.   return sign * result;
  82. }
  83.  
  84. #endif /* _DOUBLE_IS_32BITS */
  85.