Announcement

Collapse
No announcement yet.

Elegant Logic test

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

  • Elegant Logic test

    Is there an elegant way to code this:
    Code:
    LOCAL a,b,c AS LONG ' for example
    
    IF a OR b OR c THEN        ' If one is present then 
      IF a AND b AND c THEN  ' all must be present  
        ' Want the Else
      ELSE
        MissingFlag = 1 ' Error, one or more is missing
      END IF
    END IF

  • #2
    IF (A*B*C) = 0 THEN
    ? "Something's missing!"
    END IF
    C'ya
    Don

    http://www.ImagesBy.me

    Comment


    • #3
      Mike,
      the outer IF THEN.. ENDIF loop is redundant. Just use:
      Code:
        IF a AND b AND c THEN  ' all must be present  
          ' Want the Else
        ELSE
          MissingFlag = 1 ' Error, one or more is missing
        END IF
      It will do the same job since if all of a,b and c are present then at least one of them must be.

      Paul.

      Comment


      • #4
        If there is any knowledge on the probability of being false then with a descending sort with 'a' as the most likely to be false and so on then we could use

        Code:
        If a Then
          If b Then
            If c Then
              Exit If
            Else
              MissingFlag = 1
            End If
          Else
            MissingFlag = 1
          End If
        Else
          MissingFlag = 1
        End If
        BTW Mike your code fails if all are missing but not so, obviously, when the outer loop is removed as Paul suggested.

        Comment


        • #5
          I think this might actually be a real case for using the IMP operator. (which I have never been able to find a case for).

          No, I haven't had enough coffee yet to do this, but it just might work AND score quite high in the 'panache points' area.
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            Forget IMP.
            Code:
            IF (A OR B OR C) AND (A AND B AND C) THEN
              If one is true then all are true
            ELSE
              ???
            END IF
            [code]
            No, that's not right is it? He wants the flag set ONLY if one is true but not all (i.e., flag not set if all false).

            IMP might be back on the table after all. (sure you could do it with an ELSEIF ( A OR B OR C alone) above, but there's no style points available for that).
            Last edited by Michael Mattias; 30 Jan 2008, 09:22 AM.
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              How about six ticks worth:

              Code:
              #COMPILE EXE
              #DIM ALL
              
              FUNCTION PBMAIN () AS LONG
                  LOCAL a,b,c AS LONG
                  a = 1:b = 1:c = 1
              '   a = 0:b = 1:c = 1 'zero any of three out and it results in 0 (not ok)
                   a = a AND b      'These 3 lines are just 6 ticks to do logic
                   a = a AND c      '                 "
                   IF a THEN        '                 "
              '    IF a AND b AND c THEN << Tried this, but... let's just say more than 6 ticks ;o)
              '    You don't need the initial OR logic since that will be determined by the AND logic
                      ? "ok"
                   ELSE
                      ? "not ok"
                   END IF
                   
              END FUNCTION

              Comment


              • #8
                Oops, got it to 5 ticks:

                Code:
                #COMPILE EXE
                #DIM ALL
                
                FUNCTION PBMAIN () AS LONG
                    LOCAL a,b,c AS LONG
                    a = 1:b = 1:c = 1
                '   a = 0:b = 1:c = 1 'zero any of three out and it results in 0 (not ok)
                '   IF a AND b AND c THEN   '<< Tried this, but... just say more than 6 ticks ;)
                    IF (a AND b AND c) THEN '<< Tried this--force to bit logic--and lo and behold, 5 ticks!
                '    You don't need the initial OR logic since that will be determined by the AND logic
                        ? "ok"
                     ELSE
                        ? "not ok"
                     END IF
                     
                END FUNCTION

                Comment


                • #9
                  Hi Mike;

                  Perhaps the XOR function will work.

                  LOCAL a,b,c AS LONG ' for example

                  IF a OR b OR c THEN ' If one is present then
                  IF a AND b AND c THEN ' all must be present
                  ' Want the Else
                  ELSE ' Error, one or more is missing
                  IF a XOR b THEN MissingFlag = 1 : EXIT IF
                  IF a XOR c THEN MissingFlag = 1 : EXIT IF
                  IF b XOR c THEN MissingFlag = 1 : EXIT IF

                  END IF
                  END IF

                  Comment


                  • #10
                    Code:
                     
                    LOCAL a,b,c AS LONG ' for example
                     
                    IF a AND b AND c THEN ' all must be present
                       ' Do something
                    ELSEIF  a OR b OR c  THEN ' at least one is present
                       MissingFlag = 1 'Error, one or two is missing
                    ELSE
                       'Optional -- all are missing
                    END IF
                    Sincerely,
                    John Harvill
                    Last edited by John Harvill; 30 Jan 2008, 12:31 PM.

                    Comment


                    • #11
                      I just read the previous posts (yes, being in the fog of... fog) and saw Paul already did "a AND b AND c", but I had checked that and it was like 9 ticks, so I thought, "5 is less than 9", case closed. Um, nope. "a AND b AND c" will "short circuit" similar to like what Dave's code above does but with no knowledge necessary of a, b, or c. Hence, it will average 4.5 ticks, and correct me if I'm wrong, but 4.5 is less than 5. My code will beat Paul's code--yeah, sure, that's gonna happen. Cold fusion COULD become reality by 2009 too.

                      Comment


                      • #12
                        Or maybe this

                        Code:
                        #COMPILE EXE
                        #DIM ALL
                        #INCLUDE "Win32API.inc"
                        FUNCTION PBMAIN () AS LONG
                          LOCAL a,b,c AS LONG ' for example
                          LOCAL MissingFlag AS LONG
                          a=1:b=1:c=0
                        '  IF a OR b OR c THEN ' If one is present then
                        '    IF a AND b AND c THEN ' all must be present
                        '     Want the Else
                        '    ELSE ' Error, one or more is missing
                        IF (a XOR b) OR (b XOR c) THEN MissingFlag = 1:MSGBOX "MissingFlag="+FORMAT$(MissingFlag),%MB_TASKMODAL
                        '    END IF
                        '  END IF
                        END FUNCTION
                        Or, more clearly

                        Code:
                        #COMPILE EXE
                        #DIM ALL
                        #INCLUDE "Win32API.inc"
                        FUNCTION PBMAIN () AS LONG
                          LOCAL a,b,c AS LONG ' for example
                          LOCAL MissingFlag AS LONG
                          a=0:b=0:c=1       'the if statement is ignored if all are equal to 1 or 0
                          IF (a XOR b) OR (b XOR c) THEN MissingFlag = 1:MSGBOX "MissingFlag="+FORMAT$(MissingFlag),%MB_TASKMODAL
                        END FUNCTION
                        Rod
                        I want not 'not', not Knot, not Knott, not Nott, not knot, not naught, not nought, but aught.

                        Comment


                        • #13
                          Wow, you guys are so creative!
                          I should have defined elegant a little better... meaning a one line solution so:

                          IF (a XOR b) OR (b XOR c) THEN ? "Error"

                          IF (a*b*c) = 0 THEN ? "Error"
                          Look good. Unfortunatly the logic of (a*b*c) is not correct

                          Speed was not an issue cos I thought logic would do it, but since the variables are actually DWORDs values (holding the number of bytes) and I didn't consider using multiplication speed now becomes interesting.
                          So you are right, a speed test is in order.

                          Using timing Macro's developed with the kind help of Michael W on the MASM site:
                          http://www.masm32.com/board/index.php?board=30.0



                          On my P4 Win XP Pro box I get:
                          424
                          188
                          336

                          The DWORD multiplication is the fastest, the problem is the logic fails... Darn.
                          Last edited by Mike Trader; 31 Jan 2008, 05:26 AM.

                          Comment


                          • #14
                            >but since the variables are actually DWORDs values (holding the number of bytes)...

                            Then you can't use AND unless you use ISTRUE.

                            e.g, ( 2 AND 4) is false, but (ISTRUE(2) and ISTRUE(4)) is true.

                            MCM
                            Michael Mattias
                            Tal Systems (retired)
                            Port Washington WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment


                            • #15
                              Mike, check out your original post, the code from which is included below, then insert the code into your timing program and run all three example timings. 7 ticks is the max I got!

                              Code:
                                  '=======================
                                  ErrorFlag = 0
                                  COUNTER_BEGIN(nLoops, %HIGH_PRIORITY_CLASS)
                                    IF a OR b OR c THEN
                                       IF a AND b AND c THEN
                                       ELSE
                              '         ErrorFlag = 1   ' Do not time this
                                       END IF
                                    END IF
                                  COUNTER_END
                                    IF a OR b OR c THEN
                                       IF a AND b AND c THEN
                                       ELSE
                                          ErrorFlag = 1
                                       END IF
                                    END IF
                                  s = s + "3: ErrorFlag=" + STR$(ErrorFlag) + ",  Clks="+STR$(CounterCycles) + $CRLF
                                  '=======================

                              Comment


                              • #16
                                Speed? Yeah.

                                Code:
                                '============
                                MACRO AllOrNone(a,b,c,errorFlag)
                                '-- errorFlag returns zero/nonzero (not 0/1 or 0/-1)
                                MACROTEMP Done
                                !  xor   eax,        eax
                                
                                !  mov   ebx,        a
                                !  mov   ecx,        b
                                !  mov   edx,        c
                                
                                !  test  ebx,        ebx
                                !  setnz al
                                
                                !  test  ecx,        ecx
                                !  setnz cl
                                
                                !  test  edx,        edx
                                !  setnz dl
                                
                                !  add   al,         cl
                                !  add   al,         dl
                                
                                !  test  eax,        eax
                                !  jz    Done
                                !  sub   eax,        &b11
                                Done:
                                !  mov   errorFlag,  eax
                                END MACRO
                                Revised later for minor tightening (and because I couldn't get to sleep ).
                                Last edited by Greg Turgeon; 31 Jan 2008, 05:21 AM.

                                Comment


                                • #17
                                  Given that A, B, and C represent the quantity of something, and the goal is to determine whether one or two variables have a quantity of zero, then:

                                  IF ROUND( 0.66 * CSNG( SGN( A ) + SNG( B ) + SNG( C ) ), 0 ) = 1 THEN MissingFlag = 1 ' Error, one or two is missing

                                  Sincerely,
                                  John Harvill
                                  Last edited by John Harvill; 2 Feb 2008, 11:18 PM.

                                  Comment


                                  • #18
                                    "If one is true all must be true" can be said as "if one is true" implies "all must be true) ... so:
                                    Code:
                                    if not((a+b+c) imp (a*b*c)) then missingflag=1
                                    Just to use imp ... I think the original code is much more clear.

                                    However, as already stated previously, this doesn't works because imp works on left and right part of expressions bitwise and result is dependent from true values of a,b,c.
                                    Should be
                                    Code:
                                    if not(istrue(a+b+c) imp istrue(a*b*c)) then missingflag=1
                                    but it's going to be too complex ...
                                    Last edited by Claudio DalZovo; 2 Feb 2008, 06:46 PM.

                                    Comment


                                    • #19
                                      Here is my one liner.

                                      Code:
                                      #COMPILE EXE
                                      #DIM ALL
                                      
                                      FUNCTION PBMAIN () AS LONG
                                      
                                      LOCAL a,b,c,flag,var1,var2 AS LONG
                                      a = 1:b = 0 :c = 1
                                      IF (ISFALSE(a)OR ISFALSE(b) OR ISFALSE(c)) THEN MSGBOX "all or one is missing" ELSE MSGBOX "all are present"
                                      END FUNCTION
                                      John Tate

                                      Comment

                                      Working...
                                      X