Announcement

Collapse
No announcement yet.

gremlins

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

  • Conrad Hoffman
    replied
    Thanks Bob! I fooled with that example for quite a while before giving up. FWIW, I went back to some very old code I remembered having a similar problem with. As usual, no problem with PB and no use of EXP, I did however find a plain old programmers typo I never noticed before.

    Leave a comment:


  • Kev Peel
    replied
    From PB/WIN 9 Help:

    Register variables are always local to the procedure where they appear.
    Basically you get a brand new set of registers for each call to a procedure, excluding the 3 (IIRC) registers used internally by PowerBASIC.

    Leave a comment:


  • Alan Vella
    replied
    Thanks all for your super-quick replies.

    I think I'll just include the #REGISTER NONE at the top of my code and register the variables manually.

    While we're on the the topic of registered variables I have one quick question: If I register two integer variables in a procedure A, then call procedure B from procedure A and register another two integer variables in procedure B ... will they not be registered since I have already used my maximum of two integer register variables in procedure A?

    Leave a comment:


  • Bob Zale
    replied
    Good catch, Alan. Thanks for reporting it. Actually, this is a very rare issue which seems to have been around for many years. But it occurred so infrequently that we've never had a report.

    For those who may be interested in the specific circumstances, here's how the planets aligned to cause it: Your line 22 with the EXP() function is the culprit. PowerBASIC is very good at rearranging an expression to simplify it and minimize the number of temporary values stored... but some are alway needed. At the EXP(), there are 2 temps plus the argument to EXP(). That makes 3. The EXP() function needs 2 more, and then there are 4 register variables for a total of nine. Unfortunately, the FPU has just eight registers, not nine, and it overflows at run-time The compiler should have generated an error during compilation, but its internal data showed that EXP() needed 1 temp, not 2. We've corrected it now, and it will be just fine in the next PBWIN 9.01 update. Yes, very soon.

    For now, you can simplify the noted expression, or add a #REGISTER NONE directive to disable allocation of register variables. Sorry you had a problem.

    Best regards,

    Bob Zale
    PowerBASIC Inc.

    Leave a comment:


  • Conrad Hoffman
    replied
    The OPs code is very typical of things I do. Though I haven't seen any weirdness recently, I may have had a similar problem in the past. I'd really like to know what's going on so I can avoid it, assuming it's some easily understood construct. I'd love to see a comment by PB staff, who understand what's going on under the hood.

    Leave a comment:


  • Walt Thompson
    replied
    Solution

    Hi Alan;

    The problem with your second example is LOCAL variables are cleared when the function or sub they reside in are exited. The solution is to declare the variables as STATIC, STATIC variables are not cleared when a sub or function is exited.

    Code:
    'Change this:
    LOCAL D##,E##,R##,G##,H##,SL##,S##,T##,P##,C##,SK##,Q##
    
    'To this:
    STATIC D##,E##,R##,G##,H##,SL##,S##,T##,P##,C##,SK##,Q##
    Last edited by Walt Thompson; 21 Jan 2009, 04:44 PM. Reason: Correct spelling

    Leave a comment:


  • Alan Vella
    replied
    OK, now if I add another procedure like this:

    Code:
    #COMPILE EXE
    #DIM ALL
    
    
    SUB myProc(BYVAL str AS STRING)
        MSGBOX str
    END SUB
    
    
    FUNCTION GetChiPValue(BYVAL X AS EXT, BYVAL F AS EXT) AS EXT
    '
    ' FUNCTION PCHI2 - CALCULATES THE P-VALUE FROM
    ' THE CHI-SQUARE VALUE AND THE DEGREES OF FREEDOM
    ' The probability is calculated using series expansion 26.4.6. For the
    ' gamma functions 6.1.12, 6.1.8 and 6.1.1 are used.
    ' In: Handbook of mathematical Functions. Editors: Abramowitz M & Stegun IA,
    ' Dover, New York, 1972.
    ' Original code by Erik Christensen
            LOCAL D##,E##,R##,G##,H##,SL##,S##,T##,P##,C##,SK##,Q##
            Q = 1
            IF X = 0 OR F = 0 THEN GOTO 26
            D = F : E = D / 2 : R = F - INT(F / 2) * 2
            G = 1
            IF R > .3 THEN GOTO 20
        19  E = E - 1
            IF E < 1.8 THEN GOTO 22
            G = G * E : GOTO 19
        20  G = SQR(ATN(1) * 4) ' = PI
        21  E = E - 1
            IF E < .3 THEN GOTO 22
            G = G * E: GOTO 21
        22  H = ((X / 2) ^ (D / 2) * EXP(-X / 2)) / (X * G)
            SL = H * 2 * X / D : S = 0 : T = 0 : P = 1
        23  D = D + 2 : P = P * X / D : S = S + P : C = ABS(S - T)
            IF C < 1E-16 THEN GOTO 24
            T = S : GOTO 23
        24  SK = (S + 1) * SL : Q = 1 - SK
        25  IF Q < 1E-16 THEN Q = 1E-16
            myProc(STR$(q))
        26  FUNCTION = Q
    
    END FUNCTION
    
    
    FUNCTION PBMAIN () AS LONG
        LOCAL xxx AS EXT
        xxx = GetChiPValue(4.605, 2)
        MSGBOX( FORMAT$( xxx, "0.000000000000000000000000000" ) )
    END FUNCTION
    Running the above will give you the write answer in the two message boxes (the one in myProc and the one in pbMain).

    If however I comment the line

    Code:
    myProc(STR$(q))
    in myProc and re-run it I get the different answer in the message box from pbMain.

    I've using PB for the past two years for my PhD research work and I've seen this behaviour before. Would appreciate it alot if someone could shed some light on this.

    Leave a comment:


  • Brian Chirgwin
    replied
    #Register None

    Alan,

    Add

    Code:
    #Register None
    This can go in the function GetChiPValue or at the top of the app.


    Originally posted by Alan Vella View Post
    Hi all,


    If I compile and execute the above code, the message box pops up with the (wrong) answer 0.000000000000000100000001686.

    If I compile and DEBUG the above code and then run it in debug mode I get a different (!) answer (the right one): 0.100008508707700254000000000.

    Am I the only one whose getting this kind of behaviour?

    Cheers,

    Alan.
    Last edited by Brian Chirgwin; 21 Jan 2009, 02:28 PM. Reason: shorted Alan's quote

    Leave a comment:


  • Mel Bishop
    replied
    After modifying to cc404, I tried your code otherwise as-is. Same results.

    Replaced FORMAT$ with USING$ and still got the same results. Hmmmmm.....

    Don't have a clue.

    Leave a comment:


  • Alan Vella
    started a topic gremlins

    gremlins

    Hi all,

    I need help with a small piece of code ...

    Code:
    #COMPILE EXE
    #DIM ALL
    
    
    FUNCTION GetChiPValue(BYVAL X AS EXT, BYVAL F AS EXT) AS EXT
    '
    ' FUNCTION PCHI2 - CALCULATES THE P-VALUE FROM
    ' THE CHI-SQUARE VALUE AND THE DEGREES OF FREEDOM
    ' The probability is calculated using series expansion 26.4.6. For the
    ' gamma functions 6.1.12, 6.1.8 and 6.1.1 are used.
    ' In: Handbook of mathematical Functions. Editors: Abramowitz M & Stegun IA,
    ' Dover, New York, 1972.
    ' Original code by Erik Christensen
            LOCAL D##,E##,R##,G##,H##,SL##,S##,T##,P##,C##,SK##,Q##
            Q = 1
            IF X = 0 OR F = 0 THEN GOTO 26
            D = F : E = D / 2 : R = F - INT(F / 2) * 2
            G = 1
            IF R > .3 THEN GOTO 20
        19  E = E - 1
            IF E < 1.8 THEN GOTO 22
            G = G * E : GOTO 19
        20  G = SQR(ATN(1) * 4) ' = PI
        21  E = E - 1
            IF E < .3 THEN GOTO 22
            G = G * E: GOTO 21
        22  H = ((X / 2) ^ (D / 2) * EXP(-X / 2)) / (X * G)
            SL = H * 2 * X / D : S = 0 : T = 0 : P = 1
        23  D = D + 2 : P = P * X / D : S = S + P : C = ABS(S - T)
            IF C < 1E-16 THEN GOTO 24
            T = S : GOTO 23
        24  SK = (S + 1) * SL : Q = 1 - SK
        25  IF Q < 1E-16 THEN Q = 1E-16
        26  FUNCTION = Q
    
    END FUNCTION
    
    
    FUNCTION PBMAIN () AS LONG
        LOCAL xxx AS EXT
        xxx = GetChiPValue(4.605, 2)
        MSGBOX( FORMAT$( xxx, "0.000000000000000000000000000" ) )
    END FUNCTION
    If I compile and execute the above code, the message box pops up with the (wrong) answer 0.000000000000000100000001686.

    If I compile and DEBUG the above code and then run it in debug mode I get a different (!) answer (the right one): 0.100008508707700254000000000.

    Am I the only one whose getting this kind of behaviour?

    Cheers,

    Alan.
Working...
X