Announcement

Collapse
No announcement yet.

A kind suggestion with Select...Case

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

  • A kind suggestion with Select...Case

    This is just a small sample for ortho mode in CAD:

    Select Case dAngle
    Case >= 0.00 * PI And < 0.25* PI
    dpMove.y = mCirc.cp.y
    Case >= 0.25 * PI And < 0.50 * PI
    dpMove.x = mCirc.cp.x
    Case >= 0.50 * PI And < 0.75 * PI
    dpMove.x = mCirc.cp.x
    Case >= 0.75 * PI And < 1.00 * PI
    dpMove.y = mCirc.cp.y
    Case >= 1.00 * PI And < 1.25 * PI
    dpMove.y = mCirc.cp.y
    Case >= 1.25 * PI And < 1.50 * PI
    dpMove.x = mCirc.cp.x
    Case >= 1.50 * PI And < 1.75 * PI
    dpMove.x = mCirc.cp.x
    Case >= 1.75 * PI And < 2.0 * PI
    dpMove.y = mCirc.cp.y
    End Select

    Unfortunately the Select...Case function does not support boolean operations obviously. In many situations like this one, it would make things much more transparent in comparison to other code syntax.
    Norbert Doerre

  • #2
    I think the nearest you can get is to use a range, like:
    CASE a TO b
    in which the second limit is inclusive, unlike your example.

    Comment


    • #3
      Or forget about CASE and go for performance
      Code:
      GLOBAL gPI!()  'multiply once in advance
      FUNCTION PBMAIN () AS LONG
       
        DIM gPI!(0 TO 8) '9 pre-multiplied values to compare to
       
        pi! = 1          'change to pi
        FOR x& = 0 TO 8  '0, .25, .50, .75, 1, 1.25, 1.50, 1.75, 2 if pi = 1
          gPI!(x&) = pi! * variable!
          variable! = variable! + .25
        NEXT
        'test all 8 conditions  (0 to 7)
        FOR Angle! = -1 TO 12 STEP .25
          CALL DoIt(angle!)
        NEXT
      END FUNCTION
      SUB DoIt(Angle!)
        FOR x& = 0 TO 7    '8 possible conditions
          IF angle! >= gPI!(x&) AND angle! < gPI!(x&+1) THEN
            ? "Angel" + STR$(Angle!)+ " =>" + STR$(gPI!(x&)) + " and <" + STR$(gPI!(x&+1)) + "   condition" + STR$(x&)
            EXIT FOR
          END IF
        NEXT
      END SUB
      Last edited by Mike Doty; 6 Nov 2008, 04:00 AM. Reason: Forgot EXIT FOR

      Comment


      • #4
        Would the following work:

        Code:
        Select Case dAngle/PI
           Case >= 0.00 And < 0.25
              dpMove.y = mCirc.cp.y
           Case >= 0.25 And < 0.50
              dpMove.x = mCirc.cp.x
           Case >= 0.50 And < 0.75
              dpMove.x = mCirc.cp.x
           Case >= 0.75 And < 1.00
              dpMove.y = mCirc.cp.y
           Case >= 1.00 And < 1.25
              dpMove.y = mCirc.cp.y
           Case >= 1.25 And < 1.50
              dpMove.x = mCirc.cp.x
           Case >= 1.50 And < 1.75
              dpMove.x = mCirc.cp.x
           Case >= 1.75 And < 2.0
              dpMove.y = mCirc.cp.y
        End Select
        Chris Boss
        Computer Workshop
        Developer of "EZGUI"
        http://cwsof.com
        http://twitter.com/EZGUIProGuy

        Comment


        • #5
          'Case >= 0.00 And < 0.25 =====> Syntax error (not String or Numeric Expression)

          This perhaps?
          Code:
          Select Case dAngle/PI
             Case <0
               Exit Select
             Case < 0.25
                dpMove.y = mCirc.cp.y
             Case < 0.50
                dpMove.x = mCirc.cp.x
             Case < 0.75
                dpMove.x = mCirc.cp.x
             Case < 1.00
                dpMove.y = mCirc.cp.y
          ' etc
           End Select
          Rgds, Dave

          Comment


          • #6
            ??? (not tried)
            Code:
              SELECT CASE -1& 
                     CASE (X => 0.00 * PI ) AND ( x< 0.25* PI) 
            ...
            Kind of a spinoff from COBOL...
            Code:
               EVALUATE TRUE 
                   WHEN  (condition ) [AND|or] [NOT] condition] 
                        Do something
                    WHEN .....
                     ...
                END-EVALUATE
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              You can usually order the cases to avoid complex boolean expressions (as Dave Biggs showed). You'll get a big speed improvement by pre-calculating your pi ranges (like Mike Doty said too).
              Code:
              #COMPILE EXE
              #DIM ALL
              
              FUNCTION PBMAIN () AS LONG
                 DIM piFactor(8) AS EXT
                 LOCAL dAngle, pi, mult AS EXT
                 LOCAL ii AS LONG
                 '-------------------place below in PBMAIN where it will get executed only once-----------------
                 pi = 4 * ATN(1)                  'make accurate pi value
                 FOR ii = 1 TO 8                  'pre calculate your case ranges so SELECT CASE doesn't have to.
                    mult = mult + .25
                    piFactor(ii) = piFactor(ii) + mult * pi
                 NEXT
                 '-------------------place above in PBMAIN where it will get executed only once-----------------
                 RANDOMIZE
                   dAngle = piFactor(8) * RND
                                     
                SELECT CASE dAngle
                   CASE < piFactor(1)
                      ? "dpMove.y = mCirc.cp.y"
                   CASE < piFactor(2)
                      ? "dpMove.x = mCirc.cp.x"
                   CASE < piFactor(3)
                      ? "dpMove.x = mCirc.cp.x"
                   CASE < piFactor(4)
                      ? "dpMove.y = mCirc.cp.y"
                   CASE < piFactor(5)
                      ? "dpMove.y = mCirc.cp.y"
                   CASE < piFactor(6)
                      ? "dpMove.x = mCirc.cp.x"
                   CASE < piFactor(7)
                      ? "dpMove.x = mCirc.cp.x"
                   CASE < piFactor(8)
                      ? "dpMove.y = mCirc.cp.y"
                END SELECT

              Comment


              • #8
                Select Case doesn't but IF THEN does, that is the difference between them ie
                IF dAngle >= 0.00 AND dAngle < 0.25*PI THEN
                ...
                ELSEIF dAngle >= 0.25*PI AND dAngle < 0.50*PI THEN
                ...
                ELSEIF dAngle >= 0.50*PI AND dAngle < 0.75*PI THEN
                ...
                etc
                Just as readable and not much more typing using copy and paste.
                I make no comments about the speed.

                Comment


                • #9
                  When working with SELECT CASE I've found it useful to insert EXIT SELECT after each case. This makes the code a little more "bullet proof" by eliminating a situation where more than one case satisifies a given condition. Also, the cases do not have to be in any particular order.

                  Code:
                  #COMPILE EXE
                  #DIM ALL
                  
                  FUNCTION PBMAIN () AS LONG
                     DIM piFactor(8) AS EXT
                     LOCAL dAngle, pi, mult AS EXT
                     LOCAL ii AS LONG
                     '-------------------place below in PBMAIN where it will get executed only once-----------------
                     pi = 4 * ATN(1)                  'make accurate pi value
                     FOR ii = 1 TO 8                  'pre calculate your case ranges so SELECT CASE doesn't have to.
                        mult = mult + .25
                        piFactor(ii) = piFactor(ii) + mult * pi
                     NEXT
                     '-------------------place above in PBMAIN where it will get executed only once-----------------
                     RANDOMIZE
                       dAngle = piFactor(8) * RND
                                         
                    SELECT CASE dAngle
                       CASE < piFactor(1)
                          ? "dpMove.y = mCirc.cp.y"
                          EXIT SELECT 
                  
                       CASE < piFactor(2)
                          ? "dpMove.x = mCirc.cp.x"
                          EXIT SELECT 
                  
                       CASE < piFactor(3)
                          ? "dpMove.x = mCirc.cp.x"
                          EXIT SELECT 
                  
                       CASE < piFactor(4)
                          ? "dpMove.y = mCirc.cp.y"
                          EXIT SELECT 
                  
                       CASE < piFactor(5)
                          ? "dpMove.y = mCirc.cp.y"
                          EXIT SELECT 
                  
                       CASE < piFactor(6)
                          ? "dpMove.x = mCirc.cp.x"
                          EXIT SELECT 
                  
                       CASE < piFactor(7)
                          ? "dpMove.x = mCirc.cp.x"
                          EXIT SELECT 
                  
                       CASE < piFactor(8)
                          ? "dpMove.y = mCirc.cp.y"
                    END SELECT

                  Comment


                  • #10
                    Walter,
                    Once a CASE returns true the next CASE won't execute.
                    EXIT SELECT is only useful in early termination in the CASE that is true.
                    I see the logic in your statements, but 2 CASE's won't be executed.
                    Last edited by Mike Doty; 13 Nov 2008, 11:40 AM.

                    Comment


                    • #11
                      Also, the cases do not have to be in any particular order.
                      CASE's may need to be in a correct order.
                      This is an error:
                      x& = 2
                      SELECT CASE x&
                      ...CASE > 0 'would catch all positive values
                      ...CASE > 1 'never executes
                      END SELECT
                      Last edited by Mike Doty; 8 Nov 2008, 07:05 PM.

                      Comment


                      • #12
                        Sorry for my delay...

                        Sorry but I had no time to have an earlier look into this thread again. Boolean operation should be possible into SELECT...CASE. It would help a lot in many, many cases. I remember that this syntax was once added just to make life easier than with IF...ELSE...ENDIF. SELECT CASE should at least be able to do what IF ENDIF could do ever before. The sample I introduced in this thread is very simple and only shows the priciple of the syntax needed in order not to loose overview when code becomes much more complex.
                        Norbert Doerre

                        Comment


                        • #13
                          Code:
                          SELECT CASE dAngle
                          CASE 0.00 * PI TO  0.24* PI
                          dpMove.y = mCirc.cp.y
                          CASE 0.25 * PI TO  0.49 * PI
                          dpMove.x = mCirc.cp.x
                          CASE 0.50 * PI TO 0.74 * PI
                          dpMove.x = mCirc.cp.x
                          CASE 0.75 * PI TO .99 * PI
                          dpMove.y = mCirc.cp.y
                          CASE 1.00 * PI TO 1.24 * PI
                          dpMove.y = mCirc.cp.y
                          CASE 1.25 * PI TO 1.49 * PI
                          dpMove.x = mCirc.cp.x
                          CASE 1.50 * PI TO 1.74 * PI
                          dpMove.x = mCirc.cp.x
                          CASE 1.75 * PI TO 2.0 * PI
                          dpMove.y = mCirc.cp.y
                          END SELECT
                          Does this help?
                          Rod
                          In some future era, dark matter and dark energy will only be found in Astronomy's Dark Ages.

                          Comment


                          • #14
                            Code:
                            SELECT CASE X 
                               CASE 1
                                 do a 
                               CASE 2, 3, 4 
                                 do b 
                               CASE < Y 
                                 do c 
                               CASE  J TO  K                 '    J to K , inclusive
                                 ... 
                            
                               CASE BETWEEN  J and K    '    J TO K , not inclusive 
                                  ....
                            ...
                            ???
                            Last edited by Michael Mattias; 14 Nov 2008, 07:07 AM.
                            Michael Mattias
                            Tal Systems (retired)
                            Port Washington WI USA
                            [email protected]
                            http://www.talsystems.com

                            Comment


                            • #15
                              A fly on the moon

                              Rod, in case You are programming with the windows API, your code is certainly sufficient. But in the reality of real numbers, there exist limits down to 10^-14 or even less, for instance if You zoom into a real world. I made an example with my program: I drew the moon 1:1 and a fly on the moon 1:1. Then, when You zoom in so that the fly just fills the screen, You must still be able to use orthgonal mode.
                              Norbert Doerre

                              Comment


                              • #16
                                A substitution does not help much.

                                Michael, You are doing a substitution. When I tried it 14 days ago I found out that accuracy is diminished each time a quad number is transferred to another quad variable. I'm using PI as quad number. May be this is a result of "Heisenberg's unsharpness". Hope You understand!
                                Norbert Doerre

                                Comment


                                • #17
                                  I found out that accuracy is diminished each time a quad number is transferred to another quad variable
                                  Huh? Not by simple assignment (LET quadvar= another quadvar) it isn't. Show failing code
                                  Michael Mattias
                                  Tal Systems (retired)
                                  Port Washington WI USA
                                  [email protected]
                                  http://www.talsystems.com

                                  Comment


                                  • #18
                                    Without evidence to the contrary, M is right here.

                                    '
                                    Code:
                                    'PBWIN 9.00 - WinApi 05/2008 - XP Pro SP3
                                    #Compile Exe                                
                                    #Dim All 
                                    #Include "WIN32API.INC"
                                    #Include "COMDLG32.INC"
                                     
                                    Function PBMain
                                      Local quad1, quad2,quad3,quad4 As Quad
                                      Local f, s As String, ctr, ctr2 As Long
                                      
                                      Quad1 = 22 / 7 * 10000000000000000000000000000000  'PI = lotsa places (32)
                                      ?Str$(quad1)
                                      f$ = "Quad # = #,     (Lotsa Places)" 
                                      Quad2 = quad1
                                      quad3 = quad2
                                      quad4 = quad3  
                                      
                                      s$ =      Using$(f$, 1, quad1) & $CrLf 
                                      s$ = s$ & Using$(f$, 2, quad2) & $CrLf 
                                      s$ = s$ & Using$(f$, 3, quad3) & $CrLf 
                                      s$ = s$ & Using$(f$, 4, quad4) & $CrLf 
                                      
                                      ctr2 = 1000000' Reassign lotsa times
                                      For ctr = 1 To 100000
                                       Quad1 = Quad4
                                       Quad2 = quad1
                                       quad3 = quad2
                                       quad4 = quad3  
                                      Next ctr
                                      
                                      ?s$,, Using$("Quad = Test after #, iterations", ctr2)
                                    End Function 'Applikation beenden
                                    '
                                    =========================================
                                    I conceive that the great part
                                    of the miseries of mankind
                                    are brought upon them by false estimates
                                    they have made of the value of things.
                                    Ben Franklin
                                    =========================================
                                    It's a pretty day. I hope you enjoy it.

                                    Gösta

                                    JWAM: (Quit Smoking): http://www.SwedesDock.com/smoking
                                    LDN - A Miracle Drug: http://www.SwedesDock.com/LDN/

                                    Comment


                                    • #19
                                      Code:
                                      Saw this in some source code from Fred Meier:
                                      'Problem: C returns quads using the EDX:EAX registers, whereas
                                               'PB returns quad values in st(0) of the FPU. Following will
                                               'move value from EDX:EAX into a Quad
                                               lqpA = VARPTR(lqA)
                                               CALL DWORD lhRutAddr USING UsingLastInsertRowid(ghDab)
                                               ! mov ecx, lqpA
                                               ! mov [ecx], eax
                                               ! mov [ecx+4], edx
                                      Also, there is an issue with QUAD's, but I can't find the post.
                                      I think it has something to do with different processors. Maybe
                                      it is in the current help file, but can't find it there either.

                                      Comment


                                      • #20
                                        Actually, this is what's found in the current help file:

                                        "While most FUNCTION calling conventions are fairly well defined throughout the industry, there are a few exceptions. In the case of functions which return a Quad Integer value, some programming languages (including PowerBASIC) return the quad value in the FPU, while others return it in EDX:EAX. PowerBASIC automatically detects the method used by imported functions and adjusts accordingly for you, but that's not a feature found in other compilers. Therefore, we recommend that you do not EXPORT QUAD FUNCTIONS unless they will only be accessed by PowerBASIC programs. A simple equivalent functionality would be to return the quad-integer value to the caller in a BYREF QUAD parameter."

                                        Best regards,

                                        Bob Zale
                                        PowerBASIC Inc.

                                        Comment

                                        Working...
                                        X