1226048Sobrien
2103373Sobrien/*
3267843Sdelphij *  M_APM  -  mapmpwr2.c
4103373Sobrien *
5103373Sobrien *  Copyright (C) 2002 - 2007   Michael C. Ring
6103373Sobrien *
7103373Sobrien *  Permission to use, copy, and distribute this software and its
8103373Sobrien *  documentation for any purpose with or without fee is hereby granted,
9103373Sobrien *  provided that the above copyright notice appear in all copies and
10103373Sobrien *  that both that copyright notice and this permission notice appear
11103373Sobrien *  in supporting documentation.
12103373Sobrien *
13103373Sobrien *  Permission to modify the software is granted. Permission to distribute
14103373Sobrien *  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.
17 *
18 *  This software is provided "as is" without express or implied warranty.
19 */
20
21/*
22 *      $Id: mapmpwr2.c,v 1.4 2007/12/03 01:56:21 mike Exp $
23 *
24 *      This file contains the Integer Power function and the result
25 *	is NOT ROUNDED. The exponent must be an integer >= zero.
26 *
27 *      This will typically be used in an application where full integer
28 *	precision is required to be maintained.
29 *
30 *      $Log: mapmpwr2.c,v $
31 *      Revision 1.4  2007/12/03 01:56:21  mike
32 *      Update license
33 *
34 *      Revision 1.3  2003/07/21 20:38:06  mike
35 *      Modify error messages to be in a consistent format.
36 *
37 *      Revision 1.2  2003/03/31 21:51:23  mike
38 *      call generic error handling function
39 *
40 *      Revision 1.1  2002/11/03 21:02:04  mike
41 *      Initial revision
42 */
43
44#include "m_apm_lc.h"
45
46/****************************************************************************/
47void	m_apm_integer_pow_nr(M_APM rr, M_APM aa, int mexp)
48{
49M_APM   tmp0, tmpy, tmpz;
50int	nexp, ii;
51
52if (mexp == 0)
53  {
54   m_apm_copy(rr, MM_One);
55   return;
56  }
57else
58  {
59   if (mexp < 0)
60     {
61      M_apm_log_error_msg(M_APM_RETURN,
62            "\'m_apm_integer_pow_nr\', Negative exponent");
63
64      M_set_to_zero(rr);
65      return;
66     }
67  }
68
69if (mexp == 1)
70  {
71   m_apm_copy(rr, aa);
72   return;
73  }
74
75if (mexp == 2)
76  {
77   m_apm_multiply(rr, aa, aa);
78   return;
79  }
80
81nexp = mexp;
82
83if (aa->m_apm_sign == 0)
84  {
85   M_set_to_zero(rr);
86   return;
87  }
88
89tmp0 = M_get_stack_var();
90tmpy = M_get_stack_var();
91tmpz = M_get_stack_var();
92
93m_apm_copy(tmpy, MM_One);
94m_apm_copy(tmpz, aa);
95
96while (TRUE)
97  {
98   ii   = nexp & 1;
99   nexp = nexp >> 1;
100
101   if (ii != 0)                       /* exponent -was- odd */
102     {
103      m_apm_multiply(tmp0, tmpy, tmpz);
104
105      if (nexp == 0)
106        break;
107
108      m_apm_copy(tmpy, tmp0);
109     }
110
111   m_apm_multiply(tmp0, tmpz, tmpz);
112   m_apm_copy(tmpz, tmp0);
113  }
114
115m_apm_copy(rr, tmp0);
116
117M_restore_stack(3);
118}
119/****************************************************************************/
120
121