PureBasic

Forums PureBasic
Nous sommes le Sam 24/Aoû/2019 8:30

Heures au format UTC + 1 heure




Poster un nouveau sujet Répondre au sujet  [ 3 messages ] 
Auteur Message
 Sujet du message: AbsDayNumToDate en ASM (pour archive)
MessagePosté: Mar 17/Déc/2013 17:29 
Hors ligne

Inscription: Mer 14/Sep/2011 16:59
Messages: 904
Code:
; DWORD AbsDayNumToDate(DWORD N, DWORD Gregorian, DWORD* Y, DWORD* M, DWORD* D)
;
; This function converts the absolute day number N = 1, 2, ..., 2^32-1 to the adequate date (for the chosen calendar).
;
; Parameters:
;   N - absolute day number,
;   Gregorian - chosen calendar (0 - Julian, 1 - Gregorian),
;   Y - pointer to variable where the calculated year number will be stored,
;   M - pointer to variable where the calculated month number will be stored,
;   D - pointer to variable where the calculated day number will be stored.
;
; Returned values:
;   * 0 for the valid parameters (N, Gregorian),
;   * -1 in opposite case.
Procedure AbsDayNumToDate( N.l, Gregorian.l, Y.l, M.l, D.l)
   ;PUSHFD
   ;PUSH   ebx ecx edx
   Protected.l tmpeax, tmpecx, tmpedx, tmpeflags, tmp

EnableASM
   CMP   N, 0                     ; N <> 0 ; l'année  n'existe pas
   JE   l_absdaynumtodate_error                     ;

   TEST   Gregorian, -2      ; 0 <= Gregorian <= 1
   JNZ   l_absdaynumtodate_error                     ;

   XOR   ecx, ecx               ; ecx := 0
   
   MOV   eax, N                 ; eax := N - 1
   DEC   eax                       ;

   CMP   Gregorian, 0
   JE   l_absdaynumtodate_julian

   gregorian:
   CMP   eax, 1   
   JA   l_absdaynumtodate_nextdays ;Jump short if above (CF=0 and ZF=0).
                                 ; 0 <= eax <= 1 (1 <= N <= 2)
      MOV   ecx, M               ; M := 12                        
      MOV   dword [ecx], 12               ;

      ADD   eax, 30               ; eax := eax + 30 = N - 1 + 30 = N + 29

      MOV   ecx, D               ; D := eax = N + 29
      MOV   [ecx], eax         ;

      MOV   ecx, -5844001   ; -k*G - 1      ; ecx := -kG - 1 = -5844001
;       Global k   = 30
;     Global J   = 194796      ; The constants J and G are equal to the numbers of the complete years
;     Global G   = 194800      ; of the Julian and Gregorian calendars respectively contained in the
                                ; time interval given by "Great Cycle" T.

      JMP   l_absdaynumtodate_yearr

   nextdays:                       ; eax > 1 (N > 2)
      SUB   eax, 2                  ; eax := eax - 2 = N - 1 - 2 = N - 3
      XOR   edx, edx               ;
;       Global C1   = 365         ; Number of days in a normal year.
;     Global C4   = 4*C1 + 1   = 1461   ; Number of days in the 4-year cycle (base cycle of the Julian calendar).      
;     Global C100   = 25*C4 - 1   = 36524; Number of days in a "normal" century in the Gregorian calendar
;                             ; (i.e. century ending with a normal, 365-day, year).
;     Global C400   = 4*C100 + 1   = 146097   ; Number of days in the complete 400-year cycle of the Gregorian calendar.


      MOV   ecx, 146097   ;C400               ; eax := E(eax / C400) = E((N - 3) / C400)
      DIV   ecx                  ; edx := eax mod C400 = (N - 3) mod C400

      LEA   eax, [eax + 4*eax]   ; eax := 5*eax = 5*E((N - 3) / C400)
      LEA   eax, [eax + 4*eax]   ; eax := 5*eax = 5*(5*E((N - 3) / C400)) =
                                  ; = 25*E((N - 3) / C400)

      SHL   eax, 4                    ; eax := 16*eax = 16*(25*E((N - 3) / C400)) =
                                     ; = 400*E((N - 3) / C400)

      XCHG   ecx, eax               ; ecx := eax = 400*E((N - 3) / C400)
                           
   
      XCHG   eax, edx               ; eax := edx = (N - 3) mod C400
                     

      centuries:                  ;
      CMP   eax, 36524    ; C100            

         JB   l_absdaynumtodate_julian   ;Jump short if below (CF=1).
                        
         ADD   ecx, 100            
         SUB   eax, 36524    ; C100            
                        
         CMP   eax, 36524    ; C100            ; (eax, ecx) := P(eax, ecx) =
         JB   l_absdaynumtodate_julian      ;             = P((N - 3) mod C400, 400*E((N - 3) / C400)) =
                                 ; = (N100, Y100)
         ADD   ecx, 100            
         SUB   eax, 36524    ; C100            
                           
         CMP   eax, 36524    ; C100            
         JB   l_absdaynumtodate_julian               
                           
         ADD   ecx, 100            
         SUB   eax, 36524    ; C100            

julian:
                           ;                             /
                           ;                             |  (N - 1, 0)                                 ; Gregorian = 0
                           ; (N100, Y100) = (eax, ecx) = <
                           ;                             |  P((N - 3) mod C400, 400*E((N - 3) / C400)) ; Gregorian = 1
                           ;                             \
    PUSH ecx
      XOR   edx, edx               
      MOV   ecx, 1461 ; C4   ; eax := E(eax / C4) = E(N100 / C4)
      DIV   ecx            ; edx := eax mod C4 = N100 mod C4
      POP ecx
      
      SHL   eax, 2      ; eax := 4*eax = 4*E(N100 / C4)

      ADD   ecx, eax   ; ecx := ecx + eax = Y100 + 4*E(N100 / C4)

      years:                     
         INC   ecx               
         
         CMP   edx, 365 ; C1               
         JB   l_absdaynumtodate_md               
                        
         SUB   edx, 365 ; C1               
                           
         INC   ecx                       ; (edx, ecx) := Q(edx, ecx) =
         CMP   edx, 365 ; C1               ; = Q(N100 mod C4, Y100 + 4*E(N100 / C4)) =
         JB   l_absdaynumtodate_md   ; = (N', Y*)
                           
         SUB   edx, 365 ; C1               
                              
         INC   ecx               
         CMP   edx, 365 ; C1               
         JB   l_absdaynumtodate_md               
                           
         SUB   edx, 365 ; C1               
                           
         INC   ecx               

   md:
      INC   edx                  ; edx := edx + 1 = N' + 1
   
      ;sauvegarde
      MOV tmpeax, eax
      MOV tmpecx, ecx
      MOV tmpedx, edx

      IsLeapYear(tmpecx, Gregorian)         ; eax := IsLeapYear(ecx=year, Gregorian) =
                                        ; = IsLeapYear(Y*, Gregorian)
    MOV tmpeax, eax

      ;DayNumToMD(n.l, LeapYearFlag.l, M.l, D.l)
    DayNumToMD(tmpedx, tmpeax, M, D)

      MOV ecx, tmpecx
      MOV edx, tmpedx
      
      CMP   Gregorian, 0
      JE   l_absdaynumtodate_julianyears

      gregorianyears:               
         SUB   ecx, 120  ;k*(G - J)            ;k*(G - J)=180
                             ; ecx := ecx - kJ - k(G - J)[Gregorian = 1] =
      julianyears:      ;      = Y* - kJ - k(G - J)[Gregorian = 1] =
         SUB   ecx, 5843880  ;k*J            ; = Y';k*J=5843880

         CMP   ecx, 0
         JG   l_absdaynumtodate_yearr
                             ; ecx <= 0 (Y' <= 0)

         DEC   ecx            ; ecx := ecx - 1 = Y' - 1 = Y' - [Y' <= 0]

      yearr:
         MOV   eax, Y      ; Y := ecx
         MOV   [eax], ecx            

      XOR   eax, eax
      JMP   l_absdaynumtodate_theend

   error:
      MOV   eax, -1

   theend:

   ;POP   edx ecx ebx
   ;POPFD

   DisableASM
ProcedureReturn

EndProcedure


M.


Dernière édition par Mesa le Jeu 19/Déc/2013 18:56, édité 2 fois.

Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: AbsDayNumToDate en ASM (pour archive)
MessagePosté: Mar 17/Déc/2013 17:48 
Hors ligne
Avatar de l’utilisateur

Inscription: Dim 22/Aoû/2010 15:24
Messages: 6849
Localisation: IDF (Yvelines)
Le resultat
Code:
Debug AbsDayNumToDate(2135207292,1,@Y, @M, @D );  N, Gregorian, Y, M, D
Debug D
Debug M
Debug Y
N'est pas du tout le même que
Code:
Debug Day(2135207292)
Debug Month(2135207292)
Debug Year(2135207292)

_________________

➽ Config PureBasic : i3, RAM 4Go, NVidia (1024 Mo), Windows 10 - PB 5.70 LTS
➽ Je papote aussi sur http://purebasic.chat

➽ Sites personnels http://falsam.com & EasySprite.js

➽ Je ne réponds pas aux MP techniques


Haut
 Profil  
Répondre en citant le message  
 Sujet du message: Re: AbsDayNumToDate en ASM (pour archive)
MessagePosté: Mer 18/Déc/2013 9:23 
Hors ligne

Inscription: Mer 14/Sep/2011 16:59
Messages: 904
C'est tout à fait normal car le "2135207292" est un nombre de jours à partir du 30 Dec -5844001 (environ) alors que les fonctions DATE de PureBasic utilisent un nombre de secondes écoulées à partir du '01/01/1970 0:00:00'


M.


Haut
 Profil  
Répondre en citant le message  
Afficher les messages postés depuis:  Trier par  
Poster un nouveau sujet Répondre au sujet  [ 3 messages ] 

Heures au format UTC + 1 heure


Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 1 invité


Vous ne pouvez pas poster de nouveaux sujets
Vous ne pouvez pas répondre aux sujets
Vous ne pouvez pas éditer vos messages
Vous ne pouvez pas supprimer vos messages

Rechercher:
Aller à:  
cron

 


Powered by phpBB © 2008 phpBB Group | Traduction par: phpBB-fr.com
subSilver+ theme by Canver Software, sponsor Sanal Modifiye