/*****************************************************************************/ /* */ /* math.c ;extra int and float math functions for IC */ /* ;works with both the 6.270 board and the Handy Board */ /* */ /* by */ /* */ /* Dr. Richard F. Drushel */ /* Department of Biology */ /* Case Western Reserve University */ /* Biology 300 */ /* 2080 Adelbert Road */ /* Cleveland, Ohio 44106-7080 U.S.A. */ /* rfd@po.cwru.edu */ /* */ /*****************************************************************************/ /* */ /* VERSION HISTORY: */ /* */ /* Whenever the program is updated, record it here. Add new version info */ /* to the top of this list, so the newest version is always first. */ /* */ /* 1.1 18 May 1997 ;Richard F. Drushel */ /* ;comment style standardization */ /* */ /* 1.0 8 August 1996 ;Richard F. Drushel */ /* ;initial code and organization */ /* */ /*****************************************************************************/ /* */ /* PUBLIC FUNCTIONS: */ /* */ /* These functions may be used freely by user programs. */ /* */ /* int min(int a,int b) ;return the smaller of 2 integers */ /* */ /* float fmin(float a,float b) ;return the smaller of 2 floats */ /* */ /* int max(int a,int b) ;return the larger of 2 integers */ /* */ /* float fmax(float a,float b) ;return the larger of 2 floats */ /* */ /* int sgn(int a) ;return the sign of an integer */ /* */ /* float fsgn(float a) ;return the sign of a float */ /* */ /* int abs(int a) ;return the absolute value of a */ /* ;signed integer */ /* */ /* float fabs(float a) ;return the absolute value of a float */ /* */ /* float int2uf(int a) ;converts a signed int into its unsigned */ /* ;form, and returns the value as a float */ /* */ /* int uf2int(float a) ;converts a float representing an */ /* ;unsigned int into its signed int form */ /* */ /* fint(float a) ;returns the "integer" part of a float */ /* */ /*****************************************************************************/ /* */ /* PUBLIC GLOBAL VARIABLES: */ /* */ /* These global variables may be accessed freely by user programs. Any */ /* restrictions on their use (e.g., flags which are read-only) should be */ /* noted here. It is suggested that global variables be named in all */ /* capital letters, to avoid confusion with local varibles which are */ /* defined within functions. */ /* */ /* None. */ /* */ /*****************************************************************************/ /* */ /* PRIVATE FUNCTIONS: */ /* */ /* These are internal functions which have no public entry points, and */ /* which user programs should not access directly. It is suggested that */ /* private functions be named with a leading underscore (_), to avoid */ /* confusion with user-defined functions which might have the same name. */ /* */ /* None. */ /* */ /*****************************************************************************/ /* */ /* PRIVATE GLOBAL VARIABLES: */ /* */ /* These are internal global variables which user programs should not */ /* access directly. It is suggested that private global variables be */ /* named in all capital letters with a leading underscore (_), to avoid */ /* confusion with user-defined global variables which might have the same */ /* name. */ /* */ /* None. */ /* */ /*****************************************************************************/ /* */ /* EXTERNAL LIBRARY FILE DEPENDENCIES: */ /* */ /* Any external functions or variables which are used but not defined in */ /* this file should be noted here. List the external library filename, */ /* the library function, and the local calling function. */ /* */ /* None. */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* */ /* global variable declarations */ /* */ /*****************************************************************************/ /* declare global variables here */ /*****************************************************************************/ /* */ /* function declarations */ /* */ /*****************************************************************************/ int min(int a, int b) /* return the smaller of 2 integers */ /* removed from menu.c 9608.21 RFD */ /* original routine written by Anne Wright */ /* 9111.14 and 9403.05 */ { if (ab) return (a); else return (b); } /*****************************************************************************/ float fmax(float a, float b) /* return the larger of 2 floats */ { if (a>b) return (a); else return (b); } /*****************************************************************************/ int sgn(int a) /* returns the sign of an integer: */ /* 1 if positive, -1 if negative, 0 if zero */ { if (a>0) return (1); else { if (a<0) return (-1); else return (0); } } /*****************************************************************************/ float fsgn(float a) /* returns the sign of a float: */ /* 1 if positive, -1 if negative, 0 if zero */ { if (a>0.0) return (1.0); else { if (a<0.) return (-1.0); else return (0.0); } } /*****************************************************************************/ int abs(int a) /* returns the absolute value of a signed int */ { if (a<0) return (-a); else return (a); } /*****************************************************************************/ float fabs(float a) /* returns the absolute value of a float */ { if (a<0.0) return (-a); else return (a); } /*****************************************************************************/ float int2uf(int a) /* converts a signed int into its */ /* corresponding unsigned form, and */ /* returns the value as a float. */ /* return values range 0. to 65535. */ { if (a<0) return (((float)(a))+65536.); else return ((float)(a)); } /*****************************************************************************/ int uf2int(float a) /* converts a float representing an unsigned */ /* int into its corresponding signed int form */ /* Note: 0<=a<=65535 only! */ /* returns 0 if a<0. and -1 if a>65535. */ { if (a<0.) return (0); /* underflow error */ if (a>65536.) return (-1); /* overflow error */ if (a>32768.) return ((int)(a-65536.)); else return ((int)(a)); } /*****************************************************************************/ float fint(float a) /* returns the "integer" part of a float */ /* Note: becomes inaccurate for input values */ /* whose absolute value is greater than about */ /* 1.00E+07 due to loss of internal precision. */ /* Also note: IC's native ability to cast */ /* floats to ints only works between -32768 */ /* and +32767, thus leading to this ugly */ /* algorithm. */ { float sign,count,b; if ((a<1.) && (a>-1.)) return (0.); /* this prevents the infinite loop */ sign=fsgn(a); /* keep the sign for later */ a=fabs(a); /* and let's work only with the absolute value */ count=fint(a/32768.); /* how many 32768s are there? ** RECURSIVE ** */ b=a-(count*32768.); /* and get the remainder (0-32767) */ b=(float)((int)(b)); /* and make the remainder into an integer */ b=(count*32768.)+b; /* reconstitute the absolute value */ return (sign*b); /* and swap in the sign */ } /*****************************************************************************/