Leap days (or not) in February for PBDOS
#3
Bit optimized routines, regarding to your thoughts:

Code:
Declare _
FUNCTION iFeb(ByVal iJahr As Integer)        As Integer
'----------------------------------------------------------------------------
' Optimize the BASIC code for speed
FUNCTION iFeb(ByVal iJahr As Integer) Public As Integer
  '--------------------------------------------------------------------------
  ' Use a temporary variable to reduce calculationtime
  Dim iJahriDiv4 As Local Integer
  '--------------------------------------------------------------------------
  ' Optimize the BASIC's mathematics - thanks to Dale Yarker
  $If 0
    Arithmetic ops by powers of 2 can be done a bit faster by not using
    *, \ or MOD (likely you know of 2 them). For example:
    X * 4 can be SHIFT LEFT X, 2
    X \ 4 can be SHIFT RIGHT X, 2
    X MOD 4 can be X AND 3
    Those can be done in BASIC code so difference between BASIC and ASM
    timing may be made smaller.
    MOD is a divide with the remainder returned instead of the quotient.
    Your BASIC code can be quicker with MOD 100 and MOD 400 than 2 divides
    by 100 and 2 divides by 400.
    In ASM the DIV instruction returns both quotient and remainder. 100 is
    not a power 0f 2, so had to divide by 100. The remainder used as
    MOD 100 and quotient used with X AND as MOD 400.
    The 1,15 times faster for 1204 and 1201 shows how small the difference
    is between MOD and AND.)
  $EndIf
  iJahriDiv4  = iJahr
  SHIFT RIGHT    iJahriDiv4, 2%
  if iJahr < 1582% then
    Function = 29% _
            + ((iJahr AND 3)<>0%)
  else
    Function = 29% _
            + ( _
                (iJahr/4%) <> iJahriDiv4  _
                OR _        _
                (iJahr/100%)=(iJahr\100%) _
                AND _
                (iJahr/400%)<>(iJahr\400%) _
              )
  end if
END FUNCTION
Declare _
Function iTage_im_Februar(byval iJahr as integer) as integer
'----------------------------------------------------------------------------
' Optimize the BASIC code for speed
Function iTage_im_Februar(byval iJahr as integer) as integer
  Dim iFebruarTage As Local Integer
  ! mov iFebruarTage, 28%              ; not a leap year, pre-set to 28
  ! mov ax, 1582%
  ! cmp ax, iJahr
  ! jge Julian
  ! mov ax, 3%
  ! and ax, iJahr                      ; conditionally equivalent MOD 4
  ! jz MOD100                          ; 0 is possible leap year
  ! jmp Done
MOD100:
                                      ' remainder (MOD)
  ! xor dx, dx
  ! mov ax, iJahr
  ! mov bx, 100%
  ! div bx
  ! cmp dx, 0%                        ; does MOD 100 = 0 ?
  ! jz MOD400                          ; 0 is possibly not a leap year
  ! jmp Is29Days                      ; non 0 is a leap year
MOD400:
  ! and ax, 3%                        ; AX has Year\100, so conditionally
                                      ' equivalent MOD 400
  ! jnz Done
Julian:
  ! mov ax, 3%
  ! and ax, iJahr
  ! jnz Done
Is29Days:
  ! mov iFebruarTage, 29%
Done:
  function = iFebruarTage
End Function
Reply


Messages In This Thread
RE: Leap days (or not) in February for PBDOS - by Andy Dee - 03-09-2025, 05:05 PM

Forum Jump:


Users browsing this thread: 1 Guest(s)