1 // Rational power function
6 static void qpowf(void);
7 static void normalize_angle(void);
8 static int is_small_integer(U
*);
25 unsigned int a
, b
, *t
, *x
, *y
;
30 // if base is 1 or exponent is 0 then return 1
32 if (isplusone(BASE
) || iszero(EXPO
)) {
37 // if base is zero then return 0
40 if (isnegativenumber(EXPO
))
41 stop("divide by zero");
46 // if exponent is 1 then return base
48 if (isplusone(EXPO
)) {
53 // if exponent is integer then power
55 if (isinteger(EXPO
)) {
58 if (expo
== (int) 0x80000000) {
59 // expo greater than 32 bits
66 x
= mpow(BASE
->u
.q
.a
, abs(expo
));
67 y
= mpow(BASE
->u
.q
.b
, abs(expo
));
83 // from here on out the exponent is NOT an integer
85 // if base is -1 then normalize polar angle
87 if (isminusone(BASE
)) {
93 // if base is negative then (-N)^M -> N^M * (-1)^M
95 if (isnegativenumber(BASE
)) {
107 // if BASE is not an integer then power numerator and denominator
109 if (!isinteger(BASE
)) {
123 // At this point BASE is a positive integer.
125 // If BASE is small then factor it.
127 if (is_small_integer(BASE
)) {
134 // At this point BASE is a positive integer and EXPO is not an integer.
136 if (MLENGTH(EXPO
->u
.q
.a
) > 1 || MLENGTH(EXPO
->u
.q
.b
) > 1) {
147 x
= mroot(BASE
->u
.q
.a
, b
);
165 if (MSIGN(EXPO
->u
.q
.a
) == -1) {
176 //-----------------------------------------------------------------------------
178 // Normalize the angle of unit imaginary, i.e. (-1) ^ N
180 // Input: N on stack (must be rational, not float)
182 // Output: Result on stack
191 // (-1)^(8/3) -> (-1)^(2/3) 8 3 2 2
192 // (-1)^(7/3) -> (-1)^(1/3) 7 3 2 1
193 // (-1)^(5/3) -> -(-1)^(2/3) 5 3 1 2
194 // (-1)^(4/3) -> -(-1)^(1/3) 4 3 1 1
195 // (-1)^(2/3) -> (-1)^(2/3) 2 3 0 2
196 // (-1)^(1/3) -> (-1)^(1/3) 1 3 0 1
198 // (-1)^(-1/3) -> -(-1)^(2/3) -1 3 -1 2
199 // (-1)^(-2/3) -> -(-1)^(1/3) -2 3 -1 1
200 // (-1)^(-4/3) -> (-1)^(2/3) -4 3 -2 2
201 // (-1)^(-5/3) -> (-1)^(1/3) -5 3 -2 1
202 // (-1)^(-7/3) -> -(-1)^(2/3) -7 3 -3 2
203 // (-1)^(-8/3) -> -(-1)^(1/3) -8 3 -3 1
205 //-----------------------------------------------------------------------------
212 normalize_angle(void)
222 push_integer(-1); // odd exponent
224 push_integer(1); // even exponent
235 if (isnegativenumber(A
)) {
242 // remainder (always positive)
249 // remainder becomes new angle
256 // negate if quotient is odd
265 is_small_integer(U
*p
)
267 if (isinteger(p
) && MLENGTH(p
->u
.q
.a
) == 1 && (p
->u
.q
.a
[0] & 0x80000000) == 0)