Дата православной и католической пасхи.

Тема в разделе "ТЕОЛОГИЯ", создана пользователем Intro, 19 дек 2020.

  1. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    561
    Вот код, который я сам сделал уже не помню когда.
    Код (C):
    1.  
    2. /*============================================
    3.     Julian Day Number   v0.02
    4. (c) NanoBot
    5. ============================================*/
    6. #include <stdio.h>
    7. #include <time.h>
    8. long    GetJDN(struct tm *date)
    9. {
    10.     int     mon, year, k;
    11.     long    JDN = date->tm_mday;
    12.     mon = date->tm_mon;
    13.     year = date->tm_year;
    14.     k = (mon-=2)<0;     /* Новый год 1 марта! */
    15.     year += 4800-k; mon += 12*k;
    16.     JDN += mon*30+(mon%5+1)/2+mon/5*3;
    17.     JDN += year*365+year/4+year/400-year/100-32045;
    18.     return JDN;
    19. }
    20. long    GetMJD(struct tm *date)
    21. {
    22.     struct tm   date0;
    23.     date0.tm_mday   = 17;
    24.     date0.tm_mon    = 11-1; /* ноябрь */
    25.     date0.tm_year   = 1858;
    26.     return GetJDN(date)-GetJDN(&date0);
    27. }
    28. int main(int argc, char *argv[])
    29. {
    30.     struct tm   date;
    31.     long    num_jd;
    32.     char*   strEnd;
    33.     if(argc!=4){
    34.         puts("Usage: JD day mon year\n");
    35.         return 0;
    36.     }
    37.     date.tm_mday = strtol(argv[1], &strEnd, 10);
    38.     if (!*strEnd){
    39.         date.tm_mon = strtol(argv[2], &strEnd, 10) - 1;
    40.         if (!*strEnd){
    41.             date.tm_year = strtol(argv[3], &strEnd, 10);
    42.             if (!*strEnd){
    43.                 num_jd = GetJDN(&date);
    44.                 printf("%d.%02d.%d, JD = %ld/n", date.tm_mday, date.tm_mon, date.tm_year, num_jd);
    45.                 return 0;
    46.             }
    47.         }
    48.     }
    49.     printf("ERROR The integer is expected. %s\r\n", strEnd);
    50.     return 1;
    51. }
    52.  
    У него есть проблема. Неправильно вычисляется номер дня после 4800 года до нашего стиля. Надо бы доработать код.
    ЗЫ
    Да, код я чисто сам создал.
    --- Сообщение объединено, 19 дек 2020 ---
    Ну и в ответку конечно ассемблер UASM.
    Код (ASM):
    1.  
    2. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    3. ;;  Julian Day Number       v0.02
    4. ;;  (c) NanoBot
    5. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    6. .486
    7. .model flat, stdcall
    8. option casemap:none
    9. include msvcrt.inc
    10. include \masm32\macros\macros.asm
    11. include macros.asm
    12. main        PROTO C :dword, :dword, :dword
    13. tm struct
    14.     tm_sec          dword ?
    15.     tm_min          dword ?
    16.     tm_hour         dword ?
    17.     tm_mday         dword ?
    18.     tm_mon          dword ?
    19.     tm_year         dword ?
    20.     tm_wday         dword ?
    21.     tm_yday         dword ?
    22.     tm_isdst        dword ?
    23. tm ends
    24. ;.date
    25. .code
    26. mainCRTStartup proc
    27. local argc:sdword, argv:ptr, environ:ptr, StartInfo:_startupinfo
    28.     and     StartInfo.newmode, 0
    29.     __getmainargs(&argc, &argv, &environ, 0, &StartInfo)
    30.     .if (eax==0)
    31.         main(argc, argv, environ)
    32.     .endif
    33.     _exit(eax)
    34. mainCRTStartup endp
    35. int_div MACRO a:req, b:req
    36. IFDIFI <a>, <eax>
    37.     mov     eax, a
    38. ENDIF
    39.     mov     ecx, b
    40.     cdq
    41.     idiv    ecx
    42. ENDM
    43. int_div$ MACRO a:req, b:req
    44.     int_div a, b
    45.     EXITM   <eax>
    46. ENDM
    47. align_proc
    48. GetJDN proc (dword) uses esi edi ebx date:ptr tm
    49.     mov     edx, date
    50.     ASSUME  edx:ptr tm
    51.     mov     esi, [edx].tm_mday  ;JDN
    52.     mov     ebx, [edx].tm_mon   ;mon
    53.     mov     edi, [edx].tm_year  ;year
    54.     ASSUME  edx:nothing
    55.     ;k = (mon-=2)<0;    /* Новый год 1 марта! */
    56.     xor     eax, eax
    57.     sub     ebx, 2
    58.     setl    al
    59.     neg     eax     ;k= mon<0 ? -1 : 0;
    60.     ;year += 4800-k;
    61.     lea     edi, [edi+eax+4800]
    62.     ;mon += 12*k;
    63.     and     eax, 12
    64.     add     ebx, eax
    65.     ;JDN += mon*30+(mon%5+1)/2+mon/5*3;
    66.     imul    eax, ebx, 30
    67.     add     esi, eax
    68.     int_div ebx, 5
    69.     inc     edx
    70.     shr     edx, 1  ;/=2
    71.     lea     eax, [eax*2+eax]    ;*=3
    72.     add     esi, edx
    73.     add     esi, eax
    74.     ;JDN += year*365+year/4+year/400-year/100-32045;
    75.     imul    eax, edi, 365
    76.     add     esi, eax
    77.     add     esi, int_div$(edi, 4)
    78.     add     esi, int_div$(edi, 400)
    79.     sub     esi, int_div$(edi, 100)
    80.     lea     eax, [esi-32045]
    81.     ret
    82. GetJDN endp
    83. ;align_proc
    84. ;GetMJD proc date:ptr tm
    85. ;local date0:tm
    86. ;   mov     date0.tm_mday,  17
    87. ;   mov     date0.tm_mon,   11-1    ;ноябрь
    88. ;   mov     date0.tm_year,  1858
    89. ;   mov     ebx, GetJDN(date)
    90. ;   sub     ebx, GetJDN(&date0)
    91. ;   mov     eax, ebx
    92. ;   ret
    93. ;GetMJD endp
    94. align_proc
    95. main proc C argc:sdword, argv:ptr ptr, envp:ptr ptr
    96. local date:tm, strEnd:ptr byte
    97.     mov     esi, argv
    98.     .if (argc!=4)
    99.         printf("Usage: JD day mon year\n")
    100.         xor     eax, eax
    101.         ret
    102.     .endif
    103.     ASSUME  eax:ptr byte
    104.     mov     date.tm_mday, strtol([esi+1*4], &strEnd, 10)
    105.     mov     eax, strEnd
    106.     .if ([eax]==0)
    107.         strtol([esi+2*4], &strEnd, 10)
    108.         dec     eax
    109.         mov     date.tm_mon, eax
    110.         mov     eax, strEnd
    111.         .if ([eax]==0)
    112.             mov     date.tm_year, strtol([esi+3*4], &strEnd, 10)
    113.             mov     eax, strEnd
    114.             .if ([eax]==0)
    115.                 GetJDN(&date)
    116.                 printf("%d.%02d.%d, JD = %ld/n", date.tm_mday, date.tm_mon, date.tm_year, eax)
    117.                 xor     eax, eax
    118.                 ret
    119.             .endif
    120.         .endif
    121.     .endif
    122.     ASSUME  eax:nothing
    123.     printf("ERROR! The integer is expected. %s\n", strEnd)
    124.     mov     eax, 1
    125.     ret
    126. main endp
    127. end mainCRTStartup
    128.  
    Код ( (Unknown Language)):
    1.  
    2. @echo off
    3. ..\..\..\uasm246_x86\bin\uasm32 /c /coff /I\assemblers\uasm246_x86\include JD.asm
    4. \masm32\bin\link /SUBSYSTEM:CONSOLE /LIBPATH:\assemblers\uasm246_x86\lib JD.obj
    5. rem ..\..\..\uasm246_x86\bin\polink
    6. if exist JD.obj del JD.obj
    7. pause
    8.  
    Если что код своих библиотек потом вылажу. Я грозился для UASM MS-DOS сделать стандартную библиотеку сделать. Ладно!
     
    Последнее редактирование: 19 дек 2020
  2. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    561
    Я помню, тут уже это выкладывал. Вот только совсем не подходящей теме.
    Код (C):
    1.  
    2. /*=====================================================
    3. Дата православной и католической пасхи.
    4. По формуле Карла Фридриха Гаусса (1777-1855).
    5. Календарь и хронология. Климишин И.А. 1990, стр. 133
    6. (c) Intro  v1.04    5.04.2019       2.04.2020
    7. ======================================================*/
    8. #include <stdio.h>
    9. #include <stdlib.h>
    10. #ifndef bool
    11. #define     bool        char
    12. #define     true        1
    13. #define     false       0
    14. #endif
    15. typedef struct _Sdate {
    16.     int     day;    /* 1-31 */
    17.     int     mon;    /* 1-12 */
    18. } Sdate;
    19. /* Расхождение между новым и старым стилем, дней. */
    20. int NewStyleDay(int year)
    21. {
    22.     int century = year/100;
    23.     return (century/4)*3 + century%4 - 2;
    24. }
    25. /* номер дня от 1 марта в Sdate */
    26. const int   days_in_year[12] = {31,30,31,30,31,31,30,31,30,31,31,28};
    27. void    NumDay2Data(Sdate *date, int day)
    28. {
    29.     int mon;
    30.     for(mon=0; mon<12 && day>days_in_year[mon]; ++mon)
    31.         day -= days_in_year[mon];
    32.     date->day = day;
    33.     date->mon = mon+3;
    34. }
    35. int GetEasterGauss(int year, int m, int n, bool is_catholic)
    36. {
    37.     int a,b,c,d,e,day;
    38.     a = year % 19;
    39.     b = year % 4;
    40.     c = year % 7;
    41.     d = (19*a + m) % 30;
    42.     e = (2*b + 4*c + 6*d + n) % 7;
    43.     day = 22 + d + e;
    44.     if (is_catholic && (day>=56 && e==6)) day -= 7;
    45.     return day;
    46. }
    47. int GetOrthodoxEaster(int year)     /* православная пасха */
    48. {
    49.     return GetEasterGauss(year, 15, 6, false);
    50. }
    51. int GetCatholicEaster(int year)     /* католическая пасха */
    52. {
    53.     int M,N,p,q,century;
    54.     century = year/100;
    55.     p = (century*8 + 13)/25;
    56.     q = century/4;
    57.     M = (century - p - q + 15) % 30;
    58.     N = (century - q + 4) % 7;
    59.     return GetEasterGauss(year, M, N, true);
    60. }
    61. int main(int argc, char *argv[])
    62. {
    63.     Sdate   old_s, new_s;
    64.     int     year, day;
    65.     if(argc!=2){
    66.         puts("Usage: easter year\n");
    67.         return 0;
    68.     }
    69.     year = atoi(argv[1]);
    70.     day = GetOrthodoxEaster(year);  /* old style */
    71.     NumDay2Data(&old_s, day);
    72.     day += NewStyleDay(year);
    73.     NumDay2Data(&new_s, day);
    74.     printf("Orthodox easter in %d:\n", year);
    75.     printf("Old style: %2d.%02d New style: %2d.%02d\n", old_s.day, old_s.mon, new_s.day, new_s.mon);
    76.     day = GetCatholicEaster(year);  /* new style */
    77.     NumDay2Data(&new_s, day);
    78.     day -= NewStyleDay(year);
    79.     NumDay2Data(&old_s, day);
    80.     printf("Catholic easter in %d:\n", year);
    81.     printf("Old style: %2d.%02d New style: %2d.%02d\n", old_s.day, old_s.mon, new_s.day, new_s.mon);
    82.     return 0;
    83. }
    84.  
    Так же есть проблемы, если год задан слишком большой, но в пределах до 3000 года дата вычисляется точно.
     
    RETN и Ronin_ нравится это.
  3. RETN

    RETN Member

    Публикаций:
    4
    Регистрация:
    4 апр 2020
    Сообщения:
    74
    СПС БРО
     
    ryuk нравится это.
  4. Intro

    Intro Active Member

    Публикаций:
    0
    Регистрация:
    29 авг 2009
    Сообщения:
    561
    Блиннн, аптимизатыр хреныф.
    Код (C):
    1.  
    2. /*============================================
    3.     Julian Day Number   v0.02
    4. (c) NanoBot
    5. ============================================*/
    6. #include <stdio.h>
    7. #include <time.h>
    8. long    GetJDN(struct tm *date)
    9. {
    10.     int     mon, year, k;
    11.     long    JDN = date->tm_mday;
    12.     mon = date->tm_mon;
    13.     year = date->tm_year;
    14.     k = (mon-=2)<0;     /* Новый год 1 марта! */
    15.     year += 4800-k; mon += 12*k;
    16.     JDN += mon*30+(mon%5+1)/2+mon/5*3;
    17.     JDN += year*365+year/4+year/400-year/100-32045;
    18.     return JDN;
    19. }
    20. long    GetMJD(struct tm *date)
    21. {
    22.     struct tm   date0;
    23.     date0.tm_mday   = 17;
    24.     date0.tm_mon    = 11-1; /* ноябрь */
    25.     date0.tm_year   = 1858;
    26.     return GetJDN(date)-GetJDN(&date0);
    27. }
    28. int main(int argc, char *argv[])
    29. {
    30.     struct tm   date;
    31.     long    num_jd;
    32.     char*   strEnd;
    33.     if(argc!=4){
    34.         puts("Usage: JD day mon year\n");
    35.         return 0;
    36.     }
    37.     date.tm_mday = strtol(argv[1], &strEnd, 10);
    38.     if (!*strEnd){
    39.         int mon = strtol(argv[2], &strEnd, 10);  /* 1..12 */
    40.         if (!*strEnd){
    41.             date.tm_year = strtol(argv[3], &strEnd, 10);
    42.             if (!*strEnd){
    43.                 date.tm_mon = mon-1;
    44.                 num_jd = GetJDN(&date);
    45.                 printf("%d.%02d %d, JD = %ld/n", date.tm_mday, mon, date.tm_year, num_jd);
    46.                 return 0;
    47.             }
    48.         }
    49.     }
    50.     printf("ERROR The integer is expected. %s\r\n", strEnd);
    51.     return 1;
    52. }
    53.  
     
    Последнее редактирование: 20 дек 2020