• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Functions for working with the idealized calendar of Planet Xhilr


Commit MetaInfo

Revisión5f908f8d9d9f68d8867420bbd572154aeed29b73 (tree)
Tiempo2017-06-13 17:22:28
AutorJoel Matthew Rees <joel.rees@gmai...>
CommiterJoel Matthew Rees

Log Message

shifting to period code

Cambiar Resumen

Diferencia incremental

--- /dev/null
+++ b/econcalcmonths.fs
@@ -0,0 +1,275 @@
1+(
2+// Forth program for calculating idealized lengths of months
3+// relative to skip years
4+// for the world of Bobbie, Karel, Dan, and Kristie,
5+//
6+// by Joel Matthew Rees, winter/spring 2017.
7+// Copyright 2017, Joel Matthew Rees
8+//
9+// Permission granted to use for personal entertainment only.
10+// -- You really shouldn't write programs like this on modern computers.
11+//
12+// http://joel-rees-economics.blogspot.com/2017/03/soc500-03-08-calendar-math.html
13+// http://joel-rees-economics.blogspot.com/2017/03/soc500-03-09-calculating-skip-years.html
14+//
15+// Novel here:
16+// http://joel-rees-economics.blogspot.com/2017/01/soc500-00-00-toc.html
17+//
18+//
19+// Save as "econcalcmonth.fs"
20+//
21+// In gforth and most modern or emulated environments,
22+// just paste it into the terminal of a running Forth session.
23+//
24+// Run it with
25+// 7 SHOWMONTHS
26+// for seven years, etc.
27+)
28+
29+( Using integer math. )
30+( Forth expression syntax is mostly postfix. )
31+( Only the definition syntax is prefix or infix. )
32+( I've added comments with equivalent infix expressions to help those unfamiliar with Forth. )
33+
34+
35+( Using baroque identifiers for ancient Forths. )
36+( fig-Forth used first three character significant symbol tables. )
37+
38+
39+( For ancient, especially pre-1983 fig, Forths: )
40+( Do not use these in modern Forths like gforth. )
41+: UM* U* ;
42+: FM/MOD M/MOD DROP ; ( Cheat! Behavior is not well defined for negative numbers. )
43+( This is just renaming in a sloppy fashion, )
44+( to accomodate the difference between ancient fig-Forths and modern Forths. )
45+( Showing it in infix won't help. )
46+
47+( Semi-simulate local variables. )
48+SP@ SP@ - ABS CONSTANT CELLWIDTH
49+( Infix won't help here, either, but I can try to explain: )
50+( CELLWIDTH = absolute-value-of difference-between SP-without-pointer and SP-with-pointer. )
51+
52+( Infix will be confusing here, too. )
53+: LC@ ( index -- sp[ix] ) ( 0 is top. PICK is available on many modern Forths. )
54+ 1 + CELLWIDTH * ( Skip over the stack address on stack. )
55+ SP@ + @ ( Assumes push-down stack. Will fail on push-up. )
56+;
57+
58+( Infix will be confusing here, too. )
59+: LC! ( n index -- ) ( 0 is top. Just store. This is not ROLL. )
60+ 2 + CELLWIDTH * ( Index and stack address are extra on stack during calculation. )
61+ SP@ + ( Assumes push-down stack. )
62+ ! ( *** Will fail in MISERABLE ways on push-up stacks! *** )
63+;
64+
65+( Make things easier to read. )
66+( Infix will be confusing here, too. )
67+
68+: PRCH EMIT ;
69+
70+: COMMA 44 PRCH ;
71+: COLON 58 PRCH ;
72+: POINT 46 PRCH ;
73+: LPAREN 40 PRCH ;
74+: RPAREN 41 PRCH ;
75+
76+( No trailing space. )
77+: PSNUM ( number -- )
78+ 0 .R ;
79+
80+
81+( Watch limits on 16 bit processors. )
82+( Do it in integers! )
83+
84+7 CONSTANT SCYCLE ( years in short cycle )
85+( SCYCLE = 7 )
86+
87+7 2 * CONSTANT SPMCYC ( short cycles in medium cycle )
88+( SPMCYC = 7 × 2 )
89+
90+SCYCLE SPMCYC * CONSTANT MCYCLE ( years in medium cycle, should be 98 )
91+( MCYCLE = SCYCLE × SPMCYC )
92+
93+7 7 * CONSTANT SPLCYC ( short cycles in single long cycle )
94+( SPLCYC = 7 × 7 )
95+
96+SCYCLE SPLCYC * CONSTANT LCYCLE ( years in single long cycle, should be 343 )
97+( LCYCLE = SCYCLE × SPLCYC )
98+
99+7 CONSTANT MP2LCYC ( medium cycles in double long cycle )
100+( MP2LCYC = 7 )
101+( MPLCYC would not be an integer: 3 1/2 )
102+
103+MCYCLE MP2LCYC * CONSTANT 2LCYCLE ( years in double long cycle, should be 686 )
104+( 2LCYCLE = MCYCLE × MP2LCYC )
105+
106+352 CONSTANT DPSKIPYEAR ( floor of days per year )
107+
108+
109+5 CONSTANT RDSCYCLE ( remainder days in short cycle )
110+
111+DPSKIPYEAR SCYCLE * RDSCYCLE + CONSTANT DPSCYCLE ( whole days per 7 year cycle )
112+( DPSCYCLE = DPSKIPYEAR × SCYCLE + RDSCYCLE )
113+( DPMCYCLE and DP2LCYCLE would overflow on 16 bit math CPUs. )
114+
115+RDSCYCLE SPMCYC * 1 - CONSTANT RDMCYCLE ( remainder days in medium cycle )
116+( RDMCYCLE = RDSCYCLE × SPMCYC - 1 )
117+
118+RDMCYCLE MP2LCYC * 2 + CONSTANT RD2LCYCLE ( remainder days in double long cycle -- odd number )
119+( RD2LCYCLE = RDMCYCLE × MP2LCYC + 2 )
120+( RD2LCYCLE / 2LCYCLE is fractional part of year. )
121+( Ergo, length of year is DPSKIPYEAR + RD2LCYCLE / 2LCYCLE, )
122+( or 352 485/686 days. )
123+
124+12 CONSTANT MPYEAR ( months per year )
125+
126+DPSKIPYEAR MPYEAR /MOD CONSTANT FDMONTH ( floor of days per month )
127+( FDMONTH = DPSKIPYEAR / MPYEAR )
128+CONSTANT FRMONTH ( floored minimum remainder days per month )
129+( FRMONTH = DPSKIPYEAR MOD MPYEAR )
130+
131+2LCYCLE MPYEAR * CONSTANT MDENOMINATOR ( denominator of month fractional part )
132+( MDENOMINATOR = 2LCYCLE × MPYEAR )
133+
134+FRMONTH 2LCYCLE * RD2LCYCLE + CONSTANT MNUMERATOR ( numerator of month fractional part )
135+( MNUMERATOR = FRMONTH × 2LCYCLE + RD2LCYCLE )
136+( Ergo, length of month is FDMONTH + MNUMERATOR / MDENOMINATOR, )
137+( or 29 3229/8232 days. )
138+
139+MDENOMINATOR 2 / CONSTANT MROUNDFUDGE
140+
141+( Infix will be confusing below here, as well. )
142+( Hopefully, the comments and explanations will provide enough clues. )
143+
144+( Sum up the days of the months in a year. )
145+: SU1MONTH ( startfractional startdays -- endfractional enddays )
146+ 29 + ( Add the whole part. )
147+ SWAP ( Make the fractional part available to work on. )
148+ MNUMERATOR + ( Add the fractional part. )
149+ DUP MDENOMINATOR < ( Have we got a whole day yet? )
150+ IF
151+ SWAP ( No, restore stack order for next pass. )
152+ ELSE
153+ MDENOMINATOR - ( Take one whole day from the fractional part. )
154+ SWAP 1+ ( Restore stack and add the day carried in. )
155+ ENDIF
156+;
157+
158+: PRMONTH ( fractional days -- fractional days )
159+ SPACE DUP PSNUM POINT ( whole days )
160+ OVER 1000 UM* ( Fake three digits of decimal precision. )
161+ MROUNDFUDGE 0 D+ ( Round the bottom digit. )
162+ MDENOMINATOR FM/MOD ( Divide, or evaluate the fraction. )
163+ 0 <# # # # #> ( Formatting puts most significant digits in buffer first. )
164+ TYPE ( Fake decimal output. )
165+ DROP SPACE
166+;
167+
168+: SH1YEAR ( year daysmemory fractional days -- year daysmemory fractional days )
169+ CR
170+ 12 0 DO
171+ 3 LC@ PSNUM SPACE ( year )
172+ I PSNUM COLON SPACE
173+ SU1MONTH
174+ DUP 3 LC@ - ( difference in days )
175+ 2 LC@ ( ceiling ) IF 1+ ENDIF
176+ DUP PSNUM SPACE ( show theoretical days in month )
177+ 3 LC@ + ( sum of days )
178+ LPAREN DUP PSNUM COMMA SPACE
179+ 2 LC! ( update )
180+ PRMONTH RPAREN CR
181+ LOOP
182+;
183+
184+: SHOWMONTHS ( years -- )
185+ >R
186+ 0 0 0 0 ( year, daysmemory, fractional, days )
187+ R> 0 DO
188+ CR
189+ SH1YEAR
190+ 3 LC@ 1+ 3 LC!
191+ LOOP
192+ DROP DROP DROP DROP
193+;
194+
195+
196+( Below here is scratch work I'm leaving for my notes. )
197+( It can be deleted. )
198+
199+: V2-SHOWMONTHS ( years -- )
200+ >R
201+ 0 0 0 ( daysmemory, fractional, days )
202+ R> 0 DO
203+ CR
204+ 12 0 DO
205+ J PSNUM SPACE ( year )
206+ I PSNUM COLON SPACE
207+ SU1MONTH
208+ DUP 3 LC@ - ( difference in days )
209+ 2 LC@ ( ceiling ) IF 1+ ENDIF
210+ DUP PSNUM SPACE ( show theoretical days in month )
211+ 3 LC@ + ( sum of days )
212+ LPAREN DUP PSNUM COMMA SPACE
213+ 2 LC! ( update )
214+ PRMONTH RPAREN CR
215+ LOOP
216+ LOOP
217+ DROP DROP DROP
218+;
219+
220+
221+: NUMERATORS ( count -- )
222+DUP 1+ 0 DO
223+ I PSNUM COLON SPACE
224+ I 1000 * OVER / PSNUM COMMA ( 1000 times I divided by count )
225+ SPACE LOOP
226+DROP ;
227+
228+: FRACTIONS ( count -- )
229+1 DO
230+ I NUMERATORS CR
231+LOOP ;
232+
233+( : ABS number -- absolute-value *** built in! ***
234+DUP 0< IF NEGATE THEN ; )
235+
236+: WITHIN1 ( n1 n2 -- flag )
237+ - ABS 1 <= ; ( n1 and n2 are within 1 of each other )
238+
239+( Negatives end in division by zero or infinite loop. )
240+: SQRT ( number -- square-root )
241+DUP IF ( square root of zero is zero. )
242+ ABS
243+ 2 ( initial guess )
244+ BEGIN
245+ OVER OVER / ( test guess by divide )
246+ OVER OVER - ABS 1 <= ( number guess quotient flag )
247+ IF ( number guess quotient )
248+ MIN -1 ( number result flag )
249+ ELSE
250+ OVER + 2 / ( number guess avg )
251+ SWAP OVER ( number avg guess avg )
252+ - 1 <= ( number avg flag ) ( Integer average will always be floored. )
253+ ENDIF
254+ UNTIL ( number result )
255+ SWAP DROP
256+ENDIF ;
257+
258+
259+353 CONSTANT DPYEAR ( nominal days per year )
260+
261+7 CONSTANT 7YEARS
262+
263+2 CONSTANT DS7CYCLE ( days short in seven year cycle )
264+
265+DPYEAR 7YEARS * DS7CYCLE - CONSTANT DP7YEAR ( whole days per 7 year cycle )
266+
267+7YEARS 7 2 * * CONSTANT 98YEARS
268+
269+98YEARS 7YEARS / DS7CYCLE * 1 + CONSTANT DS98CYCLE ( days short in 98 year cycle )
270+
271+98YEARS 7 * CONSTANT 686YEARS
272+
273+686YEARS 98YEARS / DS98CYCLE * 2 - CONSTANT DS686CYCLE ( days short in 686 year cycle )
274+
275+