src/libm/s_floor.c
changeset 11683 48bcba563d9c
parent 6044 35448a5ea044
child 11685 1788f503254d
equal deleted inserted replaced
11682:b26412a89fbb 11683:48bcba563d9c
     1 /* @(#)s_floor.c 5.1 93/09/24 */
       
     2 /*
     1 /*
     3  * ====================================================
     2  * ====================================================
     4  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
     3  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
     5  *
     4  *
     6  * Developed at SunPro, a Sun Microsystems, Inc. business.
     5  * Developed at SunPro, a Sun Microsystems, Inc. business.
     8  * software is freely granted, provided that this notice
     7  * software is freely granted, provided that this notice
     9  * is preserved.
     8  * is preserved.
    10  * ====================================================
     9  * ====================================================
    11  */
    10  */
    12 
    11 
    13 #if defined(LIBM_SCCS) && !defined(lint)
       
    14 static const char rcsid[] =
       
    15     "$NetBSD: s_floor.c,v 1.8 1995/05/10 20:47:20 jtc Exp $";
       
    16 #endif
       
    17 
       
    18 /*
    12 /*
    19  * floor(x)
    13  * floor(x)
    20  * Return x rounded toward -inf to integral value
    14  * Return x rounded toward -inf to integral value
    21  * Method:
    15  * Method:
    22  *	Bit twiddling.
    16  *	Bit twiddling.
    23  * Exception:
    17  * Exception:
    24  *	Inexact flag raised if x not equal to floor(x).
    18  *	Inexact flag raised if x not equal to floor(x).
    25  */
    19  */
    26 
    20 
       
    21 /*#include <features.h>*/
       
    22 /* Prevent math.h from defining a colliding inline */
       
    23 #undef __USE_EXTERN_INLINES
    27 #include "math_libm.h"
    24 #include "math_libm.h"
    28 #include "math_private.h"
    25 #include "math_private.h"
    29 
    26 
    30 #ifdef __STDC__
    27 static const double huge = 1.0e300;
    31 static const double huge_val = 1.0e300;
       
    32 #else
       
    33 static double huge_val = 1.0e300;
       
    34 #endif
       
    35 
    28 
    36 libm_hidden_proto(floor)
    29 double floor(double x)
    37 #ifdef __STDC__
       
    38      double floor(double x)
       
    39 #else
       
    40      double floor(x)
       
    41      double x;
       
    42 #endif
       
    43 {
    30 {
    44     int32_t i0, i1, j0;
    31 	int32_t i0,i1,j0;
    45     u_int32_t i, j;
    32 	u_int32_t i,j;
    46     EXTRACT_WORDS(i0, i1, x);
    33 	EXTRACT_WORDS(i0,i1,x);
    47     j0 = ((i0 >> 20) & 0x7ff) - 0x3ff;
    34 	j0 = ((i0>>20)&0x7ff)-0x3ff;
    48     if (j0 < 20) {
    35 	if(j0<20) {
    49         if (j0 < 0) {           /* raise inexact if x != 0 */
    36 	    if(j0<0) { 	/* raise inexact if x != 0 */
    50             if (huge_val + x > 0.0) {       /* return 0*sign(x) if |x|<1 */
    37 		if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
    51                 if (i0 >= 0) {
    38 		    if(i0>=0) {i0=i1=0;}
    52                     i0 = i1 = 0;
    39 		    else if(((i0&0x7fffffff)|i1)!=0)
    53                 } else if (((i0 & 0x7fffffff) | i1) != 0) {
    40 			{ i0=0xbff00000;i1=0;}
    54                     i0 = 0xbff00000;
    41 		}
    55                     i1 = 0;
    42 	    } else {
    56                 }
    43 		i = (0x000fffff)>>j0;
    57             }
    44 		if(((i0&i)|i1)==0) return x; /* x is integral */
    58         } else {
    45 		if(huge+x>0.0) {	/* raise inexact flag */
    59             i = (0x000fffff) >> j0;
    46 		    if(i0<0) i0 += (0x00100000)>>j0;
    60             if (((i0 & i) | i1) == 0)
    47 		    i0 &= (~i); i1=0;
    61                 return x;       /* x is integral */
    48 		}
    62             if (huge_val + x > 0.0) {       /* raise inexact flag */
    49 	    }
    63                 if (i0 < 0)
    50 	} else if (j0>51) {
    64                     i0 += (0x00100000) >> j0;
    51 	    if(j0==0x400) return x+x;	/* inf or NaN */
    65                 i0 &= (~i);
    52 	    else return x;		/* x is integral */
    66                 i1 = 0;
    53 	} else {
    67             }
    54 	    i = ((u_int32_t)(0xffffffff))>>(j0-20);
    68         }
    55 	    if((i1&i)==0) return x;	/* x is integral */
    69     } else if (j0 > 51) {
    56 	    if(huge+x>0.0) { 		/* raise inexact flag */
    70         if (j0 == 0x400)
    57 		if(i0<0) {
    71             return x + x;       /* inf or NaN */
    58 		    if(j0==20) i0+=1;
    72         else
    59 		    else {
    73             return x;           /* x is integral */
    60 			j = i1+(1<<(52-j0));
    74     } else {
    61 			if(j<i1) i0 +=1 ; 	/* got a carry */
    75         i = ((u_int32_t) (0xffffffff)) >> (j0 - 20);
    62 			i1=j;
    76         if ((i1 & i) == 0)
    63 		    }
    77             return x;           /* x is integral */
    64 		}
    78         if (huge_val + x > 0.0) {   /* raise inexact flag */
    65 		i1 &= (~i);
    79             if (i0 < 0) {
    66 	    }
    80                 if (j0 == 20)
    67 	}
    81                     i0 += 1;
    68 	INSERT_WORDS(x,i0,i1);
    82                 else {
    69 	return x;
    83                     j = i1 + (1 << (52 - j0));
       
    84                     if (j < (u_int32_t) i1)
       
    85                         i0 += 1;        /* got a carry */
       
    86                     i1 = j;
       
    87                 }
       
    88             }
       
    89             i1 &= (~i);
       
    90         }
       
    91     }
       
    92     INSERT_WORDS(x, i0, i1);
       
    93     return x;
       
    94 }
    70 }
    95 
       
    96 libm_hidden_def(floor)
    71 libm_hidden_def(floor)