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