problem with RND (or maybe INT)

edited January 2012 in Sinclair Basic
I'm using this statement:

LET m=(INT (RND*sn)+k1)*k2-k1

to give a pointer m to a 2-byte segment of a string l$. Items k1 & k2 are integer constants 1 & 2 and sn is the number of segments in the string (ie. half the length of the string).

If I run this statement in a continuous loop:

FOR p=k0 TO k0 STEP k0: LET m=(INT (RND*sn)+k1)*k2-k1: PRINT m: NEXT p

with sn=1 then it always prints m=1, but when run within the actual program I'm getting m=3 when sn=1, so I get a subscript error.

I presume that there's some problem with floating point evaluation. Any suggestions on how to define the expression so that it always gives a pointer within the bounds of the string?
Post edited by Battle Bunny on

Comments

  • edited January 2012
    That statement doesn't seem to do anything useful at all.

    Are you trying to get a random number between k1 and k2?
  • edited January 2012
    what does the p loop do?
  • edited January 2012
    To answer your questions:

    The statement gives an odd +ve integer (1,3,5,7,etc...) between 1 and (2*sn)-1, where 2*sn is the (variable) length of the string being scanned.

    The p loop just repeats indefinitely. The sections in the actual program code which use that structure make the "NEXT p" statement dependent upon various conditions, thus looping if any are true and dropping through to the next section if none are true. For further elucidation I've appended an example code segment; the line in question is 1342.

    To answer my question:

    There's somewhat more of a problem with the errant interpolation of a spurious "+" rather than the necessary "-", which being corrected then thoroughly resolves the matter (ie. I'd typed a "+" instead of a "-" in that statement in the actual program and hadn't noticed it). :oops:
         REM Reset a specified number of other conditions, specific & random,
         REM excluding any just set above.
    1340 LET ea=k7: LET ez=VAL "89": LET sc=CODE r$(k8): GO SUB VAL "1100":
         IF NOT sc THEN GO TO VAL "1361"
    1341 LET e$=CHR$ kG+CHR$ k5+"DROP "+STR$ sc: GO SUB e0
    1342 FOR p=k0 TO k0 STEP k0:
           LET m=INT (RND*sn+k1)*k2-k1: LET co=FN s(l$(m TO m+k1)):
           IF x$(m)="y" THEN
             NEXT p: REM closed loop
    1343   IF NOT co THEN
             GO TO VAL "1350"
    1345!  GO SUB VAL "1110":
        !  IF ht>=kCC THEN LET o$="y": GO TO VAL "1356"
    1346!  IF ht<kA THEN
             LET hk=ht: GO TO VAL "1354"
         REM Drop selected conditions
    1348   FOR e=k1 TO mz:
             IF m$(e,TO k2)=l$(m TO m+k1) THEN
                 LET me=e: GO TO VAL "1352"
    1349   NEXT e
    1350   GO SUB VAL "1114": IF mn THEN
             NEXT p: REM closed loop
    1352   LET m$(me,k5 TO )=FN h$(fm):
        !  IF ht>kA THEN
             LET hk=FN a(ht): LET hp=-k1: GO SUB VAL "1120"
    1353   PRINT AT me+k1,k0; OVER k1; INK k1;b$(TO k28):
           LET o$="y": GO TO VAL "1356"
         REM Apply -ve quantity adjustments
    1354   LET p$="Give "+STR$ hp+" "+(FN c$(co)(TO k2))+"?": LET e$="yn": GO SUB p0:
           IF o$="y" THEN
             GO SUB VAL "1115"
    1356   LET yx=yx-(o$="y"): LET x$(m)=o$: IF yx THEN
             NEXT p
    
  • edited January 2012
    sorry, I still don't get the p loop! (since all the for/to/step values are the same thing?)
  • edited January 2012
    A FOR ... NEXT loop normally terminates when the controlling variable goes beyond the limiting value. As the STEP is zero the controlling variable never changes so it can never pass the limit and thus will stay in the loop indefinitely until some other statement causes it to leave. The "from" & "to" values don't matter (as long as they are the same); it's just the step being zero which is important. It allows a section of code to be repeated depending on various conditions at various points without using numerous GO TO statements.
  • NRANRA
    edited January 2012
    Actually it's a big no-no to interfere with params, but it's just a funny version of DO-WHILE loop.

    If you unwrap the structure then it might look like this:
    5 LET k0=0: LET STEP=0: LET END=0
    10 LET m=(INT (RND*sn)+k1)*k2-k1
    15 PRINT m
    20 LET k0=k0+STEP
    25 if k0<=END GOTO 10 //next
    
  • edited January 2012
    it's just the step being zero which is important.

    So why use the step value for the start and end values as well? That seems to be deliberately obscuring the point. Now, I know Spectrum BASIC isn't modern commercial code, but if I saw someone doing something like that in anything I was asked to review at work, they'd be asked to rewrite it ASAP and stop being so silly.
  • edited January 2012
    Upon which I would have referred you to the tale of Giotto and the perfect circle.
  • SKRSKR
    edited January 2012
    Heck!

    Even a novice like me would realise that a for-next loop with impossible parameters (never ending) on a command line was there to reiterate forever.

    Heck, why are people so pedantic?
Sign In or Register to comment.