atlnewbie 122 Report post Posted July 4, 2005 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 0 Share this post Link to post Share on other sites
jumpjumpjump 328 Report post Posted July 4, 2005 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. 0 Share this post Link to post Share on other sites
Ra 1062 Report post Posted July 4, 2005 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); } 0 Share this post Link to post Share on other sites
Fred304 382 Report post Posted July 4, 2005 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));} 0 Share this post Link to post Share on other sites
Ra 1062 Report post Posted July 4, 2005 Quote:Original post by Fred304inspired 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. 0 Share this post Link to post Share on other sites
Max_Payne 757 Report post Posted July 4, 2005 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. 0 Share this post Link to post Share on other sites
sordid 246 Report post Posted July 4, 2005 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. 0 Share this post Link to post Share on other sites