/*****************************************************************************/
/*                                                                           */
/*  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 (a<b)
        return (a);
    else
        return (b);
}

/*****************************************************************************/

float fmin(float a,float b)     /* return the smaller of 2 floats  */
                                /* removed from menu.c 9608.21 RFD */
                                /* original routine written by     */
                                /* Anne Wright 9111.14 and 9403.05 */
{
    if (a<b)
        return (a);
    else
        return (b);
}

/*****************************************************************************/

int max(int a, int b)           /* return the larger of 2 integers */
{
    if (a>b)
        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 */
}

/*****************************************************************************/


