UNPKG

1.55 kBtext/coffeescriptView Raw
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
19quickfactor = ->
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
61quickpower = ->
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