5 * Copyright (C) 2002 - 2007 Michael C. Ring
7 * Permission to use, copy, and distribute this software and its
8 * documentation for any purpose with or without fee is hereby granted,
9 * provided that the above copyright notice appear in all copies and
10 * that both that copyright notice and this permission notice appear
11 * in supporting documentation.
13 * Permission to modify the software is granted. Permission to distribute
14 * the modified code is granted. Modifications are to be distributed by
15 * using the file 'license.txt' as a template to modify the file header.
16 * 'license.txt' is available in the official MAPM distribution.
18 * This software is provided "as is" without express or implied warranty.
22 * $Id: mapmutl2.c,v 1.7 2007/12/03 02:00:04 mike Exp $
24 * This file contains various utility functions
26 * $Log: mapmutl2.c,v $
27 * Revision 1.7 2007/12/03 02:00:04 mike
30 * Revision 1.6 2003/07/21 20:53:10 mike
31 * Modify error messages to be in a consistent format.
33 * Revision 1.5 2003/05/04 18:14:32 mike
34 * move generic error handling function into a dedicated module
36 * Revision 1.4 2003/03/31 22:02:22 mike
37 * call generic error handling function
39 * Revision 1.3 2002/11/03 21:19:40 mike
40 * Updated function parameters to use the modern style
42 * Revision 1.2 2002/05/17 22:29:46 mike
43 * update some comments
45 * Revision 1.1 2002/05/17 22:28:27 mike
51 /****************************************************************************/
52 int m_apm_sign(M_APM atmp
)
54 return(atmp
->m_apm_sign
);
56 /****************************************************************************/
57 int m_apm_exponent(M_APM atmp
)
59 if (atmp
->m_apm_sign
== 0)
62 return(atmp
->m_apm_exponent
- 1);
64 /****************************************************************************/
65 int m_apm_significant_digits(M_APM atmp
)
67 return(atmp
->m_apm_datalength
);
69 /****************************************************************************/
70 int m_apm_is_integer(M_APM atmp
)
72 if (atmp
->m_apm_sign
== 0)
75 if (atmp
->m_apm_exponent
>= atmp
->m_apm_datalength
)
80 /****************************************************************************/
81 int m_apm_is_even(M_APM aa
)
85 if (aa
->m_apm_sign
== 0)
88 ii
= aa
->m_apm_datalength
;
89 jj
= aa
->m_apm_exponent
;
93 M_apm_log_error_msg(M_APM_RETURN
, "\'m_apm_is_even\', Non-integer input");
100 ii
= ((ii
+ 1) >> 1) - 1;
101 ii
= (int)aa
->m_apm_data
[ii
];
103 if ((jj
& 1) != 0) /* exponent is odd */
111 /****************************************************************************/
112 int m_apm_is_odd(M_APM bb
)
114 if (m_apm_is_even(bb
))
119 /****************************************************************************/
120 void M_set_to_zero(M_APM z
)
122 z
->m_apm_datalength
= 1;
124 z
->m_apm_exponent
= 0;
125 z
->m_apm_data
[0] = 0;
127 /****************************************************************************/
128 void m_apm_negate(M_APM d
, M_APM s
)
131 if (d
->m_apm_sign
!= 0)
132 d
->m_apm_sign
= -(d
->m_apm_sign
);
134 /****************************************************************************/
135 void m_apm_absolute_value(M_APM d
, M_APM s
)
138 if (d
->m_apm_sign
!= 0)
141 /****************************************************************************/
142 void m_apm_copy(M_APM dest
, M_APM src
)
147 j
= (src
->m_apm_datalength
+ 1) >> 1;
148 if (j
> dest
->m_apm_malloclength
)
150 if ((vp
= MAPM_REALLOC(dest
->m_apm_data
, (j
+ 32))) == NULL
)
152 /* fatal, this does not return */
154 M_apm_log_error_msg(M_APM_FATAL
, "\'m_apm_copy\', Out of memory");
157 dest
->m_apm_malloclength
= j
+ 28;
158 dest
->m_apm_data
= (UCHAR
*)vp
;
161 dest
->m_apm_datalength
= src
->m_apm_datalength
;
162 dest
->m_apm_exponent
= src
->m_apm_exponent
;
163 dest
->m_apm_sign
= src
->m_apm_sign
;
165 memcpy(dest
->m_apm_data
, src
->m_apm_data
, j
);
167 /****************************************************************************/
168 int m_apm_compare(M_APM ltmp
, M_APM rtmp
)
170 int llen
, rlen
, lsign
, rsign
, i
, j
, lexp
, rexp
;
172 llen
= ltmp
->m_apm_datalength
;
173 rlen
= rtmp
->m_apm_datalength
;
175 lsign
= ltmp
->m_apm_sign
;
176 rsign
= rtmp
->m_apm_sign
;
178 lexp
= ltmp
->m_apm_exponent
;
179 rexp
= rtmp
->m_apm_exponent
;
190 /* signs are the same, check the exponents */
198 /* signs and exponents are the same, check the data */
205 for (i
=0; i
< j
; i
++)
207 if (ltmp
->m_apm_data
[i
] > rtmp
->m_apm_data
[i
])
210 if (ltmp
->m_apm_data
[i
] < rtmp
->m_apm_data
[i
])
238 /****************************************************************************/
241 * convert a signed long int to ASCII in base 10
244 void M_long_2_ascii(char *output
, long input
)
253 t
= 2147000000L; /* something < 2^31 */
255 if ((m
> t
) || (m
< -t
)) /* handle the bigger numbers with 'sprintf'. */
256 { /* let them worry about wrap-around problems */
257 sprintf(p
, "%ld", m
); /* at 'LONG_MIN', etc. */
261 if (m
< 0) /* handle the sign */
267 while (TRUE
) /* build the digits in reverse order */
270 j
= (int)(m
- (10 * t
));
271 tbuf
[i
++] = (char)(j
+ '0');
278 while (TRUE
) /* fill output string in the correct order */
288 /****************************************************************************/
290 * this function will convert a string to lowercase
292 char *M_lowercase(char *s
)
300 if (*p
>= 'A' && *p
<= 'Z')
303 if (*p
++ == '\0') break;
307 /****************************************************************************/
308 /* returns char position of first occurence of s2 in s1
309 or -1 if no match found
311 int M_strposition(char *s1
, char *s2
)
313 register char ch1
, ch2
;
320 if (*s2
== '\0') return(-1);
329 while (TRUE
) /* scan until first char matches */
331 if ((ch1
= *p1
) == '\0') return(-1);
332 if (ch1
== ch2
) break;
337 p2
++; /* check remainder of 2 strings */
343 if ((ch2
= *p2
) == '\0') return(ct
);
344 if (*p1
!= ch2
) break;
350 /****************************************************************************/