1 | #-----------------------------------------------------------------------------
|
2 | #
|
3 | # Factor small numerical powers
|
4 | #
|
5 | # Input: tos-2 Base (positive integer < 2^31 - 1)
|
6 | #
|
7 | # tos-1 Exponent
|
8 | #
|
9 | # Output: Expr on stack
|
10 | #
|
11 | #-----------------------------------------------------------------------------
|
12 |
|
13 |
|
14 |
|
15 | #define BASE p1
|
16 | #define EXPO p2
|
17 |
|
18 |
|
19 | quickfactor = ->
|
20 | i = 0
|
21 | save()
|
22 |
|
23 | p2 = pop(); # p2 is EXPO
|
24 | p1 = pop(); # p1 is BASE
|
25 |
|
26 | h = tos
|
27 |
|
28 | push(p1); # p1 is BASE
|
29 |
|
30 | factor_small_number()
|
31 |
|
32 | n = tos - h
|
33 |
|
34 | stackIndex = h
|
35 |
|
36 | for i in [0...n] by 2
|
37 | push(stack[stackIndex+i]); # factored base
|
38 | push(stack[stackIndex + i + 1]); # factored exponent
|
39 | push(p2); # p2 is EXPO
|
40 | multiply()
|
41 | quickpower()
|
42 |
|
43 | # stack has n results from factor_number_raw()
|
44 |
|
45 | # on top of that are all the expressions from quickpower()
|
46 |
|
47 | # multiply the quickpower() results
|
48 |
|
49 | multiply_all(tos - h - n)
|
50 |
|
51 | p1 = pop()
|
52 |
|
53 | moveTos h
|
54 |
|
55 | push(p1)
|
56 |
|
57 | restore()
|
58 |
|
59 | # p1 (BASE) is a prime number so power is simpler
|
60 |
|
61 | quickpower = ->
|
62 | expo = 0
|
63 |
|
64 | save()
|
65 |
|
66 | p2 = pop(); # p2 is EXPO
|
67 | p1 = pop(); # p1 is BASE
|
68 |
|
69 | push(p2); # p2 is EXPO
|
70 | bignum_truncate()
|
71 | p3 = pop()
|
72 |
|
73 | push(p2); # p2 is EXPO
|
74 | push(p3)
|
75 | subtract()
|
76 | p4 = pop()
|
77 |
|
78 | # fractional part of p2 (EXPO)
|
79 |
|
80 | if (!iszero(p4))
|
81 | push_symbol(POWER)
|
82 | push(p1); # p1 is BASE
|
83 | push(p4)
|
84 | list(3)
|
85 |
|
86 | push(p3)
|
87 | expo = pop_integer()
|
88 |
|
89 | if (isNaN(expo))
|
90 | push_symbol(POWER)
|
91 | push(p1); # p1 is BASE
|
92 | push(p3)
|
93 | list(3)
|
94 | restore()
|
95 | return
|
96 |
|
97 | if (expo == 0)
|
98 | restore()
|
99 | return
|
100 |
|
101 | push(p1); # p1 is BASE
|
102 | bignum_power_number(expo)
|
103 |
|
104 | restore()
|
105 |
|
106 | #if SELFTEST
|
107 |
|