For Casio Graphic Calculators

Memory Optimisation Methods

Thanks to: fajoy@uio.satnet.net for items A17~A19,B5: (received autumn 1998) Tom Lynn for items A20~A26,B3~B4,C1. Tom Wheeley for safety modification to item A3. Item B6) is combination from fajoy, Tom Lynn and myself

There is only so much memory capacity in a graphic calculator and typing in long programs can be tedious. New models with more memory and communication cables can go some way towards solving this. However there are some simple techniques to shorten the length of a program.

There are 3 sections to this page:
A:(26 items): methods which work on all models
B:( 5 items): only for pre-9850 models such as 6300/7000/7700/9700
C:( 4 items): only for 9850 models and compatibles

***** NOTE ******
  Unless otherwise stated:
  On this page ^2 means SQUARE symbol and ^-1 means RECIPROCAL symbol
  and not a power symbol followed by 2 or -1.

  For the purposes of this page I think it is clearer to use ^2
  than the ctf \^2 \^-1
******************

Section A: For all models

A1)      If you use the same expression several times but its value does
 not change then you can assign it to a variable at the beginning and just
 use the variable later on.
 e.g.   :(X+3Y-2)/3->C:sin (X+3Y-2)->S:X+3Y->A:
 could be replaced by
        :X+3Y-2->B:B/3->C:sin B->S:B+2->A:

A2)      If you want to repeat an expression but you only want to repeat it
 once more and the repitition comes in the very next statement you can use
 'Ans'. The last value calculated is stored in the variable 'Ans'.
 e.g    :(256A^X)/3+sin(256A^X)->G:
 could be shortened by using
        :256A^X:Ans/3+sin Ans->G
       Be careful though: not all types of statements affect 'Ans'.
 An expression such as :20: or :sin 30: or :X+Y: will be stored in 'Ans'.
 But commands like the following do not change 'Ans':
        A=1=>Goto 2, Dsz B, Isz B, Lbl 1
 If an expression is assingned to a variable e.g. : sin 30->A:
 then this will not change 'Ans'. i.e. assignment statements
 do not change 'Ans'

A3)      Whenever you use something like
        :C+1->C:
 then it could be possible to change this to
        :Isz C:
 However this does not always have the same effect, because the Isz
 function is designed for looping and will miss out the next statement
 if C now equals zero. If you just want to replace C+1->C, but don't want
 the skipping and don't know what value C might have, then to be perfectly
 safe then use a dummy command afterwards e.g. :Isz C:0:

 e.g.   :C+1->C:C=0=>Goto 2:"A":Lbl 2:
 has the same effect as
        :Isz C:"A":
 Similarly for replacing :C-1->C: with :Dsz C:0:

A4)      If you want to initialise all the elements of a matrix to zero then
 use	:0Mat A->Mat A:

A5)      If you want to assign the same value to more than one memory at the
 same time, then use the '~' symbol
 i.e. :2->A:2->B:2->C: is the same as :2->A~C:
 it only works for a continuous forward range i.e. 2->G~C would not work

A6)      If you want to test several conditions before executing a command
 then you can string the => symbols together like the logical AND operator
 e.g. X<1=>Y<1=>Goto 2 will only jump to Lbl 2 if both conditions are true.

A7)      Since the last value of a program is displayed when program finishes
 you shouldn't include the last display symbol.
 e.g. 1_ 2_ 3_ 4_ will display the '4' twice. so just use 1_ 2_ 3_ 4

A8)	You can combine an assignment and display in the same statement
 e.g. A+1->B_

A9)	Zeros preceding a decimal point are unnecessary. e.g. 0.5 is .5

A10)	You can use implied multiplication e.g. (A*B*C)/(D*E*F) is ABC/DEF
 However if you use the fraction symbol then ABC/DEF means ((A*B*C)/D)*E*F

A11)	-Frac X is shorter than Frac(-X)

A12) 	Frac 12/7 gives zero as calculator assumes (Frac 12)/7
 If you want Frac (12/7) then use fraction symbol
 to save using brackets e.g. Frac 12%7
 % represents fraction symbol.
 Works even in situations like Frac (X+1)%7
 The same applies to Int and Intg

A13)	:BFrac A%B: is a shorter way of getting (A mod B) than
 :A-BInt(A/B): however :BFrac ((B^-1)*A): will not always give an exact
 integer due to rounding errors. Compare the below commands:
 e.g. try 7Frac((7^-1)(12))->A_
	  A-5_				;this doesn't work
          7Frac 12%7->A_
          A-5_				;but this does

A14)	:A!<>1:  can be used to test if A is not equal to 1 or 0
 Providing that A is a small positive integer. Or :Abs A>1: if
 you know that A is any non-negative number


A15)	Consider an expression containing both Frac X and Int X
 e.g  30Frac X-Int X
     =31Frac X-Frac X-Int X
     =31Frac X-X		;using the identity X=Int X+Frac X
 So the third expression is shorter than what you started with.


A16) 	If you want to execute different commands depending on the
 result of some condition
 e.g.:C=1=>1->D:C=2=>2->D
 then this can be shortened by doing the first condition anyway
 and then overwriting it if necessary:
 1->D:C=2=>2->D

A17)	Don't press [EXE] on the last line of a stored program

A18)	Replace X=0=>Goto 1: Y=0=>Goto 1  by  XY=0=>Goto 1

A19)	"LABEL"?->L   in one command produces this output
 LABEL?    And the cursor waits for the value of L.
 which is shorter than "LABEL":?->L in two separate commands

A20) 	Consider whether to use 'top-heavy' fractions, or decimals.
 For example
   X+12%3%4
 becomes
   X+12.75
 saving one byte, or
   X+51%4
 saving two.

A21) 	Consider which is shorter, / or reciprocal (X^-1).
 For example,
   1/3
 becomes
   3^-1
 saving one byte, but
   (2X)^-1
 becomes
   1/2X
 which also saves one byte.

A22) 	Try any other algebraic manipulations which seem appropriate.  For
 example, (X+2)(X-7) should be replaced with X^2-5X-14 to save two bytes.

A23) 	Using a subroutine will save bytes if it replaces repeated code
 which is 5 or more bytes long, or even shorter code which is repeated
 more than once.
 For example,
   "ABC"
   "ABC"             (11 bytes)
 becomes
   Prog 1:Prog 1     (5 bytes)
 and (Prog 1)
   "ABC"             (5 bytes)

 (Note that this only holds on old calcs, which store programs in
 "slots".
 The newer ones which support filenames require extra space for the file
 system, plus the bytes needed to actually call the programs, so use short
 filenames on these calcs.)

A24) 	Rearranging code blocks can sometimes shorten programs.
 For example,
   "ABC"
   Goto 0
   Lbl 1
   "GHI"
   Goto 2
   Lbl 0
   "DEF"
   Goto 1
   Lbl 2

 becomes simply

   "ABC"
   "DEF"
   "GHI"

 saving eighteen bytes!

 This is of course an extreme example, but this kind of thing can happen
 accidentally while writing and rewriting programs.  You should check for
 poorly structured code such as this when you finish writing a program.

A25) 	Some numbers can be written in a shorter form.  For example,

 120 = 5!, saving one byte
 100 = \10^2, saving one byte
 1000 = \10^3, saving two bytes
 ..001 = \10^-3, saving one byte
 ..25 = 4^-1, saving one byte
 ..125 = 8^-1, saving two bytes

 There are of course an almost infinite number of others which could also
 be shortened in this way, but which are not so recognisable,
 e.g. 2187 = 3^7, saving one byte, but optimisation such as this is only
 for the terminally over-enthuastic!  There are many cases however, where
 using an approximation may work, for example, by using square root to find
 the nearest square.  For example, instead of 2187, would your program work
 with 47^2 = 2209 (saving one byte)?

A26) 	Try renaming variables so that ~ assignments can be made.
   (Does 0->\r~\theta work?)

A27) 	Try redoing all expressions to allow ~ assignments to be made.
     e.g. replace
     0->R
     1->X~Y
     ...			;Some stuff which makes value of R go up and down
     ...			;in a way independent of the value of R.
     R=0=>Goto 1

     with

     1->R~Y
     ...
     ...
     R=1=>Goto 1

Section B: For Pre-9x50 models only:

B1)      If you want some of your value memories to be zero at the start of
 the program then use the :Mcl: statement at the beginning. This puts zero
 into all the value memories.

B2)	When using value memory arrays then A[J] is okay if J is allowed
 to vary but if you have a fixed number like A[5] then shorten this to the
 corresponding value memory e.g. A[5]=F

B3)	More generally than B2):
 Never use offset values in array memories.  For example,
   A[X+1]
 becomes
   B[X]
 saving two bytes.  The only exception to this is if changing the letter
 would take you outside the alphabet, as in A[X-1] or Z[X+1].

B4)	Trailing brackets ( [ are unnecessary.
 e.g 1(2+3(4+5 is fine instead of 1(2+3(4+5)) , as is
 A[15->B instead of A[15]->B. Of course, (1+2*3 is not the same as (1+2)*3
 as that bracket wasn't at the end.
 Not the same on 9850s: see item C1)

B5)	Replace sqrt(X^2+Y^2    by   Pol(X,Y   if you don't care for
   the values of I and J.

B6) Instead of going up the way using variable Z like so:

 1->Z:Lbl 1
 ?->A[Z]
 Isz Z:Z<=9=>Goto 1		;23 steps

 First rewrite to go down the way with 9-Z+1:

 9->Z:Lbl 1
 ?->A[9-Z+1]			; 9-Z+1 makes index go from 1 to 9
 Dsz Z:Goto 1			; still 23 steps

 then modifying further using items B3) & B4):

 9->Z:Lbl 1
 ?->K[-Z
 Dsz Z:Goto 1			;19 steps

Section C: For 9850 and compatible models only:

C1)	Trailing brackets (normal, square or curly) are mostly unnecessary.
 The exception is immediately before = <> < > <= >= relational signs
 where brackets must be put in because on 9x50 models equations become
 logical test expressions with truth value 0 or 1.

C2)	If you want to convert Getkey codes for keys 1-9 into the actual
 number that was pressed then the long way to do it is:
 Getkey->A
 A=72=>1->G:A=62=>2->G:A=52=>3->G
 A=73=>4->G:A=63=>5->G:A=53=>6->G
 A=74=>7->G:A=64=>8->G:A=54=>9->G

 That takes 84 steps. The short way to do it is:
 .1Getkey
 2-Ans+31Frac Ans->G

 which only takes 15 steps. Or to also detect the number 0 then use:
 .1Getkey
 2-Ans+31Frac Ans+2(Ans=7.1->G

 Also in reverse to convert numbers 1-9 into Getkey codes use:
 ?->N
 (N-1)/3			;don't use reciprocal or get rounding errors
 72+Ans-31Frac Ans->G

 If you want to take into account the number 0 as well then use:
 ?->N
 (N-1)/3			;don't use reciprocal or get rounding errors
 72+Ans-31Frac Ans-11(N=0->G

C3)	To convert Getkey codes for letters A~Z into numbers 1~26 use:
 .1Getkey
 6-10Frac Ans->R
 8-Int Ans+5R+R(R<3->G


C4)	If you are applying the same command to all entries in a List
 then you can apply it just once to the whole list. Most scientfic
 calculations and logic commands can be applied to a list
 e.g. (List 1=0)->List 1 will give a list of zeros and ones accordingly.
         sin List 1->List 1 will take sine of every entry.
      List 1(Abs List 1>1 \exp 10)->List 1 will zero all elements
 which are too small.


(c) Roy F. A. Maclean 1996-1999. Last updated 31st May 1999
rfamgm at gmail
http://www.spiderpixel.co.uk/caspro