从Gforth中的用户指定日期获取日期名称



我尝试应用Zeller的收敛简化方法从用户输入日期中获取日期名称。

的简化算法

 Zeller's Congruence
variable year       2   allot
variable day        2   allot
variable month      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 month 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)
month @ case
1 of
month 13 !
year @ 1- !
endof
2 of
month 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 @ month @ 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

语法似乎还可以,但方法或错误/失败的函数可能是根本原因。

输入很好,但随机获得的日期并不好(即使是同一天(。

所以我可能没能做点什么&在这里,我取消了代码的优化,试图调试它,但我还没有找到原因。

下面是一个执行示例:

插入日期:

gforth zellersconvergence_bugged.fs
redefined k  redefined j

Insert a decomposed date:
Century ? 20
Year    ? 21
Mounth  ? 6
Day     ? 8
Tuesday        !

gforth zellersconvergence_bugged.fs
redefined k  redefined j

Insert a decomposed date:
Century ? 20
Year    ? 21
Mounth  ? 6
Day     ? 8
Saturday       !

gforth zellersconvergence_bugged.fs
redefined k  redefined j

Insert a decomposed date:
Century ? 20
Year    ? 21
Mounth  ? 6
Day     ? 8
Monday         !

这会是堆栈问题吗?

这会是一个方法问题吗?

这可能是算法内部被误解的东西吗?

您需要两次从年份变量year @ 100 ...中获取数据。我认为在那之后?adaptday会起作用。第四个单词within n lo hi -- flag ; flag is True if lo <= n < hi用于检查范围内的数字,

在Forth中,使用这么多变量是不寻常的。这些值通常存储在堆栈中。作为变量的j可以覆盖用作外部do循环计数器的j。我也看到k用于下一个外循环!!

我会这样实现它。然后,我可以使用堆栈输入在控制台中运行这些单词,看看发生了什么来帮助调试。

: century-ix   c -- days-ix
dup 4/ swap 5 * + 
;
: year-ix    yy -- days-ix
dup 4/ +  
;
: month-ix   mm - days-ix
1+ 13 * 5 / 
;
: weekday  dd mm yyyy -- dow
over 3 < if
swap 12 + swap 1-   adjusts Jan and Feb to be month 13 or 14 of previous year.
then 
100 /mod  ( dd mm yy cc )
century-ix            ( dd mm yy days )
swap year-ix +        ( dd mm days )
swap month-ix + +      Calculate for months and days
7 mod 
; 
: weekday.   n -- ;  -- Prints weekday in English
  Too useful to hide in another definition.
case
0 of cr ."      Saturday       !" cr  endof
1 of cr ."      Sunday         !" cr  endof
2 of cr ."      Monday         !" cr  endof
3 of cr ."      Tuesday        !" cr  endof
4 of cr ."      Wednesday      !" cr  endof
5 of cr ."      Thursday       !" cr  endof
6 of cr ."      Friday         !" cr  endof
endcase
; 
8 6 2021 weekday weekday. 
Tuesday        !

相关内容

  • 没有找到相关文章

最新更新