Advertisement
Lorfa

CleanedSunFloor

May 25th, 2023
613
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.70 KB | None | 0 0
  1. // floor(x)
  2. // Return x rounded toward -inf to integral value
  3. // Method: Bit twiddling.
  4. // Exception: Inexact flag raised if x not equal to floor(x)
  5.  
  6. static const double huge = 1.0e300;
  7.  
  8. double floor(double x)
  9.  
  10. {
  11.     int i0,i1,j0;
  12.    
  13.     unsigned int i,j;
  14.    
  15.     i0 =  *(1 + (int*)&x);              // __HI(x)
  16.    
  17.     i1 =  *(int*)&x;                    // __LO(x)
  18.    
  19.     j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;  
  20.        
  21.     if (j0 < 20) {                      
  22.        
  23.         if (j0 < 0) {                   // raise inexact if x != 0;
  24.        
  25.             if (huge + x > 0.0) {       // return 0 * sign(x) if |x| < 1
  26.            
  27.                 if (i0 >= 0) {i0 = i1 = 0;}
  28.                
  29.                     else if (((i0 & 0x7fffffff) | i1) != 0)
  30.                
  31.                     {i0 = 0xbff00000; i1=0;}
  32.                                 }
  33.        
  34.                     }  
  35.        
  36.             else {                     
  37.            
  38.                 i = (0x000fffff) >> j0;            
  39.        
  40.                 if (((i0 & i) | i1) == 0) return x; // x is integral               
  41.        
  42.                     if (huge + x > 0.0) {   // raise inexact flag
  43.                
  44.                         if (i0 < 0) {      
  45.                                        
  46.                             i0 += (0x00100000) >> j0;                          
  47.                    
  48.                             i0 &= (~i);
  49.                    
  50.                             i1=0;
  51.                        
  52.                             }
  53.                         }
  54.                 }
  55.        
  56.     } else if (j0 > 51) {
  57.        
  58.         if (j0 == 0x400) return x + x;  // inf or NaN
  59.        
  60.             else return x;              // x is integral
  61.        
  62.             }
  63.    
  64.      else {
  65.        
  66.         i = ((unsigned)(0xffffffff)) >> (j0 - 20);
  67.        
  68.         if ((i1 & i) == 0) return x;    // x is integral
  69.        
  70.         if (huge + x > 0.0) {           // raise inexact flag
  71.        
  72.             if (i0 < 0) {
  73.            
  74.                 if (j0 == 20) i0 += 1;
  75.            
  76.                 else {
  77.                
  78.             j = i1 + (1 << (52 - j0));
  79.            
  80.             if (j < i1) i0 += 1 ;       // got a carry
  81.            
  82.             i1 = j;
  83.            
  84.                     }
  85.             }
  86.            
  87.         i1 &= (~i);
  88.        
  89.         }
  90.     }
  91.        
  92.     *(1 + (int*)&x) = i0;
  93.    
  94.     *(int*)&x = i1;
  95.    
  96.     return x;  
  97. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement