src/libm/s_floor.c
author Ryan C. Gordon <icculus@icculus.org>
Thu, 21 Apr 2016 03:16:44 -0400
changeset 11729 d1ce8396c356
parent 11685 1788f503254d
child 12420 4a6c91d9cc33
permissions -rw-r--r--
Initial shot at a renderer target for Apple's Metal API.

This isn't complete, but is enough to run testsprite2. It's currently
Mac-only; with a little work to figure out how to properly glue in a Metal
layer to a UIView, this will likely work on iOS, too.

This is only wired up to the configure script right now, and disabled by
default. CMake and Xcode still need their bits filled in as appropriate.
     1 /*
     2  * ====================================================
     3  * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
     4  *
     5  * Developed at SunPro, a Sun Microsystems, Inc. business.
     6  * Permission to use, copy, modify, and distribute this
     7  * software is freely granted, provided that this notice
     8  * is preserved.
     9  * ====================================================
    10  */
    11 
    12 /*
    13  * floor(x)
    14  * Return x rounded toward -inf to integral value
    15  * Method:
    16  *	Bit twiddling.
    17  * Exception:
    18  *	Inexact flag raised if x not equal to floor(x).
    19  */
    20 
    21 /*#include <features.h>*/
    22 /* Prevent math.h from defining a colliding inline */
    23 #undef __USE_EXTERN_INLINES
    24 #include "math_libm.h"
    25 #include "math_private.h"
    26 
    27 static const double huge = 1.0e300;
    28 
    29 double floor(double x)
    30 {
    31 	int32_t i0,i1,j0;
    32 	u_int32_t i,j;
    33 	EXTRACT_WORDS(i0,i1,x);
    34 	j0 = ((i0>>20)&0x7ff)-0x3ff;
    35 	if(j0<20) {
    36 	    if(j0<0) { 	/* raise inexact if x != 0 */
    37 		if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
    38 		    if(i0>=0) {i0=i1=0;}
    39 		    else if(((i0&0x7fffffff)|i1)!=0)
    40 			{ i0=0xbff00000;i1=0;}
    41 		}
    42 	    } else {
    43 		i = (0x000fffff)>>j0;
    44 		if(((i0&i)|i1)==0) return x; /* x is integral */
    45 		if(huge+x>0.0) {	/* raise inexact flag */
    46 		    if(i0<0) i0 += (0x00100000)>>j0;
    47 		    i0 &= (~i); i1=0;
    48 		}
    49 	    }
    50 	} else if (j0>51) {
    51 	    if(j0==0x400) return x+x;	/* inf or NaN */
    52 	    else return x;		/* x is integral */
    53 	} else {
    54 	    i = ((u_int32_t)(0xffffffff))>>(j0-20);
    55 	    if((i1&i)==0) return x;	/* x is integral */
    56 	    if(huge+x>0.0) { 		/* raise inexact flag */
    57 		if(i0<0) {
    58 		    if(j0==20) i0+=1;
    59 		    else {
    60 			j = i1+(1<<(52-j0));
    61 			if(j<(u_int32_t)i1) i0 +=1 ; 	/* got a carry */
    62 			i1=j;
    63 		    }
    64 		}
    65 		i1 &= (~i);
    66 	    }
    67 	}
    68 	INSERT_WORDS(x,i0,i1);
    69 	return x;
    70 }
    71 libm_hidden_def(floor)