【发布时间】:2021-06-08 07:46:56
【问题描述】:
我尝试应用 zeller 收敛简化方法从用户输入的日期中获取日期名称。
来自
的简化算法\ Zeller's Congruence
variable year 2 allot
variable day 2 allot
variable mounth 2 allot
variable century 2 allot
variable daynumber 1 allot
variable k 2 allot
variable j 2 allot
\ read keyboard word input
: input$ ( n -- addr n )
pad swap accept
pad swap
;
\ check input type
: input# ( -- u true | false )
0. 16 input$ dup >R
>number nip nip
R> <> dup 0 = if
nip
then
;
\ get all year mounth and day to check
: readyear
CR ." Year ? "
input# if
year !
else
cr ." Must be a number" cr
bye
then
year @ dup >r 99 > r> 1 < or if \ more forth way to write it
cr ." Must be lower than 99 and gregorian date ( so also over 1752 September 2cd)" cr
bye
then
;
: readday
CR ." Day ? "
input# if
day !
else
cr ." Must be a number" cr
bye
then
day @ dup >r 31 > r> 1 < or if
cr ." Must be between 1 and 31" cr ( is user stupid ? )
bye
then
;
: ?adaptday
\ NOTE: In this algorithm January and February are
\ counted as months 13 and 14 of the previous
\ year.E.g. if it is 2 February 2010, the
\ algorithm counts the date as the second day
\ of the fourteenth month of 2009 (02/14/2009
\ in DD/MM/YYYY format)
mounth @ case
1 of
mounth 13 !
year @ 1- !
endof
2 of
mounth 14 !
year @ 1- !
endof
endcase
\ 13(m+1) K J
\ daynumber = ( day + (-------) + k + (---) + (---) + 5j ) %7
\ 5 4 4
year 100 mod k !
year 100 / j !
day @ mounth @ 1 + 13 * 5 / + \ day + ((13*(m-1))/5)
k @ + \ day + ((13*(m-1))/5) + k
k @ 4 / + \ day + ((13*(m-1))/5) + k + k/4
J @ 4 / + \ day + ((13*(m-1))/5) + k + k/4 + J/4
J @ 5 * + \ day + ((13*(m-1))/5) + k + k/4 + J/4 + 5J
7 mod daynumber ! \ (day + ((13*(m-1))/5) + k + k/4 + J/4 + 5J) %7
\ 1 line for each sub calculation just for better mathematical reading
daynumber @ case
0 of cr ." Saturday !" cr bye endof
1 of cr ." Sunday !" cr bye endof
2 of cr ." Monday !" cr bye endof
3 of cr ." Tuesday !" cr bye endof
4 of cr ." Wednesday !" cr bye endof
5 of cr ." Thursday !" cr bye endof
6 of cr ." Friday !" cr bye endof
endcase
;
\ main function
: main
page
cr
>readvars
?adaptday
cr cr
bye
;
main
语法似乎没问题,但方法或错误/失败的功能可能是根本原因。
输入很好,但随机获得的日期不是好的一天(即使是同一天)
所以我可能没有做某事&在这里我未优化代码以尝试调试它,但我还没有找到原因。
这是一个执行示例:
插入日期:
????francois@????zaphod????:~/GITLAB/dev/dev_gforth_calendar$ gforth zellersconvergence_bugged.fs
redefined k redefined j
Insert a decomposed date :
Century ? 20
Year ? 21
Mounth ? 6
Day ? 8
Tuesday !
????francois@????zaphod????:~/GITLAB/dev/dev_gforth_calendar$ gforth zellersconvergence_bugged.fs
redefined k redefined j
Insert a decomposed date :
Century ? 20
Year ? 21
Mounth ? 6
Day ? 8
Saturday !
????francois@????zaphod????:~/GITLAB/dev/dev_gforth_calendar$ gforth zellersconvergence_bugged.fs
redefined k redefined j
Insert a decomposed date :
Century ? 20
Year ? 21
Mounth ? 6
Day ? 8
Monday !
????francois@????zaphod????:~/GITLAB/dev/dev_gforth_calendar$
可能是堆栈问题? 可能是方法问题? 那么算法本身可能是一个被误解的东西?
谢谢
【问题讨论】:
-
最好不要从单词中执行
bye。这样您就有机会检查变量并在终端会话中重新运行代码。最初的问题是对变量的地址而不是它们的内容求和。@s 不见了。因此,当程序重新加载时,它们可能位于不同的地址,因此会给您不同的答案。 -
哦,你说得对,例如,我错过了
year @,再见,我将标记退出状态,谢谢。
标签: calendar calculation date-arithmetic forth gforth