Announcement

Collapse
No announcement yet.

FASTPROCs for "ODD" and "EVEN"

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • FASTPROCs for "ODD" and "EVEN"

    Currently i have not many Fastprocs in use. Most often in such cases i rather use MACROS.
    Now i found two that i want to share.
    They do return 0 or 1 depending if the Input-Integer is ODD or EVEN.

    Code:
    ' ODD-Function (ungerade)
    ' Rückgabe ist 1 wenn ungerade Zahl, 0 bei gerader Zahl.
    ' Bei 0 - Rückgabe ist 0
    FASTPROC A_AA(BYVAL R01 AS LONG) AS LONG
    STATIC b AS BYTE
    ! MOV b,0
    ! MOV eax,R01
    ! AND eax,1
    ! JZ L1
    ! MOV b,1
    L1:
    END FASTPROC=b
    
    MACRO ODD(P1) = A_AA(P1)
    
    '----------------------------------------------------------------------------------
    
    ' EVEN-Function (ungerade)
    ' Rückgabe ist 1 wenn gerade Zahl, 0 bei ungerader Zahl.
    ' Bei 0 - Rückgabe ist 1
    FASTPROC A_AB(BYVAL T01 AS LONG) AS LONG
    STATIC b AS BYTE
    ! MOV b,0
    ! MOV eax,T01
    ! AND eax,1
    ! JNZ L1
    ! MOV b,1
    L1:
    END FASTPROC=b
    
    MACRO EVEN(P1) = A_AB(P1)
    --Theo Gottwald
    ------------------------------------------------
    76706 Dettenheim * Germany * info@it-berater.org
    ------------------------------------------------
    Joses Forum * Theo's Link Site * IT-Berater.org

  • #2
    There are shorter ways which also avoid the jump.
    Code:
    'PBCC6 program
    FUNCTION PBMAIN () AS LONG
    
    LOCAL b AS BYTE
    LOCAL a AS LONG
    
    FOR a = -10 TO 10
    
        !test a,1     'look at the first bit of a
        !setnz b      'set b to 0 or 1 depending on the result of the test
      '  !setz b       'this would give the opposite to setnz
    
        PRINT a,b
    
    NEXT
    
    WAITKEY$
    
    END FUNCTION

    Comment


    • #3
      Paul, your ASM Knowledge is amazing. You and Hutch are my 2 favourites in this topic.
      --Theo Gottwald
      ------------------------------------------------
      76706 Dettenheim * Germany * info@it-berater.org
      ------------------------------------------------
      Joses Forum * Theo's Link Site * IT-Berater.org

      Comment


      • #4
        Here is another technique.
        Code:
        ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
        
            #compile exe "oddeven.exe"
        
        ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
        
         FUNCTION PBmain as LONG
        
            LOCAL oddnum as DWORD
            LOCAL evnnum as DWORD
        
            PREFIX "!"
        
            mov oddnum, 3333
            mov evnnum, 4444
        
            and oddnum, &B00000000000000000000000000000001
            and evnnum, &B00000000000000000000000000000001
        
            END PREFIX
        
            StdOut "odd number  = "+bin$(oddnum)
            StdOut "even number = "+bin$(evnnum)
        
            waitkey$
        
         End FUNCTION
        
        ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
        hutch at movsd dot com
        The MASM Forum

        www.masm32.com

        Comment


        • #5
          Code:
          #compile exe
          #dim all
          'PBMain makes the two FastProcs compilable, and a place for a quick demo.
          function pbmain () as long
            local A_Num, Other_Num as long
            A_Num = 3
            Other_Num = 2
            ' test Is_Odd -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
            if Is_Odd(A_Num) then
              ? "3 is odd"
            end if
            if isfalse Is_Odd(Other_Num) then
              ? "2 is not odd"
            end if
            ' test Is_Even   -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
            if Is_Even(Other_Num) then
              ? "2 is even"
            end if
            if isfalse Is_Even(A_Num) then
              ? "3 is not even"
            end if
            waitkey$
          end function
          '===============================================================================
          ' Thinking more of "many ways to skin a cat" than a speed competion, I
          ' submit the following two functions.
          ' Couldn't resist getting rid of the BYTE variable in each function.
          ' (THAT is a slow down!)
          ' Odd or Even depends solely on least significant bit.
          '-------------------------------------------------------------------------------
          ' ODD Function
          ' Returns non-zero if input number is odd, zero if even.
          fastproc Is_Odd(byval R01 as long) as long
            'R01 is BYVAL so no static var, and no change of original var value.
            ! mov eax, R01
            ! and eax, 1
            ! mov R01, eax
          end fastproc = R01
          '-------------------------------------------------------------------------------
          ' EVEN Function
          ' Returns non-zero if input number is even, zero if odd.
          fastproc Is_Even(byval T01 as long) as long
            'T01 is BYVAL so no static var, and no change of original var value.
            ! mov eax, T01
            ! not eax
            ! and eax, 1
            ! mov T01, eax
          end fastproc = T01
          Dale

          Comment


          • #6
            I think Theo had the right idea, all you need to do is play with the overheads for the calculation.

            A FASTPROC is good, inlining it is even better and a single line of ASM is all that is needed. The AND operation works fine on a memory operand so you don't need to pass it through a register. Its really hard to beat 1 line of assembler code.
            Code:
            ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
            
             FUNCTION PBmain as LONG
            
                LOCAL var as DWORD
            
                var = 1234
                ! and var, &B00000000000000000000000000000001
            
                If var = 0 Then
                  StdOut "Number is even"
                Else
                  StdOut "Number is odd"
                End if
            
                waitkey$
            
             End FUNCTION
            
            ' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
            hutch at movsd dot com
            The MASM Forum

            www.masm32.com

            Comment


            • #7
              Code:
              Macro Function Odd(x)
               MacroTemp y
               Dim y As Long
               y = x
               ! and y, &B00000000000000000000000000000001
              End Macro = -y
              isn't much faster than
              Code:
              Macro Odd(x) = (x\2)*2 <> x
              On my PC, one million iterations of a simple application
              Code:
              For count = 1 To 1000000
                  k = Odd(count)
                 Next
              took about .003 with the assembler macro versus about .004 with the algebraic macro. (In each case you could subtract about .00025 for just doing k = something.)
              Politically incorrect signatures about immigration patriots are forbidden. Googling “immigration patriots” is forbidden. Thinking about Googling ... well, don’t even think about it.

              Comment


              • #8
                That is fascinating Mark

                I cannot wait to see what the assembler boys make of it!!!!!
                [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
                Kerry Farmer

                Comment

                Working...
                X