i need floor function implementation

Started by
5 comments, last by sordid 18 years, 9 months ago
I'm programming on a platform that doesn't have the typical "math.h" c runtime functions - I'm looking for an implementation of the floor function using standard IEEE floats - not doubles - preferably a fast one as I'm pretty sure I can write an inefficient one using casting and so forth.. ;) float floor(float x) { ... } thanx in advance
Advertisement
It sounds like you are writing an operating system, here is what I use in mine.

double sqrt(double x){	double i = x/2;	if(x<0)return 0;	while(fabs(i-(x/i))/i>0.000000000000001)			/* (15 DP) ?HOW GET MORE? */		i=(i+(x/i))/2;	return i;}double fabs(double x){	if(x < 0)return -x;	return x;}double hypot(double x, double y){	return sqrt(x*x+y*y);}double ceil(double x){	if(x<0)return (int)x;	return ((int)x)+1;}double cbrt(double x){	double i = x/4;	while(fabs(i-(x/i/i))/i>0.00000000000001)		/* (15 DP) ?HOW GET MORE? */		i=(i+(x/i/i)+i)/3;	return i;}double copysign(double x,double signval){	if(signval<0 && x<0)return x;	if(signval<0 && x>0)return -x;	if(signval>0 && x>0)return x;	if(signval>0 && x<0)return -x;	return x;}double fdim(double a, double b){	if(a-b<1)return 0;	return a-b;}double fmax(double a, double b){	if(a>b)return a;	return b;}double floor(double x){	if(x>0)return (int)x;	return (int)(x-0.9999999999999999);}double fmin(double a, double b){	if(a<b)return a;	return b;}double fmod(double a,double b){	return (int)((((a/b)-((int)(a/b)))*b)+0.5);}double round(double arg){	return (int)(arg+0.5);}double rint(double arg){	return round(arg);}double remainder(double a, double b){	return fmod(a,b);}int trunc(double arg){	return (int)arg;}double nearbyint(double arg){	return round(arg);}double exp2(double exp){	int i;	double value=1;	for(i=1;i<=exp;i++){		value=value*2;	}	return value;}double fma(double a,double b,double c){	return (int)((a*b)+c+0.5);}double ldexp(double num, int exp){        return num*exp2(exp);}        


EDIT: woops, didn't catch the double party, but maybe the others will help you.
float floor(float x){	if (x >= 0.0f)	{		return (float)((int)x);	}	else	{		return (float)((int)x - 1);	}}
That should provide identical behavior to floor() but there's probably a better way to handle it which I can't think of right now.

EDIT: Same thing, one-liner:

float floor(float x) { return (float)((int)x - ((x < 0.0f) ? 1 : 0); }
Ra
float floor(float x){    int i = (int)x;    return (float)((x<0.0f) ? i-1 : i);}

untested. maybe this will also work:

float floor(float x){    int i = (int)x;    return (float)(i - (x<0.0f));}


inspired by Ra:

float floor(float x){    return (float)((int)x - (x<0.0f));}

Quote:Original post by Fred304
inspired by Ra:
float floor(float x){    return (float)((int)x - (x<0.0f));}
float floor(float x){    return (float)((int)x - (int)(x < 0.0f));}
I'm not 100% sure about this, but I believe a cast is needed to turn the zero/non-zero bool to 0/1. A value of true could be 0xFF (or any non-zero value) in some cases.
Ra
Indeed, I'm quite sure this would generate an error, or at least a warning in VS2003... Why do a cheap hack when you can do it cleanly ;)

To the parent poster: The techniques suggested in this thread seem relatively efficient. Apart perhaps from the casting from float to int and int to float. Perhaps you can get around this using some hacked up assembler code, but unless your platform needs extreme performance, I don't see the point of overcomplicating things.

Looking for a serious game project?
www.xgameproject.com
If you have a FPU on that platform.. here's mine:

	float floor(float f)	{		const float half = -0.5f;		int i;		__asm {			fld f			fadd st, st(0)			fadd half			fistp i			sar i,1		};		return float(i);	}


Works with positive and negatives (ie. -2.5 will floor to -3)

The int-to-float conversion is a little more graceful than the float-to-int, as there is no direct float-to-int conversion.

This topic is closed to new replies.

Advertisement