Subversion Repositories Kolibri OS

Rev

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

  1. /* lrintf adapted to be llrintf for Newlib, 2009 by Craig Howland.  */
  2. /* @(#)sf_lrint.c 5.1 93/09/24 */
  3. /*
  4.  * ====================================================
  5.  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  6.  *
  7.  * Developed at SunPro, a Sun Microsystems, Inc. business.
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software is freely granted, provided that this notice
  10.  * is preserved.
  11.  * ====================================================
  12.  */
  13.  
  14. /*
  15.  * llrintf(x)
  16.  * Return x rounded to integral value according to the prevailing
  17.  * rounding mode.
  18.  * Method:
  19.  *      Using floating addition.
  20.  * Exception:
  21.  *      Inexact flag raised if x not equal to llrintf(x).
  22.  */
  23.  
  24. #include "fdlibm.h"
  25.  
  26. #ifdef __STDC__
  27. static const float
  28. #else
  29. static float
  30. #endif
  31. /* Adding a float, x, to 2^23 will cause the result to be rounded based on
  32.    the fractional part of x, according to the implementation's current rounding
  33.    mode.  2^23 is the smallest float that can be represented using all 23 significant
  34.    digits. */
  35. TWO23[2]={
  36.   8.3886080000e+06, /* 0x4b000000 */
  37.  -8.3886080000e+06, /* 0xcb000000 */
  38. };
  39.  
  40. #ifdef __STDC__
  41.         long long int llrintf(float x)
  42. #else
  43.         long long int llrintf(x)
  44.         float x;
  45. #endif
  46. {
  47.   __int32_t j0,sx;
  48.   __uint32_t i0;
  49.   float t;
  50.   volatile float w;
  51.   long long int result;
  52.  
  53.   GET_FLOAT_WORD(i0,x);
  54.  
  55.   /* Extract sign bit. */
  56.   sx = (i0 >> 31);
  57.  
  58.   /* Extract exponent field. */
  59.   j0 = ((i0 & 0x7f800000) >> 23) - 127;
  60.  
  61.   if (j0 < (int)(sizeof (long long int) * 8) - 1)
  62.     {
  63.       if (j0 < -1)
  64.         return 0;
  65.       else if (j0 >= 23)
  66.         result = (long long int) ((i0 & 0x7fffff) | 0x800000) << (j0 - 23);
  67.       else
  68.         {
  69.           w = TWO23[sx] + x;
  70.           t = w - TWO23[sx];
  71.           GET_FLOAT_WORD (i0, t);
  72.           /* Detect the all-zeros representation of plus and
  73.              minus zero, which fails the calculation below. */
  74.           if ((i0 & ~((__uint32_t)1 << 31)) == 0)
  75.               return 0;
  76.           j0 = ((i0 >> 23) & 0xff) - 0x7f;
  77.           i0 &= 0x7fffff;
  78.           i0 |= 0x800000;
  79.           result = i0 >> (23 - j0);
  80.         }
  81.     }
  82.   else
  83.     {
  84.       return (long long int) x;
  85.     }
  86.   return sx ? -result : result;
  87. }
  88.  
  89. #ifdef _DOUBLE_IS_32BITS
  90.  
  91. #ifdef __STDC__
  92.         long long int llrint(double x)
  93. #else
  94.         long long int llrint(x)
  95.         double x;
  96. #endif
  97. {
  98.   return llrintf((float) x);
  99. }
  100.  
  101. #endif /* defined(_DOUBLE_IS_32BITS) */
  102.