123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- //-----------------------------------------------------------------------------
- //
- // Factor small numerical powers
- //
- // Input: tos-2 Base (positive integer < 2^31 - 1)
- //
- // tos-1 Exponent
- //
- // Output: Expr on stack
- //
- //-----------------------------------------------------------------------------
- #include "stdafx.h"
- #include "defs.h"
- #define BASE p1
- #define EXPO p2
- static void quickpower(void);
- void
- quickfactor(void)
- {
- int h, i, n;
- U **s;
- save();
- EXPO = pop();
- BASE = pop();
- h = tos;
- push(BASE);
- factor_small_number();
- n = tos - h;
- s = stack + h;
- for (i = 0; i < n; i += 2) {
- push(s[i]); // factored base
- push(s[i + 1]); // factored exponent
- push(EXPO);
- multiply();
- quickpower();
- }
- // stack has n results from factor_number_raw()
- // on top of that are all the expressions from quickpower()
- // multiply the quickpower() results
- multiply_all(tos - h - n);
- p1 = pop();
- tos = h;
- push(p1);
- restore();
- }
- // BASE is a prime number so power is simpler
- static void
- quickpower(void)
- {
- int expo;
- save();
- EXPO = pop();
- BASE = pop();
- push(EXPO);
- bignum_truncate();
- p3 = pop();
- push(EXPO);
- push(p3);
- subtract();
- p4 = pop();
- // fractional part of EXPO
- if (!iszero(p4)) {
- push_symbol(POWER);
- push(BASE);
- push(p4);
- list(3);
- }
- push(p3);
- expo = pop_integer();
- if (expo == (int) 0x80000000) {
- push_symbol(POWER);
- push(BASE);
- push(p3);
- list(3);
- restore();
- return;
- }
- if (expo == 0) {
- restore();
- return;
- }
- push(BASE);
- bignum_power_number(expo);
- restore();
- }
|