Announcement

Collapse
No announcement yet.

Help with C++ conversion

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

  • Help with C++ conversion

    Just a quick question, did I do this correctly?
    Not too good with the way the casting works in C...

    Thx.
    Regards,
    Jules

    Code:
                'C++ code...
                'double m_dLowerLimit;        // lower bounds
                'double m_dUpperLimit;        // upper bounds
                'nCharacters = abs((int)log10(fabs(m_dUpperLimit))) ;
                'nCharacters = max(nCharacters, abs((int)log10(fabs(m_dLowerLimit)))) ;
                
                'PB code...
                GLOBAL m_dLowerLimit  AS DOUBLE
                GLOBAL m_dUpperLimit  AS DOUBLE
    
                LOCAL nTemp AS INTEGER
                
                nTemp = LOG10( ABS(m_dUpperLimit) )
                nCharacters = ABS( nTemp )
                
                nTemp = LOG10( ABS( m_dLowerLimit) )
                nCharacters = MAX( nCharacters, ABS( nTemp ) )

  • #2
    'nCharacters = abs((int)log10(fabs(m_dUpperLimit))) ;

    nCharacters = ABS(INT(LOG10(ABS(m_dUpperLimit))))

    'nCharacters = max(nCharacters, abs((int)log10(fabs(m_dLowerLimit)))) ;

    nCharacters = MAX(nCharacters, ABS(INT(LOG10(ABS(m_dLowerLimit)))))
    Scott Slater
    Summit Computer Networks, Inc.
    www.summitcn.com

    Comment


    • #3
      Thanks Scott !

      Embarrassed to say, ...I overlooked PB INT.

      Regards,
      Jules

      Comment


      • #4
        One more trouble spot for me...

        double nRandom;
        // generate a random number between -5 and 5
        nRandom = -5.0 + 10.0*rand()/(double)RAND_MAX;

        RAND_MAX i think is at least 32768

        Thx.
        Regards,
        Jules

        Comment


        • #5
          Almost. It is 32767.

          %RAND_MAX = &H7fff&
          Forum: http://www.jose.it-berater.org/smfforum/index.php

          Comment


          • #6
            Ok, this works I believe:
            Code:
            LOCAL nRandom AS DOUBLE 
            
            nRandom = (RND - .4999999999999999#) * 10
            Last edited by John Gleason; 15 Jul 2009, 09:52 PM.

            Comment


            • #7
              Jose, Oops! I should have known that.

              John, I don't understand it, but I will give it a try.

              ...thank you both for helping out an old timer.

              Regards,
              Jules

              Comment


              • #8
                This is how I think it it works:

                rand() / RAND_MAX apparently gives a number between 0 and 1, which when multiplied by 10 gives a number between 0 and 10. So subtract 5 from that, and you get a number between -5 and 5.

                The PB RND function, however, gives a number less than 1, BUT EQUAL TO or greater than 0. That slight difference means that if the following simpler equation is used:
                Code:
                nRandom = (RND - .5) * 10
                then we could end up with (0 - .5) * 10 which is exactly -5, not between -5 and 5. So to avoid that possibility, I used:
                Code:
                nRandom = (RND - .4999999999999999#) * 10
                Btw, the equation could also be stated in PB as:
                Code:
                nRandom = RND * 10 - 4.999999999999999#

                Comment


                • #9
                  To get a random number from -5 to 5 use this in PB

                  Code:
                     Randomize Timer   ' MUST BE CALLED AT LEAST ONCE BEFORE USING RND.
                  
                     x = Rnd(-5,5)
                  Scott Slater
                  Summit Computer Networks, Inc.
                  www.summitcn.com

                  Comment


                  • #10
                    Originally posted by Scott Slater View Post
                    To get a random number from -5 to 5 use this in PB

                    Code:
                       Randomize Timer   ' MUST BE CALLED AT LEAST ONCE BEFORE USING RND.
                    
                       x = Rnd(-5,5)
                    BETWEEN -5,5 not Range -5 TO 5

                    James

                    Comment


                    • #11
                      Ok, so you want decimal numbers then.

                      Code:
                      Randomize Timer
                      
                      x = Rnd(-5,4) + RND
                      Scott Slater
                      Summit Computer Networks, Inc.
                      www.summitcn.com

                      Comment


                      • #12
                        Originally posted by Scott Slater View Post
                        Ok, so you want decimal numbers then.

                        Code:
                        Randomize Timer
                        
                        x = Rnd(-5,4) + RND
                        That still allows x = -5 if RND = 0 and Rnd(-5,4) = -5 (which may not actually occur with PB RND, but logically it is possible). Also the code will cycle thru its 4GB period in just 2GB of x's, and be slower since it requires two RND calls.

                        Comment


                        • #13
                          Originally posted by John Gleason View Post
                          That still allows x = -5 if RND = 0 and Rnd(-5,4) = -5 (which may not actually occur with PB RND, but logically it is possible). Also the code will cycle thru its 4GB period in just 2GB of x's, and be slower since it requires two RND calls.
                          Oops....

                          If speed is in issue in this case (didn't realize it was), you should probably lean toward doing it with the inline asm.


                          I guess in that case you can simply convert the original C++ statement to its PB equivalent of:

                          Code:
                          nRandom = -5 + 10*Rnd(0,32767)/32767#
                          The C Rand() function returns a range from 0 to 32767
                          Last edited by Scott Slater; 16 Jul 2009, 12:36 PM.
                          Scott Slater
                          Summit Computer Networks, Inc.
                          www.summitcn.com

                          Comment


                          • #14
                            Originally posted by John Gleason View Post
                            That still allows x = -5 ...
                            The original C++ code includes the values of 5 & -5 BTW.
                            Scott Slater
                            Summit Computer Networks, Inc.
                            www.summitcn.com

                            Comment


                            • #15
                              Originally posted by jcfuller View Post
                              BETWEEN -5,5 not Range -5 TO 5

                              James
                              Not according to the original C++ code.
                              Scott Slater
                              Summit Computer Networks, Inc.
                              www.summitcn.com

                              Comment


                              • #16
                                Originally posted by Jules Marchildon View Post
                                One more trouble spot for me...

                                double nRandom;
                                // generate a random number between -5 and 5
                                nRandom = -5.0 + 10.0*rand()/(double)RAND_MAX;

                                RAND_MAX i think is at least 32768

                                Thx.
                                Regards,
                                Jules
                                I was going by the text not the code.

                                James

                                Comment


                                • #17
                                  Originally posted by jcfuller View Post
                                  I was going by the text not the code.

                                  James
                                  Nor did I when I originally posted RND(-5,5) because then I would have realized it was returning a DOUBLE instead of an INT
                                  Scott Slater
                                  Summit Computer Networks, Inc.
                                  www.summitcn.com

                                  Comment


                                  • #18
                                    Originally posted by Scott Slater View Post
                                    The original C++ code includes the values of 5 & -5 BTW.
                                    Ok, so the comment "// generate a random number between -5 and 5" is not quite accurate, because the code says we should include exactly -5 and 5 as possibilities.
                                    Code:
                                    nRandom = RND * 10 - 5
                                    gets us everything but exactly 5
                                    and:
                                    Code:
                                    x = Rnd(-5,4) + RND
                                    also omits exactly 5.

                                    Well, it looks like
                                    Code:
                                    nRandom = -5 + 10*Rnd(0,32767)/32767
                                    then is the answer to exactly match the C++ code and be sure you get 5 and -5. You could choose other arbitrary limits, eg.
                                    Code:
                                    nRandom = -5 + 10*Rnd(0,2000000)/2000000
                                    if more resolution might help.

                                    But, if you don't think you really need to exactly hit 5 on the nose, RND * 10 - 5 is easiest on both the processor and programmer.

                                    added later: Jules, I checked into the C++ Rand() function and found out it produces 32K random integers. 32K?! This means it is, oh, 131,000 times smaller then the PB generator. It'll loop thru all its numbers in milliseconds and is therefore not worth trying to emulate. It is also unusual in that both its bounds are inclusive. Bottom line? nRandom = RND * 10 - 5 has nearly a 100% chance of working best for you.
                                    Last edited by John Gleason; 16 Jul 2009, 05:50 PM.

                                    Comment


                                    • #19
                                      That's great to know, thanks for the lessons! You are correct, it does not need to be exact, it generates data points to demo a plot, it will be replaced by an array of data points. Thank you very much for the help!!!

                                      As Columbo would say "Ah...just one more thing ma'am... I worry. I mean, little things bother me. I'm a worrier. I mean, little insignificant details - I lose my appetite. I can't eat. My wife, she says to me, "you know, you can really be a pain."

                                      .
                                      .
                                      .
                                      Do you see anything I may have messed up. All the member variables are converted to a a global for demo purposes only.


                                      PB Code...

                                      Code:
                                      GLOBAL m_rectClient         AS RECT       'CRect
                                      GLOBAL m_dcPlot             AS DWORD       'CDC
                                      GLOBAL m_rectPlot           AS RECT        'CRect
                                      GLOBAL m_brushBack          AS DWORD       'CBrush
                                      GLOBAL m_penPlot            AS DWORD       'CPen
                                      GLOBAL m_dLowerLimit        AS DOUBLE      'DOUBLE lower bounds
                                      GLOBAL m_nShiftPixels       AS INTEGER     'INT amount to shift with each new point
                                      GLOBAL m_dVerticalFactor    AS INTEGER     '
                                      GLOBAL m_dCurrentPosition   AS DOUBLE      'DOUBLE current position
                                      GLOBAL m_dPreviousPosition  AS DOUBLE      'DOUBLE previous position
                                      GLOBAL m_nPlotHeight        AS INTEGER       'INT
                                      GLOBAL m_nPlotWidth         AS INTEGER     'INT
                                      GLOBAL m_nHalfShiftPixels   AS INTEGER     'INT
                                      GLOBAL m_nPlotShiftPixels   AS INTEGER     'INT
                                      
                                        
                                      '------------------------------------------------------------------------------
                                      '  
                                      '------------------------------------------------------------------------------
                                      SUB DrawPoint()
                                      
                                          '-this does the work of "scrolling" the plot to the left
                                          ' and appending a new data point all of the plotting is
                                          ' directed to the memory based bitmap associated with m_dcPlot
                                          ' and will subsequently be BitBlt'd to the client in OnPaint
                                      
                                          LOCAL currX AS INTEGER, prevX AS INTEGER, currY AS INTEGER,prevY AS INTEGER
                                          LOCAL oldPen AS DWORD
                                          LOCAL rectCleanUp AS RECT
                                      
                                        IF ISTRUE( m_dcPlot ) THEN
                                      
                                          '-shift the plot by BitBlt'ing it to itself
                                          ' note: the m_dcPlot covers the entire client
                                          '       but we only shift bitmap that is the size
                                          '       of the plot rectangle
                                          ' grab the right side of the plot (exluding m_nShiftPixels on the left)
                                          ' move this grabbed bitmap to the left by m_nShiftPixels
                                      
                                          CALL BitBlt(  m_dcPlot,m_rectPlot.nLeft,m_rectPlot.nTop+1,m_nPlotWidth, m_nPlotHeight, _
                                                        m_dcPlot,m_rectPlot.nLeft+m_nShiftPixels,m_rectPlot.nTop+1,%SRCCOPY )
                                      
                                          '-establish a rectangle over the right side of plot
                                          ' which now needs to be cleaned up prior to adding the new point
                                          rectCleanUp = m_rectPlot
                                          rectCleanUp.nLeft  = rectCleanUp.nRight - m_nShiftPixels
                                      
                                          '-fill the cleanup area with the background
                                          CALL FillRect( m_dcPlot,rectCleanUp, m_brushBack )
                                      
                                          '-draw the next line segment
                                      
                                          '-grab the plotting pen
                                          oldPen = SelectObject( m_dcPlot ,m_penPlot )
                                      
                                          '-move to the previous point
                                          prevX = m_rectPlot.nRight-m_nPlotShiftPixels
                                          prevY = m_rectPlot.nBottom -((m_dPreviousPosition - m_dLowerLimit) * m_dVerticalFactor)
                                          CALL MoveToEx( m_dcPlot, prevX, prevY, BYVAL %NULL )
                                      
                                          '-draw to the current point
                                          currX = m_rectPlot.nRight-m_nHalfShiftPixels
                                          currY = m_rectPlot.nBottom -((m_dCurrentPosition - m_dLowerLimit) * m_dVerticalFactor)
                                          CALL LineTo( m_dcPlot, currX, currY )
                                      
                                          '-restore the pen
                                          CALL SelectObject( m_dcPlot, oldPen )
                                      
                                          '-if the data leaks over the upper or lower plot boundaries
                                          ' fill the upper and lower leakage with the background
                                          ' this will facilitate clipping on an as needed basis
                                          ' as opposed to always calling IntersectClipRect
                                      
                                          LOCAL rcFill AS RECT
                                      
                                          IF (prevY <= m_rectPlot.nTop) OR  (currY <= m_rectPlot.nTop) THEN
                                              CALL setRect( rcFill,prevX, m_rectClient.nTop, currX+1, m_rectPlot.nTop+1 )
                                              CALL FillRect( m_dcPlot,rcFill, m_brushBack )
                                          END IF
                                      
                                          IF (prevY >= m_rectPlot.nBottom) OR (currY >= m_rectPlot.nBottom) THEN
                                              CALL SetRect( rcFill,prevX, m_rectPlot.nBottom+1, currX+1, m_rectClient.nBottom+1 )
                                              CALL FillRect( m_dcPlot,rcFill, m_brushBack )
                                          END IF
                                      
                                          'store the current point for connection to the next point
                                          m_dPreviousPosition = m_dCurrentPosition
                                      
                                        END IF
                                      
                                      END SUB
                                      C++ code...

                                      Code:
                                        INT m_nShiftPixels;           // amount TO SHIFT WITH each NEW point
                                        DOUBLE m_dCurrentPosition;    // current position
                                        DOUBLE m_dPreviousPosition;  // previous position
                                        INT m_nHalfShiftPixels;
                                        INT m_nPlotShiftPixels;
                                        INT m_nPlotHeight;
                                        INT m_nPlotWidth;
                                        DOUBLE m_dLowerLimit;         // lower bounds
                                        DOUBLE m_dVerticalFactor;
                                        CRect  m_rectClient;
                                        CRect  m_rectPlot;
                                        CPen   m_penPlot;
                                        CBrush m_brushBack;
                                        CDC     m_dcPlot;
                                        
                                      
                                      /////////////////////////////////////////////////////////////////////////////
                                      void COScopeCtrl::DrawPoint()
                                      {
                                        // this does the work OF "scrolling" the plot TO the LEFT
                                        // AND appending a NEW DATA point all of the plotting is
                                        // directed TO the memory based BITMAP associated WITH m_dcPlot
                                        // the will subsequently be BitBlt'd to the client in OnPaint
                                      
                                        INT currX, prevX, currY, prevY ;
                                      
                                        CPen *oldPen ;
                                        CRect rectCleanUp ;
                                      
                                        IF (m_dcPlot.GetSafeHdc() != NULL)
                                        {
                                          // SHIFT the plot by BitBlt'ing it to itself
                                          // note: the m_dcPlot covers the entire CLIENT
                                          //       but we only SHIFT BITMAP that IS the SIZE
                                          //       OF the plot rectangle
                                          // grab the RIGHT side OF the plot (exluding m_nShiftPixels ON the LEFT)
                                          // move this grabbed BITMAP TO the LEFT by m_nShiftPixels
                                      
                                          m_dcPlot.BitBlt(m_rectPlot.left, m_rectPlot.top+1,
                                                          m_nPlotWidth, m_nPlotHeight, &m_dcPlot,
                                                          m_rectPlot.left+m_nShiftPixels, m_rectPlot.top+1,
                                                          SRCCOPY) ;
                                      
                                          // establish a rectangle over the RIGHT side OF plot
                                          // which now needs TO be cleaned up proir TO adding the NEW point
                                          rectCleanUp = m_rectPlot ;
                                          rectCleanUp.left  = rectCleanUp.right - m_nShiftPixels ;
                                      
                                          // FILL the CLEANUP area WITH the background
                                          m_dcPlot.FillRect(rectCleanUp, &m_brushBack) ;
                                      
                                          // DRAW the NEXT LINE segement
                                      
                                          // grab the plotting pen
                                          oldPen = m_dcPlot.SelectObject(&m_penPlot) ;
                                      
                                          // move TO the previous point
                                          prevX = m_rectPlot.right-m_nPlotShiftPixels ;
                                          prevY = m_rectPlot.bottom -
                                                  (LONG)((m_dPreviousPosition - m_dLowerLimit) * m_dVerticalFactor) ;
                                          m_dcPlot.MoveTo (prevX, prevY) ;
                                      
                                          // DRAW TO the current point
                                          currX = m_rectPlot.right-m_nHalfShiftPixels ;
                                          currY = m_rectPlot.bottom -
                                                  (LONG)((m_dCurrentPosition - m_dLowerLimit) * m_dVerticalFactor) ;
                                          m_dcPlot.LineTo (currX, currY) ;
                                      
                                          // restore the pen
                                          m_dcPlot.SelectObject(oldPen) ;
                                      
                                          // IF the DATA leaks over the upper or lower plot boundaries
                                          // FILL the upper AND lower leakage WITH the background
                                          // this will facilitate clipping ON an AS needed basis
                                          // AS opposed TO always calling IntersectClipRect
                                          IF ((prevY <= m_rectPlot.top) || (currY <= m_rectPlot.top))
                                            m_dcPlot.FillRect(CRect(prevX, m_rectClient.top, currX+1, m_rectPlot.top+1), &m_brushBack) ;
                                          IF ((prevY >= m_rectPlot.bottom) || (currY >= m_rectPlot.bottom))
                                            m_dcPlot.FillRect(CRect(prevX, m_rectPlot.bottom+1, currX+1, m_rectClient.bottom+1), &m_brushBack) ;
                                      
                                          // store the current point FOR connection TO the NEXT point
                                          m_dPreviousPosition = m_dCurrentPosition ;
                                      
                                        }
                                      
                                      } // END DrawPoint
                                      Last edited by Jules Marchildon; 17 Jul 2009, 07:11 AM.

                                      Comment


                                      • #20
                                        That's a graphics conversion lesson to me, Jules.

                                        I certainly don't see anything "messed up" in there. My only suggestion/question might be regarding data types. Are the values for m_dCurrentPosition, m_dPreviousPosition, and m_dLowerLimit always integers? I noticed you converted m_dVerticalFactor to an integer from a DOUBLE in the C++ code, and it would help speed things up with the other three as well if those too are always integers.

                                        Also, all the "AS INTEGER" types would be better off as LONG in PB, as that is most efficient type. There is likely no problem making the DWORD pointers LONG too.

                                        Comment

                                        Working...
                                        X