Minor changes to README.
[vvhitespace] / stdlib / math.pvvs
CommitLineData
48f88489
AT
1@ (c) 2020 Aaron Taylor <ataylor at subgeniuskitty dot com>
2@ See LICENSE.txt file for copyright and license details.
3
3625ff3a
AT
4#ifndef VVS_STDLIB_MATH
5#define VVS_STDLIB_MATH
6
2612f47f 7@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
bb21580a
AT
8@ Name:
9@ random (10000)
2612f47f 10@ Description:
f969012f
DNR
11@ Returns a pseudo-random number.
12@ Before using for the first time, seed heap[0] with a non-zero value.
13@ This PRNG was taken from: https://en.wikipedia.org/wiki/Xorshift
2612f47f
AT
14@ Call Stack:
15@ empty
16@ Return Stack:
17@ random number <-- TOS
18@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
f969012f 19#include <logic.pvvs>
2612f47f 20NSSVTSSSSN | Mark: 10000 (random)
b15f1da5 21
f969012f 22@ Fetch seed from heap[0].
b15f1da5
AT
23SSSSN | PUSH 0 (ptr)
24TTT | LOAD
b15f1da5 25
f969012f
DNR
26@ Set TOS ^= TOS << 13
27SNS | DUP
28SSSTTSTN | PUSH +13
29NSTTSTTSTN | JSR > 101101 (lshift)
30NSTTSTSTTN | JSR > 101011 (xor)
31
32@ Set TOS ^= TOS >> 7
33SNS | DUP
34SSSTTTN | PUSH +7
35NSTTSTTSSN | JSR > 101100 (rshift)
36NSTTSTSTTN | JSR > 101011 (xor)
37
38@ Set TOS ^= TOS << 17
39SNS | DUP
40SSSTSSSTN | PUSH +17
41NSTTSTTSTN | JSR > 101101 (lshift)
42NSTTSTSTTN | JSR > 101011 (xor)
43
44@ Store a copy of the new seed at heap[0] and return.
b15f1da5
AT
45SNS | DUP
46SSSSN | PUSH 0 (ptr)
47SNT | SWAP
48TTS | STORE
2612f47f
AT
49NTN | RTS
50
d5a0b337
AT
51@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
52@ Name:
53@ fastrand (10011)
54@ Description:
55@ Returns a pseudo-random number.
27c76338 56@ Probably not as good as `random`, but much faster since it does not use XOR.
d5a0b337
AT
57@ Based on the POSIX.1-2001 example for random().
58@ Before using for the first time, seed heap[0] with a value.
59@ Call Stack:
60@ empty
61@ Return Stack:
62@ random number <-- TOS
63@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
64NSSVTSSTTN | Mark: 10011 (fastrand)
65
66@ Generate the next seed value
67SSSSN | PUSH 0 (ptr)
68TTT | LOAD
69SSSTSSSSSTTTSSSTTSSTSSTTTSSTTSTTSTN | PUSH 1103515245
70TSSN | MULTIPLY
71SSSTTSSSSSSTTTSSTN | PUSH 12345
72TSSS | ADD
73
74@ Store the next seed value but keep a copy on the stack.
75SNS | DUP
76SSSSN | PUSH 0 (ptr)
77SNT | SWAP
78TTS | STORE
79
80@ Calculate the random number and return.
81SSSTSSSSSSSSSSSSSSSSN | PUSH 65536
82TSTS | DIVIDE
83SSSTSSSSSSSSSSSSSSSN | PUSH 32768
84TSTT | MODULO
85NTN | RTS
86
3625ff3a 87@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
bb21580a
AT
88@ Name:
89@ abs (10001)
3625ff3a 90@ Description:
bb21580a 91@ Returns the absolute value of its argument
3625ff3a
AT
92@ Call Stack:
93@ signed number <-- TOS
94@ Return Stack:
95@ abs(signed number) <-- TOS
96@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
97NSSVTSSSTN | Mark: 10001 (absolute value)
7359501c
AT
98
99@ Catch -(2^63) as a special case since its absolute value will overflow
100@ a twos-complement 64-bit word. Return zero as though the absolute value
101@ overflowed to the bottom of the non-negative integers rather than
102@ overflowing back to the most negative integer.
103SNS | DUP
104SSTTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSN | -(2^63)
105TSST | SUBTRACT
106NTSSSSTSSSTSSSSSSTSN | BRZ > 00010001 00000010
107
108@ Handle all the other numbers.
3625ff3a
AT
109SNS | DUP
110NTTSSSTSSSTSSSSSSSSN | BMI > 00010001 00000000
111NSNSSSTSSSTSSSSSSSTN | JMP > 00010001 00000001
112NSSVSSSTSSSTSSSSSSSSN | Mark: 00010001 00000000
113SSTTN | PUSH -1
114TSSN | MULTIPLY
115NSSVSSSTSSSTSSSSSSSTN | Mark: 00010001 00000001
116NTN | RTS
117
7359501c
AT
118@ Special case: Push 0 and return.
119NSSVSSSTSSSTSSSSSSTSN | Mark: 00010001 00000010
120SNN | DROP
121SSSSN | PUSH 0
122NTN | RTS
123
37372ed0
AT
124@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
125@ Name:
126@ gcd (10010)
127@ Description:
128@ Returns greatest common divisor of X and Y.
129@ Call Stack:
130@ Y
131@ X <-- TOS
132@ Return Stack:
133@ gcd(X,Y) <-- TOS
134@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
135#include <stack.pvvs>
136NSSVTSSTSN | Mark: 10010 (gcd)
137
138@ Since 1 > -1, transform problem into gcd(abs(X),abs(Y)).
139SNT | SWAP
140NSTTSSSTN | JSR > 10001 (abs)
141SNT | SWAP
142NSTTSSSTN | JSR > 10001 (abs)
143
144@ Verify neither operand is zero.
145SNT | SWAP
146SNS | DUP
147NTSSSSTSSTSSSSSSSSSN | BRZ > 00010010 00000000 (gcd:zero input)
148SNT | SWAP
149SNS | DUP
150NTSSSSTSSTSSSSSSSSSN | BRZ > 00010010 00000000 (gcd:zero input)
151
152@ Verify X != Y and sort X,Y so the smaller is TOS.
153SNS | DUP
154SSSTTN | PUSH 3
155NSTTTSSN | JSR > 1100 (deepdup)
156SNT | SWAP
157TSST | SUBTRACT
158@ TOS> Y-X, X, Y
159NTTSSSTSSTSSSSSSSSTN | BMI > 00010010 00000001 (gcd:swap inputs)
160NSNSSSTSSTSSSSSSSTSN | JMP > 00010010 00000010 (gcd:main loop)
161NSSVSSSTSSTSSSSSSSSTN | MARK: 00010010 00000001 (gcd:swap inputs)
162SNT | SWAP
163
164@ Main gcd loop.
165@ Euclidean algorithm.
166NSSVSSSTSSTSSSSSSSTSN | MARK: 00010010 00000010 (gcd:main loop)
167SNS | DUP
168SSSTTN | PUSH 3
169NSTTSTSN | JSR > 1010 (stackrotate)
170TSTT | MODULO
171SNS | DUP
172NTSSSSTSSTSSSSSSSTTN | BRZ > 00010010 00000011 (gcd:loop termination)
173NSNSSSTSSTSSSSSSSTSN | JMP > 00010010 00000010 (gcd:main loop)
174NSSVSSSTSSTSSSSSSSTTN | MARK: 00010010 00000011 (gcd:loop termination)
175SNN | DROP
176NTN | RTS
177
178@ At least one operand was zero.
179@ Since we define gcd(a,0) = a, return the other operand.
180NSSVSSSTSSTSSSSSSSSSN | MARK: 00010010 00000000 (gcd:zero input)
181SNN | DROP
182NTN | RTS
183
3625ff3a 184#endif