/* * M_APM - mapmutl2.c * * Copyright (C) 2002 - 2007 Michael C. Ring * * Permission to use, copy, and distribute this software and its * documentation for any purpose with or without fee is hereby granted, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. * * Permission to modify the software is granted. Permission to distribute * the modified code is granted. Modifications are to be distributed by * using the file 'license.txt' as a template to modify the file header. * 'license.txt' is available in the official MAPM distribution. * * This software is provided "as is" without express or implied warranty. */ /* * $Id: mapmutl2.c,v 1.7 2007/12/03 02:00:04 mike Exp $ * * This file contains various utility functions * * $Log: mapmutl2.c,v $ * Revision 1.7 2007/12/03 02:00:04 mike * Update license * * Revision 1.6 2003/07/21 20:53:10 mike * Modify error messages to be in a consistent format. * * Revision 1.5 2003/05/04 18:14:32 mike * move generic error handling function into a dedicated module * * Revision 1.4 2003/03/31 22:02:22 mike * call generic error handling function * * Revision 1.3 2002/11/03 21:19:40 mike * Updated function parameters to use the modern style * * Revision 1.2 2002/05/17 22:29:46 mike * update some comments * * Revision 1.1 2002/05/17 22:28:27 mike * Initial revision */ #include "m_apm_lc.h" /****************************************************************************/ int m_apm_sign(M_APM atmp) { return(atmp->m_apm_sign); } /****************************************************************************/ int m_apm_exponent(M_APM atmp) { if (atmp->m_apm_sign == 0) return(0); else return(atmp->m_apm_exponent - 1); } /****************************************************************************/ int m_apm_significant_digits(M_APM atmp) { return(atmp->m_apm_datalength); } /****************************************************************************/ int m_apm_is_integer(M_APM atmp) { if (atmp->m_apm_sign == 0) return(1); if (atmp->m_apm_exponent >= atmp->m_apm_datalength) return(1); else return(0); } /****************************************************************************/ int m_apm_is_even(M_APM aa) { int ii, jj; if (aa->m_apm_sign == 0) return(1); ii = aa->m_apm_datalength; jj = aa->m_apm_exponent; if (jj < ii) { M_apm_log_error_msg(M_APM_RETURN, "\'m_apm_is_even\', Non-integer input"); return(0); } if (jj > ii) return(1); ii = ((ii + 1) >> 1) - 1; ii = (int)aa->m_apm_data[ii]; if ((jj & 1) != 0) /* exponent is odd */ ii = ii / 10; if ((ii & 1) == 0) return(1); else return(0); } /****************************************************************************/ int m_apm_is_odd(M_APM bb) { if (m_apm_is_even(bb)) return(0); else return(1); } /****************************************************************************/ void M_set_to_zero(M_APM z) { z->m_apm_datalength = 1; z->m_apm_sign = 0; z->m_apm_exponent = 0; z->m_apm_data[0] = 0; } /****************************************************************************/ void m_apm_negate(M_APM d, M_APM s) { m_apm_copy(d,s); if (d->m_apm_sign != 0) d->m_apm_sign = -(d->m_apm_sign); } /****************************************************************************/ void m_apm_absolute_value(M_APM d, M_APM s) { m_apm_copy(d,s); if (d->m_apm_sign != 0) d->m_apm_sign = 1; } /****************************************************************************/ void m_apm_copy(M_APM dest, M_APM src) { int j; void *vp; j = (src->m_apm_datalength + 1) >> 1; if (j > dest->m_apm_malloclength) { if ((vp = MAPM_REALLOC(dest->m_apm_data, (j + 32))) == NULL) { /* fatal, this does not return */ M_apm_log_error_msg(M_APM_FATAL, "\'m_apm_copy\', Out of memory"); } dest->m_apm_malloclength = j + 28; dest->m_apm_data = (UCHAR *)vp; } dest->m_apm_datalength = src->m_apm_datalength; dest->m_apm_exponent = src->m_apm_exponent; dest->m_apm_sign = src->m_apm_sign; memcpy(dest->m_apm_data, src->m_apm_data, j); } /****************************************************************************/ int m_apm_compare(M_APM ltmp, M_APM rtmp) { int llen, rlen, lsign, rsign, i, j, lexp, rexp; llen = ltmp->m_apm_datalength; rlen = rtmp->m_apm_datalength; lsign = ltmp->m_apm_sign; rsign = rtmp->m_apm_sign; lexp = ltmp->m_apm_exponent; rexp = rtmp->m_apm_exponent; if (rsign == 0) return(lsign); if (lsign == 0) return(-rsign); if (lsign == -rsign) return(lsign); /* signs are the same, check the exponents */ if (lexp > rexp) goto E1; if (lexp < rexp) goto E2; /* signs and exponents are the same, check the data */ if (llen < rlen) j = (llen + 1) >> 1; else j = (rlen + 1) >> 1; for (i=0; i < j; i++) { if (ltmp->m_apm_data[i] > rtmp->m_apm_data[i]) goto E1; if (ltmp->m_apm_data[i] < rtmp->m_apm_data[i]) goto E2; } if (llen == rlen) return(0); else { if (llen > rlen) goto E1; else goto E2; } E1: if (lsign == 1) return(1); else return(-1); E2: if (lsign == 1) return(-1); else return(1); } /****************************************************************************/ /* * * convert a signed long int to ASCII in base 10 * */ void M_long_2_ascii(char *output, long input) { long t, m; int i, j; char *p, tbuf[64]; m = input; p = output; i = 0; t = 2147000000L; /* something < 2^31 */ if ((m > t) || (m < -t)) /* handle the bigger numbers with 'sprintf'. */ { /* let them worry about wrap-around problems */ sprintf(p, "%ld", m); /* at 'LONG_MIN', etc. */ } else { if (m < 0) /* handle the sign */ { *p++ = '-'; m = -m; } while (TRUE) /* build the digits in reverse order */ { t = m / 10; j = (int)(m - (10 * t)); tbuf[i++] = (char)(j + '0'); m = t; if (t == 0) break; } while (TRUE) /* fill output string in the correct order */ { *p++ = tbuf[--i]; if (i == 0) break; } *p = '\0'; } } /****************************************************************************/ /* * this function will convert a string to lowercase */ char *M_lowercase(char *s) { char *p; p = s; while (TRUE) { if (*p >= 'A' && *p <= 'Z') *p += 'a' - 'A'; if (*p++ == '\0') break; } return(s); } /****************************************************************************/ /* returns char position of first occurence of s2 in s1 or -1 if no match found */ int M_strposition(char *s1, char *s2) { register char ch1, ch2; char *p0, *p1, *p2; int ct; ct = -1; p0 = s1; if (*s2 == '\0') return(-1); while (TRUE) { ct++; p1 = p0; p2 = s2; ch2 = *p2; while (TRUE) /* scan until first char matches */ { if ((ch1 = *p1) == '\0') return(-1); if (ch1 == ch2) break; p1++; ct++; } p2++; /* check remainder of 2 strings */ p1++; p0 = p1; while (TRUE) { if ((ch2 = *p2) == '\0') return(ct); if (*p1 != ch2) break; p1++; p2++; } } } /****************************************************************************/