Jump to content
dhe

Need Help XB and nested If's

Recommended Posts

I've never been able to figure out how to do nested if's, in XB. I am trying to implement checking for a leap year.

I can do that thing in c or pascal, but can't figure out how to do that in XB - even brute forcing it.

 

Microsoft says the correct STEPS are:

How to determine whether a year is a leap year

To determine whether a year is a leap year, follow these steps:

  1. If the year is evenly divisible by 4, go to step 2. Otherwise, go to step 5.
  2. If the year is evenly divisible by 100, go to step 3. Otherwise, go to step 4.
  3. If the year is evenly divisible by 400, go to step 4. Otherwise, go to step 5.
  4. The year is a leap year (it has 366 days).
  5. The year is not a leap year (it has 365 days).

Some example java code - which would look about the same in c or pascal ...

So basically a top end IF with more IF's in a block.

 

Can anyone help with how to do something like that in XB?

 

 

public class Main {

  public static void main(String[] args) {

    // year to be checked
    int year = 1996;
    boolean leap = false;

    // if the year is divided by 4
    if (year % 4 == 0) {

      // if the year is century
      if (year % 100 == 0) {

        // if year is divided by 400
        // then it is a leap year
        if (year % 400 == 0)
          leap = true;
        else
          leap = false;
      }
      
      // if the year is not century
      else
        leap = true;
    }
    
    else
      leap = false;

    if (leap)
      System.out.println(year + " is a leap year.");
    else
      System.out.println(year + " is not a leap year.");
  }
}
  • Like 2

Share this post


Link to post
Share on other sites

Just add line numbers to each line:

  'Leap Year Determination Program (LEAP.BAS)
   INPUT "Year (eg 1998)";yr
   leap$="N"
   IF yr MOD 4 = 0 THEN leap$ = "Y"
   IF yr MOD 100 = 0 THEN leap$ ="N"
   IF yr MOD 400 = 0 THEN leap$ = "Y"
   IF leap$ = "Y" THEN
     PRINT yr; " is a leap year"
   ELSE
     PRINT yr; " is NOT a leap year"
   END IF

 

Share this post


Link to post
Share on other sites

The bigger problem here is the lack of the MOD operator in XB.

  • Like 3

Share this post


Link to post
Share on other sites

I think this will work:

 

Using Rich's example.   Use:

 

IF yr / 4 = INT(yr / 4 ) THEN leap$ = "Y"

etc.

 

  • Like 4

Share this post


Link to post
Share on other sites

Well mod is easy to duplicate in XB:

PRINT 5/2=INT(D)

PRINT D*2=INT(M)

PRINT 5-D=INT(MOD)

PRINT INT(MOD)

MOD = INT(1)

 

ANOTHER EXAMPLE:

PRINT 23/7=INT(D)

PRINT D*7=INT(M)

PRINT 23-M=INT(MOD)

PRINT INT(MOD) 

MOD = INT(2)

 

Not really that complicated using XB.

  • Like 3

Share this post


Link to post
Share on other sites

to add to Rich's post, DEF can get you close to MOD though you only get one parameter.

 

100 DEF MOD(XX)=YR-INT(YR/XX)*XX
200 FOR YR=2096 TO 2104
400 LEAP$="NOT LEAP"!RESET
410 IF MOD(4)<>0 THEN 500
420 IF MOD(100)<>0 THEN 450
430 IF MOD(400)<>0 THEN 500
450 LEAP$="LEAP"
500 PRINT YR;LEAP$
550 NEXT YR

image.png.1c8509c46f7d0f0a6d7030d0baafefb5.png

  • Like 2

Share this post


Link to post
Share on other sites
5 hours ago, dhe said:

Microsoft says the correct STEPS are:

 

You're taking your example from Microsoft???

 

There have been many occurrences of leap year bugs:

  • Microsoft Excel has, since its earliest versions, incorrectly considered 1900 to be a leap year, and therefore that February 29 comes between February 28 and March 1 of that year. The bug originated from Lotus 1-2-3, and was purposely implemented in Excel for the purpose of backward compatibility. Microsoft has written an article about this bug, explaining the reasons for treating 1900 as a leap year.[7] This bug has been promoted into a requirement in the Ecma Office Open XML (OOXML) specification.[8][9]

:twisted:

  • Like 1
  • Haha 1

Share this post


Link to post
Share on other sites
1 hour ago, dgrissom said:

I think this will work:

 

Using Rich's example.   Use:

 

IF yr / 4 = INT(yr / 4 ) THEN leap$ = "Y"

etc.

 

Bad leap year algorithm (many languages)[edit]

The following code is an example of a leap year bug that is seen in many languages. It may cause either a Category 1 or Category 2 impact, depending on what the result is used for. It incorrectly assumes that a leap year occurs exactly every four years.[6]

bool isLeapYear = year % 4 == 0;

The correct leap year algorithm is explained at Leap Year Algorithm.

 

Uhoh, this looks familiar!:|

  • Like 2

Share this post


Link to post
Share on other sites
Posted (edited)

Here it is with the important code all in one line:


10 INPUT Y
20 LY=-((Y/4)=INT(Y/4))+((Y/100)=INT(Y/100))-((Y/400)=INT(Y/400))
30 PRINT "LEAPYEAR=";LY
40 GOTO 10

If LY=1 then it is a leap year, if 0 then it is not a leap year. To explain:

-((Y/4)=INT(Y/4)) returns a value of 1 if true and 0 if false, so if the year is divisible by 4 then LY=1.

Then ((Y/100)=INT(Y/100))  returns a value of -1 if true and 0 if false, so if the year is divisible by 100 then 1 is subtracted from LY, making it 0.

Then -((Y/400)=INT(Y/100)) returns a value of 1 if the year is divisible by 400

 

(Edit) This is a tiny bit more compact:

20 LY=((Y AND 3)>0)-((Y/100)<>INT(Y/100))-((Y/400)=INT(Y/400))
 

 

Edited by senior_falcon
  • Like 3
  • Thanks 1

Share this post


Link to post
Share on other sites
PTM    TEXT '1155P2122299352*'

ADV9   CLR  R3
       MOVB @PTM+12,R3
       SWPB R3
       INC  R3
       CI   R3,>34
       JNE  NEXT6
       LI   R3,>3100
       MOVB R3,@PTM+12
       JMP  ADV10
NEXT6  SWPB R3
       MOVB R3,@PTM+12

This is what I've been using since '99... Part of the first assembly program I'd ever coded to date that used compares and conditional jumps. I wrote it based on the assumption that nothing more than incrementing and limits were required to produce an accurate clock/calendar.

 

I seem to recall running it through a minute-by-minute high-speed advance of 10 years, without once setting off the S-D mechanism. I'm still here, so it must-be accurate?:grin:

  • Like 1
  • Thanks 1

Share this post


Link to post
Share on other sites

Thank you all for your help.

Senior_Falcon thanks most of all, you laid out the example in code and words, I think if I take each part one at a time, I can figure out, how to snap them together to make multiple if...

Guess I've just been 'spoiled' by if {block if {block}} !

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

So, it seems that I owe this thread a debt of gratitude ...for helping me notice the not-so-much a bug, as more of a logic error.

 

I was under the impression that leap year came every 3 years! 

 

ADV9   CLR  R3
       MOVB @PTM+12,R3
       SWPB R3
       INC  R3
       CI   R3,>34
       JNE  NEXT6
       LI   R3,>0030
NEXT6  SWPB R3
       MOVB R3,@PTM+12

 

So, before... the program worked correctly, but was wrong!
Whereas now... the program works wrongly, but is correct.:D

 

All done.:lol:

  • Like 2
  • Haha 2

Share this post


Link to post
Share on other sites
8 hours ago, dhe said:

I think if I take each part one at a time, I can figure out, how to snap them together to make multiple if...

see post #6 if you are aiming for IF/THEN statements.

  • Like 1

Share this post


Link to post
Share on other sites
On 8/5/2021 at 3:42 AM, senior_falcon said:

20 LY=((Y AND 3)>0)-((Y/100)<>INT(Y/100))-((Y/400)=INT(Y/400))

very elegant! 

 

I fell in love with those boolean expressions when a friend of my father showed it to me back in 1983 .. often much faster than IF-THEN. But I didn't know the "AND" trick for MOD. I guess I have to update my TiCodEd Standard-Library, currently

sub mod(n,d,m)
  m = n - int(n/d) * d
subend

The AND calculation takes only one third of the time.

 

Talking of IF-THEN, we did not really answer the original question this way...

  • Like 2

Share this post


Link to post
Share on other sites

Guess I need to add MOD(number,divisor,remainder) to RXB in Assembly ROMs.

NUMBER=5

DIVISOR=2

REMAINDER=1

or

NUMBER=23

DIVISOR=7

REMAINDER=2

Share this post


Link to post
Share on other sites
27 minutes ago, RXB said:

Guess I need to add MOD(number,divisor,remainder) to RXB in Assembly ROMs.

NUMBER=5

DIVISOR=2

REMAINDER=1

or

NUMBER=23

DIVISOR=7

REMAINDER=2

Out of curiosity, is it not possible to make MOD an operator like AND and OR?  Doing so you could have a proper statement of 2021 MOD 4, &c.

Share this post


Link to post
Share on other sites
52 minutes ago, OLD CS1 said:

Out of curiosity, is it not possible to make MOD an operator like AND and OR?  Doing so you could have a proper statement of 2021 MOD 4, &c.

NO unlike others 2 parameters are needed and returns one the remainder.

I guess MIN(low,high) or MAX(high,low) could be used instead.

So you would need to assign a variable:

X=MOD(number,divisor)

X would be the result like X would equal 2 for X=MOD(23,7)

 

Share this post


Link to post
Share on other sites
4 hours ago, RXB said:

NO unlike others 2 parameters are needed and returns one the remainder.

I guess MIN(low,high) or MAX(high,low) could be used instead.

So you would need to assign a variable:

X=MOD(number,divisor)

X would be the result like X would equal 2 for X=MOD(23,7)

 

Rich if you are going to add MOD you might want a DIV function too, that returns two values, the dividend and the remainder.

Forth uses this and it is baked in to the 9900 DIV instruction anyway.

Just a thought.

  • Like 1

Share this post


Link to post
Share on other sites
7 hours ago, TheBF said:

... you might want a DIV function too, that returns two values, the dividend and the remainder.

 

That would be the quotient and the remainder. 🙂

 

...lee

  • Like 2

Share this post


Link to post
Share on other sites
1 hour ago, Lee Stewart said:

 

That would be the quotient and the remainder. 🙂

 

...lee

Yes it would.

Thank you.

  • Like 1

Share this post


Link to post
Share on other sites
14 hours ago, RXB said:

So you would need to assign a variable:

X=MOD(number,divisor)

X would be the result like X would equal 2 for X=MOD(23,7)

Rich, would you need a new token for this?

  • Like 1

Share this post


Link to post
Share on other sites
3 hours ago, Lee Stewart said:

That would be the quotient and the remainder. 🙂

For quite a while I believed that "rational numbers" got their name because they were in some sense "good", "understandable", while the "irrational numbers" were the opposite.

 

But rational numbers are merely those that can be expressed by a ratio (a/b). Often, the simpler explanation is the better one.

  • Like 2

Share this post


Link to post
Share on other sites
2 hours ago, SteveB said:

Rich, would you need a new token for this?

We have a ton of free tokens in XB:

Spoiler

***********************************************************
*                BASIC KEYWORD TABLE
*      THE TOKEN IS ITS LEFT BINDING POWER
***********************************************************
KEYTAB DATA CHAR1,CHAR2,CHAR3,CHAR4,CHAR5
       DATA CHAR6,CHAR7,CHAR8,CHAR9,CHARA
CHAR1  TEXT '!'
       BYTE TREMZ             *  !
       TEXT '#'
       BYTE NUMBEZ            *  #
       TEXT '&'
       BYTE CONCZ             *  &
       TEXT '('
       BYTE LPARZ             *  (
       TEXT ')'
       BYTE RPARZ             *  )
       TEXT '*'
       BYTE MULTZ             *  *
       TEXT '+'
       BYTE PLUSZ             *  +
       TEXT ','
       BYTE COMMAZ            *  ,
       TEXT '-'
       BYTE MINUSZ            *  -
       TEXT '/'
       BYTE DIVIZ             *  /
       TEXT ':'
       BYTE COLONZ            *  :
       TEXT ';'
       BYTE SEMICZ            *  ;
       TEXT '<'
       BYTE LESSZ             *  <
       TEXT '='
       BYTE EQUALZ            *  =
       TEXT '>'
       BYTE GREATZ            *  >
       TEXT '^'
       BYTE CIRCUZ            *  ^
       BYTE >FF
CHAR2  TEXT '::'
       BYTE SSEPZ             *  ::
       TEXT 'AT'
       BYTE ATZ               *  AT
       TEXT 'GO'
       BYTE GOZ               *  GO * RXB MOTION
       TEXT 'IF'
       BYTE IFZ               *  IF
       TEXT 'ON'
       BYTE ONZ               *  ON * RXB ONKEY
       TEXT 'OR'
       BYTE ORZ               *  OR
       TEXT 'PI'
       BYTE PIZ               *  PI
       TEXT 'TO'
       BYTE TOZ               *  TO
       BYTE >FF
CHAR3  TEXT 'ABS'
       BYTE ABSZ              *  ABS
       TEXT 'ALL'
       BYTE ALLZ              *  ALL
       TEXT 'AND'
       BYTE ANDZ              *  AND
       TEXT 'ASC'
       BYTE ASCZ              *  ASC
       TEXT 'ATN'
       BYTE ATNZ              *  ATN
       TEXT 'BYE'
       BYTE >03               *  BYE
       TEXT 'CON'
       BYTE >01               *  CONtinue
       TEXT 'COS'
       BYTE COSZ              *  COS
       TEXT 'DEF'
       BYTE DEFZ              *  DEF
* GKXB added token
       TEXT 'DEL'
       BYTE >09               *  DEL
       TEXT 'DIM'
       BYTE DIMZ              *  DIM
       TEXT 'END'
       BYTE ENDZ              *  END
       TEXT 'EOF'
       BYTE EOFZ              *  EOF
       TEXT 'EXP'
       BYTE EXPZZ             *  EXP
       TEXT 'FOR'
       BYTE FORZ              *  FOR
       TEXT 'INT'
       BYTE INTZ              *  INT
       TEXT 'LEN'
       BYTE LENZ              *  LEN
       TEXT 'LOG'
       BYTE LOGZ              *  LOG
       TEXT 'MAX'
       BYTE MAXZ              *  MAX
       TEXT 'MIN'
       BYTE MINZ              *  MIN
       TEXT 'NEW'
       BYTE >00               *  NEW * RXB CALL NEW
       TEXT 'NOT'
       BYTE NOTZ              *  NOT
       TEXT 'NUM'
       BYTE >04               *  NUMber
       TEXT 'OLD'
       BYTE >05               *  OLD * RXB SAMS
       TEXT 'POS'
       BYTE POSZ              *  POS
       TEXT 'REC'
       BYTE RECZ              *  REC
       TEXT 'REM'
       BYTE REMZ              *  REMark
       TEXT 'RES'
       BYTE >06               *  RESequence
       TEXT 'RND'
       BYTE RNDZ              *  RND * RXB CHANGED
       TEXT 'RUN'
       BYTE RUNZ              *  RUN * RXB SAMS
       TEXT 'SGN'
       BYTE SGNZZ             *  SGN
       TEXT 'SIN'
       BYTE SINZ              *  SIN
       TEXT 'SQR'
       BYTE SQRZ              *  SQR
       TEXT 'SUB'
       BYTE SUBZ              *  SUB
       TEXT 'TAB'
       BYTE TABZ              *  TAB
       TEXT 'TAN'
       BYTE TANZ              *  TAN
       TEXT 'VAL'
       BYTE VALZ              *  VAL
       TEXT 'XOR'
       BYTE XORZ              *  XOR
       BYTE >FF
CHAR4  TEXT 'BASE'
       BYTE BASEZ             *  BASE
       TEXT 'BEEP'
       BYTE BEEPZ             *  BEEP
       TEXT 'CALL'
       BYTE CALLZ             *  CALL
       TEXT 'CHR$'
       BYTE CHRZZ             *  CHR$
* GKXB added token
       TEXT 'COPY'
       BYTE >0A               *  COPY
       TEXT 'DATA'
       BYTE DATAZ             *  DATA
       TEXT 'ELSE'
       BYTE ELSEZ             *  ELSE
       TEXT 'GOTO'
       BYTE GOTOZ             *  GOTO * RXB ONKEY
       TEXT 'LIST'
       BYTE >02               *  LIST
* GKXB added token
       TEXT 'MOVE'
       BYTE >0B               *  MOVE
       TEXT 'NEXT'
       BYTE NEXTZ             *  NEXT
       TEXT 'OPEN'
       BYTE OPENZ             *  OPEN
       TEXT 'READ'
       BYTE READZ             *  READ
       TEXT 'RPT$'
       BYTE RPTZZ             *  RPT$
       TEXT 'SAVE'
       BYTE >07               *  SAVE * RXB SAVE IV254
       TEXT 'SEG$'
       BYTE SEGZZ             *  SEG$
       TEXT 'SIZE'
       BYTE SIZEZ             *  SIZE * RXB CALL SIZE
       TEXT 'STEP'
       BYTE STEPZ             *  STEP
       TEXT 'STOP'
       BYTE STOPZ             *  STOP * RXB MOTION
       TEXT 'STR$'
       BYTE STRZZ             *  STR$
       TEXT 'THEN'
       BYTE THENZ             *  THEN
       BYTE >FF
CHAR5  TEXT 'BREAK'
       BYTE BREAKZ            *  BREAK
       TEXT 'CLOSE'
       BYTE CLOSEZ            *  CLOSE
       TEXT 'DIGIT'
       BYTE DIGITZ            *  DIGIT
       TEXT 'ERASE'
       BYTE ERASEZ            *  ERASE
       TEXT 'ERROR'
       BYTE ERRORZ            *  ERROR
       TEXT 'FIXED'
       BYTE FIXEDZ            *  FIXED
       TEXT 'GOSUB'
       BYTE GOSUBZ            *  GOSUB
       TEXT 'IMAGE'
       BYTE IMAGEZ            *  IMAGE
       TEXT 'INPUT'
       BYTE INPUTZ            *  INPUT
       TEXT 'MERGE'
       BYTE >08               *  MERGE
       TEXT 'PRINT'
       BYTE PRINTZ            *  PRINT
       TEXT 'TRACE'
       BYTE TRACEZ            *  TRACE
       TEXT 'USING'
       BYTE USINGZ            *  USING
       BYTE >FF
CHAR6  TEXT 'ACCEPT'
       BYTE ACCEPZ            *  ACCEPT
       TEXT 'APPEND'
       BYTE APPENZ            *  APPEND
       TEXT 'DELETE'
       BYTE DELETZ            *  DELETE
       TEXT 'LINPUT'
       BYTE LINPUZ            *  LINPUT
       TEXT 'NUMBER'
       BYTE >04               *  NUMBER
       TEXT 'OPTION'
       BYTE OPTIOZ            *  OPTION
       TEXT 'OUTPUT'
       BYTE OUTPUZ            *  OUTPUT
       TEXT 'RETURN'
       BYTE RETURZ            *  RETURN
       TEXT 'SUBEND'
       BYTE SUBNDZ            *  SUBEND
       TEXT 'UALPHA'
       BYTE UALPHZ            *  UALPHA
       TEXT 'UPDATE'
       BYTE UPDATZ            *  UPDATE
       BYTE >FF
CHAR7  TEXT 'DISPLAY'
       BYTE DISPLZ            *  DISPLAY
       TEXT 'NUMERIC'
       BYTE NUMERZ            *  NUMERIC
       TEXT 'RESTORE'
       BYTE RESTOZ            *  RESTORE
       TEXT 'SUBEXIT'
       BYTE SUBXTZ            *  SUBEXIT
       TEXT 'UNBREAK'
       BYTE UNBREZ            *  UNBREAK
       TEXT 'UNTRACE'
       BYTE UNTRAZ            *  UNTRACE
       TEXT 'WARNING'
       BYTE WARNZ             *  WARNING
       BYTE >FF
CHAR8  TEXT 'CONTINUE'
       BYTE >01               *  CONTINUE
       TEXT 'INTERNAL'
       BYTE INTERZ            *  INTERNAL
       TEXT 'RELATIVE'
       BYTE RELATZ            *  RELATIVE
       TEXT 'VALIDATE'
       BYTE VALIDZ            *  VALIDATE
       TEXT 'VARIABLE'
       BYTE VARIAZ            *  VARIABLE
       BYTE >FF
CHAR9  TEXT 'RANDOMIZE'
       BYTE RANDOZ            *  RANDOMIZE
       BYTE >FF
CHARA  TEXT 'SEQUENTIAL'
       BYTE SEQUEZ            *  SEQUENTIAL
       BYTE >FF
***********************************************************

Currently token symbols not assigned:

>80, >AB, >AC, >AD, >AE, >AF, >B9, >C6, >E2, >E3, >E4, >E5, >E6, >E7, >F2

 

So I would pick >AB for MOD and >AC for DIV

Share this post


Link to post
Share on other sites
4 minutes ago, RXB said:

So I would pick >AB for MOD and >AC for DIV

As I try to keep TiCodEd RXB-compatible I would need to add them as well in my tokenizer. 

  • Like 1

Share this post


Link to post
Share on other sites
22 minutes ago, SteveB said:

As I try to keep TiCodEd RXB-compatible I would need to add them as well in my tokenizer. 

No rush RXB 2021 is a long way off.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...