Subversion Repositories Kolibri OS

Rev

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

  1.  
  2. /* @(#)s_floor.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. FUNCTION
  16. <<floor>>, <<floorf>>, <<ceil>>, <<ceilf>>---floor and ceiling
  17. INDEX
  18.         floor
  19. INDEX
  20.         floorf
  21. INDEX
  22.         ceil
  23. INDEX
  24.         ceilf
  25.  
  26. ANSI_SYNOPSIS
  27.         #include <math.h>
  28.         double floor(double <[x]>);
  29.         float floorf(float <[x]>);
  30.         double ceil(double <[x]>);
  31.         float ceilf(float <[x]>);
  32.  
  33. TRAD_SYNOPSIS
  34.         #include <math.h>
  35.         double floor(<[x]>)
  36.         double <[x]>;
  37.         float floorf(<[x]>)
  38.         float <[x]>;
  39.         double ceil(<[x]>)
  40.         double <[x]>;
  41.         float ceilf(<[x]>)
  42.         float <[x]>;
  43.  
  44. DESCRIPTION
  45. <<floor>> and <<floorf>> find
  46. @tex
  47. $\lfloor x \rfloor$,
  48. @end tex
  49. the nearest integer less than or equal to <[x]>.
  50. <<ceil>> and <<ceilf>> find
  51. @tex
  52. $\lceil x\rceil$,
  53. @end tex
  54. the nearest integer greater than or equal to <[x]>.
  55.  
  56. RETURNS
  57. <<floor>> and <<ceil>> return the integer result as a double.
  58. <<floorf>> and <<ceilf>> return the integer result as a float.
  59.  
  60. PORTABILITY
  61. <<floor>> and <<ceil>> are ANSI.
  62. <<floorf>> and <<ceilf>> are extensions.
  63.  
  64.  
  65. */
  66.  
  67. /*
  68.  * floor(x)
  69.  * Return x rounded toward -inf to integral value
  70.  * Method:
  71.  *      Bit twiddling.
  72.  * Exception:
  73.  *      Inexact flag raised if x not equal to floor(x).
  74.  */
  75.  
  76. #include "fdlibm.h"
  77.  
  78. #ifndef _DOUBLE_IS_32BITS
  79.  
  80. #ifdef __STDC__
  81. static const double huge = 1.0e300;
  82. #else
  83. static double huge = 1.0e300;
  84. #endif
  85.  
  86. #ifdef __STDC__
  87.         double floor(double x)
  88. #else
  89.         double floor(x)
  90.         double x;
  91. #endif
  92. {
  93.         __int32_t i0,i1,j0;
  94.         __uint32_t i,j;
  95.         EXTRACT_WORDS(i0,i1,x);
  96.         j0 = ((i0>>20)&0x7ff)-0x3ff;
  97.         if(j0<20) {
  98.             if(j0<0) {  /* raise inexact if x != 0 */
  99.                 if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
  100.                     if(i0>=0) {i0=i1=0;}
  101.                     else if(((i0&0x7fffffff)|i1)!=0)
  102.                         { i0=0xbff00000;i1=0;}
  103.                 }
  104.             } else {
  105.                 i = (0x000fffff)>>j0;
  106.                 if(((i0&i)|i1)==0) return x; /* x is integral */
  107.                 if(huge+x>0.0) {        /* raise inexact flag */
  108.                     if(i0<0) i0 += (0x00100000)>>j0;
  109.                     i0 &= (~i); i1=0;
  110.                 }
  111.             }
  112.         } else if (j0>51) {
  113.             if(j0==0x400) return x+x;   /* inf or NaN */
  114.             else return x;              /* x is integral */
  115.         } else {
  116.             i = ((__uint32_t)(0xffffffff))>>(j0-20);
  117.             if((i1&i)==0) return x;     /* x is integral */
  118.             if(huge+x>0.0) {            /* raise inexact flag */
  119.                 if(i0<0) {
  120.                     if(j0==20) i0+=1;
  121.                     else {
  122.                         j = i1+(1<<(52-j0));
  123.                         if(j<i1) i0 +=1 ;       /* got a carry */
  124.                         i1=j;
  125.                     }
  126.                 }
  127.                 i1 &= (~i);
  128.             }
  129.         }
  130.         INSERT_WORDS(x,i0,i1);
  131.         return x;
  132. }
  133.  
  134. #endif /* _DOUBLE_IS_32BITS */
  135.