We're glad you came by, but you might find what you're looking for elsewhere.

TI-Basic Developer is not the site it once was. While its information on commands and other calculator features remains almost second-to-none, its forum, archives, and even hosting service, Wikidot, have been decaying for years. The calculator community would love to see what you're working on, or help you in your next coding adventure, but TI-Basic Developer is no longer the place to do it.

Instead, you should head over to Cemetech (primarily American) or TI-Planet (primarily international). Both are active, well-established forums with their own archives, chatrooms, reference material, and abundant coding tools and resources. We'll see you there, we hope.

TI-Basic Developer

The TI-Basic Information Repository


The Home Screen and Its Commands

The TI-83/+/SE home screen is composed of eight rows (1 to 8 from top to bottom) by sixteen columns (1 to 16 from left to right); it is like a grid. The home screen uses the large, easy to see, 5 by 7 font. Because each character takes up the same 5 by 7 space, regardless of what its actual size is, the text cannot be moved around to get pixel perfect precision.
The table below shows the coordinates used for the Output( command (see below). Enter these coordinates in the Output( command as shown, only without the parentheses. There are different coordinates for a TI-84+C SE (10 rows and 26 columns, to be exact).

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 (1,1) (1,2) (1,3) (1,4) (1,5) (1,6) (1,7) (1,8) (1,9) (1,10) (1,11) (1,12) (1,13) (1,14) (1,15) (1,16)
2 (2,1) (2,2) (2,3) (2,4) (2,5) (2,6) (2,7) (2,8) (2,9) (2,10) (2,11) (2,12) (2,13) (2,14) (2,15) (2,16)
3 (3,1) (3,2) (3,3) (3,4) (3,5) (3,6) (3,7) (3,8) (3,9) (3,10) (3,11) (3,12) (3,13) (3,14) (3,15) (3,16)
4 (4,1) (4,2) (4,3) (4,4) (4,5) (4,6) (4,7) (4,8) (4,9) (4,10) (4,11) (4,12) (4,13) (4,14) (4,15) (4,16)
5 (5,1) (5,2) (5,3) (5,4) (5,5) (5,6) (5,7) (5,8) (5,9) (5,10) (5,11) (5,12) (5,13) (5,14) (5,15) (5,16)
6 (6,1) (6,2) (6,3) (6,4) (6,5) (6,6) (6,7) (6,8) (6,9) (6,10) (6,11) (6,12) (6,13) (6,14) (6,15) (6,16)
7 (7,1) (7,2) (7,3) (7,4) (7,5) (7,6) (7,7) (7,8) (7,9) (7,10) (7,11) (7,12) (7,13) (7,14) (7,15) (7,16)
8 (8,1) (8,2) (8,3) (8,4) (8,5) (8,6) (8,7) (8,8) (8,9) (8,10) (8,11) (8,12) (8,13) (8,14) (8,15) (8,16)

The home screen does not have access to any of the drawing commands that are available on the graph screen (such as the points, pixels, lines, or circles). This leaves you with just using the text to imitate graphics, which unfortunately does not look very good. Using the home screen is faster than using the graph screen, though.

There are five main home screen commands:

  • ClrHome — Clears the home screen of any text or numbers. It should be used at the beginning of a program and at the end to make sure the user has a clear screen afterwards.
  • Disp — Displays one or more arguments of text or values on a new line on the home screen and scrolls down if necessary. Disp should be used instead of Output( in most cases.
  • Output( — Displays text or a value at a specified row and column location on the home screen. It also wraps the text or value around the screen if needed.
  • Pause — Pauses the program and displays the home screen until the user presses ENTER. It also can display text or a value with scrolling available.
  • Menu( — Displays a generic menu on the home screen, with up to seven options for the user to select from. It utilizes branching to make the menu.

You should commit yourself to learning how to use these commands and then actually start using them in your programs. They are rather basic, but still quite powerful. Once you have them down, move on to the graph screen commands.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/homescreen


The Graphscreen and Its Commands

The TI-83/+/SE graphscreen is 64 rows, by 96 columns, the coordinates for the pixels being 0 to 62 a total of 63 and 0 to 93 a total of 94. So amount of editable X and Y pixels are 95 and 63. With the coordinates 0,0 actually being the very top left pixel. The graphscreen uses the small (3 by 5) font, which allows you to display more text; and the large (5 by 7) font, which allows you to make the graphscreen look like the homescreen. On the color calculators, the available screen is 165rows by 265 columns, starting at 0. Graphics can also be displayed on the graphscreen, in the form of points, pixels, lines, or circles, as well as shading an area of the graphscreen. These graphics can be displayed with the text, and they can be saved to pictures for later use.

The graphscreen does not have access to some of the commands that are available on the homescreen (such as the user input). In addition, some of the graphscreen commands have their coordinates reversed, so the row comes before the column. These commands also take longer to draw.

Setting up the Graphscreen

Note: it is good practice to save the current settings at the beginning of the program with StoGDB, and recall it later with RclGDB. The syntax for those commands is illustrated below.

Before using the graphscreen, you first need to set it up appropriately. When displaying text or drawing graphics, you want to make sure that they are displayed how you want them to be displayed. This is achieved by clearing the graphscreen, adjusting the window dimensions, and turning off the graph formats.

Clearing the Graphscreen

The ClrDraw command is the graphscreen equivalent to ClrHome. ClrDraw is usually used before you display text or draw anything on the graphscreen, to ensure that it won't be interrupted by anything that was previously displayed on the graphscreen.

Format
:ClrDraw

You also want to make sure to clear the graphscreen when exiting programs. This ensures that the next program that the user runs won't have to deal with whatever text or graphics your program left behind. It also helps the user, because they won't have to manually clear the graphscreen.

To use the ClrDraw command, you should first be in the Program editor for your program. In the Program editor, press 2nd and PRGM. Then press ENTER on ClrDraw. Now the command has been put into your program.

Adjusting the Window Dimensions

After clearing the graphscreen, you will want to set the window dimensions to the desired size. There are four window variables that control the window dimensions: Xmin, Xmax, Ymin, and Ymax. When storing values in these variables, you have to remember that the max variables always have to be larger then the min variables, otherwise you will get an error.

The Xmin variable sets the minimum value that the X coordinate can have. The Xmax variable sets the maximum value that the X coordinate can have. The Ymin variable sets the minimum value that the Y coordinate can have. The Ymax variable sets the maximum value that the Y coordinate can have. You can use these variables like regular variables.

Format
:#→Xmin:#→Xmax
:#→Ymin:#→Ymax

Although the graphscreen is 96 pixels wide by 64 pixels tall on the monochrome calculators, and 320 pixels wide by 240 pixels tall on the color calculators, the bottom row is unusable for monochrome TI-Basic programs and the far right column is reserved for the monochrome pause indicator. On the color calculators, the screen is taken up with a border, and the info bar on the top of the screen. So, most monochrome programmers set the window dimensions to 0 for Xmin and Ymin, 94 for Xmax, and 62 for Ymax. This sets the X range from -1 to 94 totaling 95 columns and the Y range from -1 to 62 totaling 63. On the color calculators, most programs set the screen to ZStandard, then ZSquare, making the screen 20 spaces on the Y axis, and just over 32 on the X.

Format
:0→Xmin:94→Xmax
:0→Ymin:62→Ymax

In a simpler notion, to make everything positive from the bottom left corner you would use the following code.

Format
:1→Xmin:95→Xmax
:1→Ymin:63→Ymax

Others set 0 for Xmin and Ymax, 94 for Xmax and -62 for Ymin. This allows them to use the same coordinates for pixel and point commands, as pixel rows on the screen are counted starting from the top. So the top pixel row is 0 and the bottom row is 62, while the point top row is 0 and bottom row is -62.

In addition to those four window variables, there are two other window variables that you can use to set the window dimensions. ΔX is the difference between Xmin and Xmax divided by the graphscreen width and ΔY is the difference between Ymin and Ymax divided by the graphscreen height. When you set Xmin and Ymin to 0, you just need to set ΔX and ΔY to 1 to make Xmax 94 and Ymin 62.

:0→Xmin:94→Xmax
:0→Ymin:62→Ymax
Replace with ΔX and ΔY
:0→Xmin:1→ΔX
:0→Ymin:1→ΔY

To use the window variables, you should first be in the Program editor for your program. In the Program editor, press VARS and 1, then scroll down to whichever variable you want to use and press ENTER. Now the variable has been put into your program. You then have to type what number you want to set the window variable to.

In addition to setting the window variables individually, there are also a couple commands that can set them all at the same time. Although these commands are only useful in a couple situations, they are a lot easier (and smaller) to use.

The ZStandard command sets the window dimensions to their default settings (which is -10 for Xmin and Ymin, and 10 for Xmax and Ymax). The ZSquare command sets the window dimensions so that they make the screen square. This is important when drawing circles because it makes the circles look like circles (instead of ellipses).

Format
:ZStandard
:ZSquare

To use the ZStandard or ZSquare command, you should first be in the Program editor for your program. In the Program editor, press the ZOOM key. Then scroll down to whichever command you want to use and press ENTER. Now the command has been put into your program.

Turning off the Graph Formats

After adjusting the window dimensions, you will want to turn off the graph formats. The graph formats include the grids, plots, axes, and functions. These can be turned off and turned on, depending on what is desired.

The GridOff command turns the grid off and the GridOn command turns the grid on. The PlotsOff command turns the plots off and the PlotsOn command turns the plots on. The AxesOff command turns the axes off and the AxesOn command turns the axes on. The FnOff command turns all of the functions off and the FnOn command turns all of the functions on.

Format
:GridOff/On
:PlotsOff/On
:AxesOff/On
:FnOff/On

The plots and functions commands can also be used to just deal with one or two plots or functions, instead of all of them. You just put the plots or functions and their numbers after the command, separating each one with a comma.

Format
:PlotsOff/On function#[,function#,...]
:FnOff/On function#[,function#,...]

To use the graph formats, you should first be in the Program editor for your program. In the Program editor, press 2nd and ZOOM. Then scroll down to GridOff/On or AxesOff/On and press ENTER. To use the PlotsOff/On or FnOff/on commands, you need to press 2nd and 0 for the Catalog menu. Then scroll down to the command or press the first letter of the command and press ENTER. Now the command has been put into your program.

Graph Databases (GDB)

There are 10 graph database (GDB) variables (GDB0 through GDB9) that store the window and graph format settings, so they can later be used to recreate the graphscreen; GDBs do not contain graphics or stat plot definitions. If a program utilizes the graphscreen, it should restore the graphscreen settings with a GDB when the program finishes executing.

The StoreGDB command saves the graph settings in a GDB. It is best used at the beginning of a program. The RecallGDB command restores the graph settings that are stored in a GDB. It is best used after a program is finished executing. You should remember to delete the GDB after recalling it.

Format
:StoreGDB #
:RecallGDB #

To use the GDB commands, you should first be in the Program editor for your program. In the Program editor, press 2nd DRAW and > > twice. Then scroll down to StoreGDB or RecallGDB and press ENTER. Finally, press the number of the GDB you want to use.

Putting all of these commands together, here is a typical way to set up the graphscreen at the beginning of a program:

PROGRAM:GRAPHSET
:StoreGDB 1
:ClrDraw
:GridOff
:PlotsOff
:AxesOff
:FnOff
:0→Xmin:1→ΔX
:0→Ymin:1→ΔY

Graphing Functions on the Graphscreen

Graphing functions is primarily used in math programs. There are three commands that are used for graphing functions: DrawF, DrawInv, and Tangent. The commands do not change the function variables, and their graphs (and tangent line) are erased when any command changes the graphscreen.

The DrawF command graphs an expression. The DrawInv command graphs the inverse of an expression by plotting X values on the y-axis and Y values on the x-axis (as if the X and Y values are switched). The Tangent command draws a line tangent to the expression, with the line touching the expression at the X value. Use the Input or Pause command to view the graph (or tangent line).

Format
:DrawF expression
:DrawInv expression
:Tangent(expression,value)

The expression can either be a function variable (Y0 through Y9) or a function in terms of X (such as 3X+4). While you create a function variable by storing an expression (enclosed in quotes) to it, the function in terms of X is just the expression itself (which allows you to bypass the function variable). The expression can consist of numbers, variables, and math functions.

Format
:"expression"→Y#
:expression

After the function variable is created, it is stored in the Y= editor and selected to be graphed. If you already have an expression stored in a function variable, you can combine function variables with other expressions to create new expressions. You cannot use a list in the expression to draw several graphs at one time.

When graphing functions, you have to adjust the graph formats and window dimensions to ensure the functions display correctly on the screen. Although you can have successive graphs (graphs displayed on top of each other), this is sometimes unwanted because it interrupts the graphscreen while you're graphing your functions. You can get rid of this problem by using the FnOff command.

To use the graph commands, you should first be in the Program editor for your program. In the Program editor, press 2nd and PRGM, then scroll down to whichever command you want and press ENTER. Now the command has been put into your program. You then have to type the expression you want to graph. The function variables can be found by pressing VARS, pressing > once to get to the Y-Vars menu, and then scrolling down to Functions.

Displaying Text on the Graphscreen

The Text command displays text, numbers, variables, or expressions wherever you want on the graphscreen. Because the Text command utilizes the small font (available only on the graphscreen), more text can be displayed on the screen. The Text command overwrites any existing text on the screen, and it is also not affected by the graphscreen window settings.

When you use the Text command, you need to specify the starting coordinates of what you want to display. You first specify the row (0 to 57 from top to bottom) and then the column (0 to 91 from left to right). Although the graphscreen is actually 94 rows by 62 columns, you will get an error if you try to display text on a higher row or column.

The reason is that the graphscreen text is five pixels tall and a variable width. While numbers, uppercase letters, and most lowercase letters are three pixels wide, some lowercase letters (such as w and m) are five pixels wide, and spaces are one pixel wide. There is an automatic space (one pixel wide) inserted between text. So, you need to factor in the height and width of the characters when positioning them on the screen.

Format
:Text(row,col,argument)

A good way to find where exactly you want to place the text or other drawing is to use a blank Input command. This gives you a cursor to find where to put it. Just remember that the coordinates at the bottom of the screen are not what you put into the Text( command.

Format
:Input

The Text command can display multiple arguments of both text and variables on the same line, at the same time. This is very useful because it eliminates the need to have to worry about spacing. If the variable changes, the Text command will adjust it on the screen accordingly. This allows you to sometimes remove multiple Text commands and just use the first one to display everything.

:Text(5,5,A
:Text(5,9,"/
:Text(5,13,B
Combine Text Commands
:Text(5,5,A,"/",B

On the TI-83+/SE calculators, the Text command can also display the large font that is available on the homescreen. Just put a negative one (-1) before the row and column arguments. When using the large font, you have to keep formatting in mind because it is very easy for the text to go off the screen. This is useful when you want to clear large portions of the graphscreen at a time.

Format
:Text(-1,row,col,argument)

If you have a string of numbers that you are displaying, you don't need to put quotes around the numbers. You may want to keep the numbers in a string, though, if they have any leading zeros. Because the numbers are no longer in a string, the leading zeros will be truncated (taken off) and not be shown.

:Text(2,2,"2345
Remove the Quotes
:Text(2,2,2345

To use the Text command, you should first be in the Program editor for your program. In the Program editor, press 2nd and PRGM. Then, scroll down (all the way at the bottom) to Text and press ENTER. Now the Text command has been put into your program. You can then begin typing some text by turning on the alpha-lock with pressing 2nd and ALPHA.

Drawing & Shading on the Graphscreen

Drawing on the graphscreen is one of the main uses of the graphscreen. There are several different things that you can draw, including points, pixels, lines, and circles. Besides drawing, you can also shade in an area on the graphscreen with whatever size and look you want.

Drawing Points

The point commands are used to draw points on the graphscreen. A point is just a pixel on the screen. The point commands use the (x,y) coordinate system, which is affected by the window settings. This means you have to change the window settings accordingly when you use the point commands, otherwise the points won't show up correctly.

The Pt-On command turns on the point at the given (x,y) coordinates. The Pt-Off command turns off the point at the given (x,y) coordinates. The Pt-Change command toggles the point at the given (x,y) coordinates. If the point is on, it will be turned off and vice versa.

Format
:Pt-On(x,y)
:Pt-Off(x,y)
:Pt-Change(x,y)

The Pt-On and Pt-Off commands also have an optional mark argument that determines the shape of the point. The mark can be either one (dot), two (3x3 box), or three (3x3 cross). You don't need to specify the mark when using the first mark because it is the default. Remember to use the same mark when turning a point off as you used to turn it on.

:Pt-On(5,5,1
Remove Mark
:Pt-On(5,5

To use the point commands, you should first be in the Program editor for your program. In the Program editor, press 2nd and PRGM, then press right once and scroll down to whichever command you want and press ENTER. Now the command has been put into your program. You then have to type the numbers for where you want the point to appear on the screen.

Drawing Pixels

The pixel commands are the alternative way to draw pixels on the graphscreen. Although they are easier to use because they are not affected by the window settings (which means you don't have to set the window dimensions when using them), the coordinate system is switched around so that the row comes first and then the column — it's (y,x) instead of (x,y).

The Pxl-On command turns on the pixel at the given (y,x) coordinates. The Pxl-Off command turns off the pixel at the given (y,x) coordinates. The Pxl-Change command toggles the pixel at the given (y,x) coordinates. If the pixel is on, it will be turned off and vice versa. The pixel commands are faster than their equivalent point commands, so they should generally be used instead whenever possible.

Format
:Pxl-On(y,x)
:Pxl-Off(y,x)
:Pxl-Change(y,x)

Besides these three commands that have point equivalents, there is also a Pxl-Test command. The Pxl-Test command checks whether the pixel at the given (y,x) coordinates is on or off. One is returned if the pixel is on and zero is returned if the pixel is off. You can store the result to a variable for later use, or use the command in a conditional or loop.

Format
:Pxl-Test(y,x)

To use the pixel commands, you should first be in the Program editor for your program. In the Program editor, press 2nd and PRGM, then press right once and scroll down to whichever command you want and press ENTER. Now the command has been put into your program. You then have to type the numbers for where you want the pixel to appear on the screen.

Drawing Lines

The Line comand allows you to draw a line anywhere on the screen. The line can be any length that you want. When using the Line command you need to supply the coordinates of the two endpoints. The Line command draws the line from the first endpoint (x1,y1) to the second endpoint (x2,y2).

Format
:Line(x1,y1,x2,y2)

The Line command has an optional fifth argument that controls whether the line will be drawn (the argument should be one) or erased (the argument should be zero). The line is drawn by default, so it should be left off unless you want to erase it.

:Line(5,5,10,5,1
Remove Line's Fifth Argument
:Line(5,5,10,5

When you have multiple pixels in a straight line that you turn on or off, you can sometimes replace the pixel commands with one or more Line commands. In the case that the pixels are arranged at a slant or angle, you can just adjust the line coordinates accordingly. You should also use Line commands instead of pixel commands when clearing large portions of the graphscreen at a time.

:Pxl-On(5,5
:Pxl-On(5,6
:Pxl-On(5,7
Replace with Lines
:Line(5,5,5,7

There are two other line commands that are also available. They are primarily designed for when you want to quickly draw a line across the entire screen. The Horizontal command draws a horizontal line at a given row and the Vertical command draws a vertical line at a given column. The argument can either be a number or a variable.

Format
:Horizontal y
:Vertical x

To use the line commands, you should first be in the Program editor for your program. In the Program editor, press 2nd and PRGM, then scroll down to whichever command you want and press ENTER. Now the command has been put into your program. You then have to type the number(s) for where you want the line to appear on the screen.

Drawing Circles

The Circle command draws a circle on the graphscreen. When using the Circle command, you must enter three numbers (separated by commas): the (x,y) coordinates of the center of the circle and the length of the radius. Because circles take a long time to draw, you should use them sparingly.

Format
:Circle(x,y,radius)

The window settings affect how the circles are drawn. With the screen height being larger than the width (the screen is a rectangle), the circles will actually look like ellipses. To make them look like circles, you need to use the ZSquare command.

To use the Circle command, you should first be in the Program editor for your program. In the Program editor, press 2nd and PRGM, then scroll down to Circle and press ENTER. Now the Circle command has been put into your program. You then have to type the numbers for where you want the center of the circle to be and the length of the radius.

Shading Areas

The Shade command shades in an area on the graphscreen. For basic shading, you just need to specify a lower function and upper function. The Shade command will vertically shade in the area that is above the lower function and below the upper function across the whole length of the screen. The functions can either be a function variable (Y0 through Y9); or a function in terms of X, consisting of numbers, variables, and math functions (such as 3X+4).

Format
:Shade(lowerfunction,upperfunction)

When shading with the function variables, the window settings affect how the shading looks. You should set the window variables to ensure that the shading is done correctly. This also applies when you are shading at the same time as drawing, because some of the drawing commands are affected by the window settings.

Because you might not want to shade the whole length of the screen, the Shade command has two optional arguments that allow you to specify the left and right boundaries for shading (the boundaries themselves are also shaded). Xleft and Xright can be whatever numbers you want, as long as they are between Xmin and Xmax (the horizontal window dimensions). You can also just specify Xleft by itself if you only want to change the left boundary (you need to set Xleft to set Xright, though).

Format
:Shade(lowerfunction,upperfunction,Xleft,Xright)

The Shade command has two other optional arguments that allow you to change the look of the shading, but you need to also set the left and right boundaries to use them. The pattern can be either one (vertical), two (horizontal), three (slanted backwards), or four (slanted forwards); and the patres (the frequency of the shading) can be from one to eight pixels.

Format
:Shade(lowerfunction,upperfunction,Xleft,Xright,pattern,patres)

To use the Shade command, you should first be in the Program editor for your program. In the Program editor, press 2nd and PRGM, then scroll down to the command (or press the 7 key) and press ENTER. Now the command has been put into your program. You then have to specify the functions (and boundaries, pattern, and patres) for how you want to shade the area.

Storing the Graphscreen to a Picture

After you have spent lots of time drawing something on the graphscreen, you naturally want to keep it for future use. So, you store it to a picture variable. A picture variable holds a copy of the graphscreen at the respective time it was stored to. Although pictures are often used, it really is a personal preference.

The StorePic command saves the current graphscreen to the designated picture. After saving a picture, you can display it again with the RecallPic command. Before recalling a picture, you should first make sure that the graphscreen is clear. This ensures that the picture won't be interrupted by anything that is already on the screen. You can only use numbers with the StorePic and RecallPic commands; no variables.

Format
:StorePic #
:RecallPic #

Because each picture takes up 768 bytes, you should delete them when exiting programs. The program should only keep the picture if it is used for something important (such as a titlescreen). The user doesn't want to have their memory cluttered up with lots of variables.

To use the picture commands, you should first be in the Program editor for your program. In the Program editor, press 2nd DRAW and < once. Then scroll down to StorePic or RecallPic and press ENTER. Finally, press the number of the picture you want to use.

Advantages & Disadvantages of Pictures

The main advantage of using pictures is that the graphics show up almost instantly compared to the slow speed of drawing them. This is particularly noticeable the more detailed the graphics are and depending on what graphics (primarily circles) are being drawn. Speed is a top priority in most programs (because the user doesn't want to wait), so pictures are usually used.

The main disadvantage of using pictures is that there are only ten pictures (from Pic0 to Pic9). With every program sharing the pictures, there can be conflict when two programs use the same picture (the picture will usually be overwritten by the other program).

Another disadvantage of using pictures is that it is another file that the user needs in order to use your program. If you give someone your program, you will have to also give them your pictures. Your program won't work properly anymore if somebody deletes your pictures or forgets to include them with your program. Although this is mostly out of your hands, users will think your program is at fault.

Pictures have a weird behavior, that can be a curse or blessing. When recalled, they only turn on pixels — not turn them off. Try recalling one picture, then recalling a different picture. You'll notice they overlap. This has an application anytime that you are displaying something (sprite) on top of a background. Draw the sprite on the screen, and use a pic for the background.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/graphscreen


Math Functions

Calculators are built with one primary purpose: math. Programming, game playing, and everything else is secondary. Thus, you will find a number of powerful math commands. Although it may seem that they are of no use to a programmer, programs sometimes need math functions, and many math functions can be used in clever ways. In this guide we'll group the commands into the following general groups:

Number Operations

These commands deal with different ways you can manipulate the integer and fraction parts of a number, and are mostly found in the MATH-NUM menu.

Probability and Combinatorics

These commands are generally found in the MATH-PRB menu (except for randM(, which is in the MATRIX-MATH menu). They include commands for generating random numbers, and commands that are useful for solving problems in combinatorics and probability theory.

Calculus

Although the TI-83 series calculators don't, by themselves, have the capability for symbolic calculations, these commands (found in the main MATH menu) can provide numerical approximations for some commonly computed quantities in calculus.

  • fMin(, fMax( — numerical function optimization in one variable.
  • nDeriv(, fnInt( — derivatives and integrals.
  • solve( — numerical solution of an equation in one variable.

Trigonometry

These commands allow you to manipulate angles, and are generally affected by Radian mode and Degree mode (so you should check those pages out). Some of these commands live in the 2nd ANGLE menu, some are on the keyboard, and some can only be found in the 2nd CATALOG menu:

Complex Number Operations

These commands are used for dealing with complex numbers, and are found in the MATH-CPX menu. Many other math commands work on complex numbers too, and complex numbers are fairly strongly connected to trigonometry.

Operators

These commands are found on the keyboard and in the 2nd TEST menu, and deal with basic mathematical and logical commands.

Powers, Inverses, Exponentials, and Logarithms

These commands are found all over the place, many on the keyboard itself, and deal with raising some value to a power, or raising a number to some value, or the inverses of those operations.

Miscellaneous

These commands have nothing to do with each other, but don't really belong to other categories either.

  • π, e — famous (and occasionally, even useful) math constants.
  • min(, max( — returns the smaller number(s) or the larger number(s).
  • lcm(, gcd( — returns the least common multiple or the greatest common denominator of two numbers.

Comments

Note that the statistics commands are not included here. That is because statistics is not math. There is also the finance commands and variables, which are another topic unto themselves.

In addition, all of the above commands, except for the calculus and random number generating commands, can be applied to lists as well. For single-argument commands, this just means that the command is applied to each element of the list separately.

For multiple-argument commands, there are two ways to do it: with a number and a list (then, the command is applied with that number to each element of a list), and with two lists (then, it's done pairwise, and the lists must be the same size, otherwise the calculator will throw a ERR:DIM MISMATCH error).

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/math


Variable Types

Variables are used extensively in programming, as most programs use variables in one form or another. They are used to keep track of numbers or text or stats; there are many uses for variables. Put simply, programming wouldn't be programming without variables. Imagine variables being little boxes which you can store almost anything in.

A variable is a reference to the information that it holds. Variables allow you to store the information, so that you can later use it for whatever purpose is desired. The thing to remember, though, is that programs all share the variables.

There are several different kinds of variables available on the calculator, but the four main variables that you will be using are number variables, lists, matrices, and strings. Number variables are used for storing a single number. Lists are used for storing a collection of numbers. Matrices are used for storing numbers in a two-dimensional format. And, strings are used for storing text.

Storing & Deleting Variables

Variables have values stored in them so that the values can be recalled for later use. When storing an expression containing a variable into another variable, the value of the variable at that time is used. The store (→) command is used for storing variables, and it is accessed by pressing the [STO►] key. When storing a value in a variable, you have the value on the left side of the store command and the variable that it will be stored to on the right side.

Format:

value→variable

Examples:

123→A
123+456→A
"Hello"→Str0

When you are done using variables, you should delete them with the DelVar command to save space. The DelVar command deletes the contents of a variable from memory. If the DelVar command is used with a real variable, the variable is not only deleted from memory but automatically set to zero the next time it is used. DelVar does not work on specific elements of a list or matrix. In fact, it will actually return an error.

Format:

DelVar variable

Examples:

DelVar A
DelVar B
DelVar Str0
DelVar L₁

Numeric variables

Numeric variables are used for storing numbers. There are 27 numeric variables (from A to Z and θ) that can be easily accessed, and more that the calculator uses for its specific purposes.

Examples:

1→A
2+3→B
(A+B)/(6+7→C

Tip: You don't need to close brackets before using the STO command. The calculator will automatically close any open brackets and string quotes as soon as it comes across a STO command.

Most numeric variables can either be real or complex (the latter involve i, the square root of -1, and are important to advanced algebra). In either case, up to 14 digits of a number can be stored, although only the first 10 will be displayed and used for comparison.

To access a real variable, press ALPHA and then the key corresponding to whatever letter you want your variable to be. You can initialize a real variable by storing a number, another variable, or an expression into the variable using the STO key (or, just using it almost anywhere will initialize it to 0).

Flag Variables

Flag Variables are a numeric variable that is used for the specific purpose of controlling program flow. They typically only contain the value 1 or 0 and are sometimes described as being binary, or Boolean variables.

(for more information, see Using Variables as Flags)

List Variables

Lists are used to hold multiple numbers at once, in a specific order. There are six "default" lists named L1 through L6, but an important feature of lists is that they can be given names, so that there are millions of possible lists. Lists are important for programmers for many purposes - saving data after a program finishes running, and storing a level of a game are only two of them.

Examples:

{1,2,3}→L₁
L₁+10→L₂
{4,5,6}→⌊X
{7,8,9}→⌊DATA

There are 6 built-in list variables available: L₁, L₂, L₃, L₄, L₅, L₆. Beyond that, you can create custom list names using one to five characters, comprised of any combination of capital letters and numbers and theta, but it must begin with a letter or theta.

(for more information, see Lists and Their Commands)

Matrix Variables

Matrices are two-dimensional lists (row by column). Equivalent to lists, they are used when the data needs more structure. Matrices are often used for storing a level or a map of the screen. There are only ten matrices available (from [A] to [J]).

(for more information, see Matrices and Their Commands)

String Variables

Strings are used for storing a sequence of characters, that is, text. A common use for strings is to manipulate text to be displayed in a program, but they have many different purposes: highscores, level and map data, and whatever else is desired.

"Hello"→Str0
"World"→Str1
Str0+" "+Str1→Str2

Using the "+" sign will concatenate strings together, so the last line above will put "Hello World" into Str2.

Although there are only ten built-in string variables (Str0 through Str9) available to use, strings can hold many different kinds of characters, including letters (both uppercase and lowercase), numbers, functions, and even other commands. The amount of free RAM is the only limit on the number of characters in a string.

Tip: You don't need to close the quotes before using the STO command. The calculator will automatically close any string quotes as soon as it comes across a STO command.

(for more information, see Strings and Their Commands)

Picture Variables and GDBs

Picture variables and GDBs (short for Graph DataBase) are used to save two different elements of the current graph display. A picture variable is used to store the exact appearance of the graph screen. A GDB is used to store system variables relevant to the graph screen - equations, window settings, and the like. 10 built-in variables of each type exist: Pic0 through Pic9 for pictures and GDB0 through GDB9 for GDBs.

(for more information, see Pictures and GDBs)

System Variables

System variables are, for the purposes of this guide, variables that certain commands will use or modify without asking (i.e. without supplying them in the command's arguments). This is a somewhat ill-defined category, and in fact the system variables we'll discuss are of a somewhat miscellaneous nature. They include equation and plot variables, window and table parameters, statistical variables, and finance variables.

(for more information, see System Variables)

Converting Between Variable Types

Between lists and matrices

The List►matr( and Matr►list( commands are used to convert between a matrix and several lists. Using these commands, it should be simple to implement any kind of conversion between these two data types.

Between strings and numbers

It is very easy to convert a string version of an expression to a number, list, or matrix: the expr( command can do it — for example, expr("5") will give you the number 5, and expr("{1,2,3}") will give you the list {1 2 3}.

Going the other way, however, is slightly more complicated because there is no built-in command to do it. What you need to use instead are a few small routines: see number to string for how to convert a number to a string. To convert a list or matrix, convert each individual element instead.

Archiving and Unarchiving Variables

On the TI-83+/84+/SE calculators, you can archive and unarchive variables. What this entails is the calculator moving the variable to the archive memory or the calculator moving the variable to RAM respectively. The main advantage of archiving a variable is that it is protected from calculator crashes, which clear the calculator's RAM. At the same time, you can't access a variable that's archived; it needs to be in RAM to use it.

:Archive L1
:UnArchive Str1

There are a couple things you need to be aware of when using Archive and UnArchive. First, since the TI-83 only has RAM, archiving is not possible, and subsequently neither of these commands are available. This means that you shouldn't use either of these commands if you plan on porting a program to the TI-83. Second, archiving does not work with the majority of the system variables, including the graphing, statistical, and finance variables. You can archive the other types of variables, however, although list variables are actually more manageable using the SetUpEditor command.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/variables


Getting Input from the User

Getting user input is a basic part of almost all programs. It provides a way of changing variables or transferring control to the user. The four commands used for getting input are: Prompt/Input, getKey, and GetCalc.

User input includes getting values for variables on the calculator, getting the keys that the user pressed, and getting a variable off of or sending a variable to another calculator over a link cable.

Getting Input

You can get input in three ways: Input, Prompt, and a graph-screen method. There are certain advantages and disadvantages to each command, and there are also certain situations where each command should be used. The first two are commands on the I/O menu of the prgm button (only while editing a program). The third has no single command. It has to be done manually. Below explains the third method a bit better.

Let us focus on the first two. Prompt and Input can be used with any variable, but some of the variables have to be entered in a certain way. If the variable is a string and you are using the Prompt command, the user must put quotes ("") around the value. However, both Prompt and Input require the user must also put curly braces ({}) around lists and square brackets ([]) around matrices.

Getting Input with Prompt

The Prompt command is the simplest way of getting user input. The Prompt command asks the user to enter a value for a variable, waiting until the user enters a value and then presses ENTER. When using Prompt, the variable that is being asked for will be displayed on the screen with an equal sign and question mark (=?) after it.

:Prompt variable

Because displaying what variable the value will be stored to does not tell the user what the variable will be used for, you can put a Disp command before the Prompt command to give the user some more insight into what an appropriate value for the variable would be. The Prompt command will be displayed one line lower, though, because the Disp command automatically creates a new line.

:Disp "Text"
:Prompt X
SCREEN01.BMP

When you have a list of Prompt commands (and each one has its own variable), you can just use the first Prompt command and combine the rest of the other Prompt commands with it. You remove the Prompt commands and combine the arguments, separating each argument with a comma. The arguments can be composed of whatever combination of variables is desired.

The advantages of combining Prompt commands are that it makes scrolling through code faster, and it is more compact (i.e. smaller) and easier to write than using the individual Prompt commands. The primary disadvantage is that it is easier to accidentally erase a Prompt command with multiple arguments. So, instead of:

:Prompt A
:Prompt Str1

Combine the Prompts and get:
:Prompt A,Str1

To use the Prompt command, you should first be in the Program editor for your program. In the Program editor, press the PRGM button, then arrow over to the I/O menu. Then, scroll down to Prompt and press ENTER. Now the Prompt command has been put into your program. You then have to type what variable(s) you want to prompt the user for (separating each one with a comma).

Final note: since the real-world applications take strings (like a username or a command) quite a bit, no-one uses Prompt because it forces the user to use quotation marks. A programmer would know to use it at the =?, but the casual user won't. 99.9% of the time, you see Input, which is discussed next.

Getting Input with Input

The other way to get input is to use the Input command. The Input command asks the user to enter a value for a variable (only one variable can be input at a time), waiting for the user to enter a value and press ENTER. The Input command, by default, does not display what variable the user is being asked for, but instead just displays a question mark.

:Input variable

Because just displaying a question mark on the screen does not really tell the user what to enter for input or what the input will be used for, the Input command has an optional text message that can be either text or a string variable that will be displayed alongside the input.

Only the first sixteen characters of the text message will be shown on the screen (because of the screen dimensions), so the text message should be kept as short as possible (a good goal is twelve characters or less). Don't worry about the user not having enough room, their input does word-wrapping.

:Input "Text",variable
:Input Str#,variable

If the text message is longer than twelve characters or you want to give the user plenty of space to enter a value, you can put a Disp command before the Input command. You break the text message up and display it in parts. The Input command will be displayed one line lower, though, because the Disp command automatically creates a new line.

:Disp "Text"
:Input "Text",variable

When you are just using the text message to tell the user what the variable being stored to is, the Prompt command makes it a byte easier. And, if there is a list of Input commands following the same pattern, you can reduce them to just one Prompt command.

:Input "A",A
:Input "B",B

Replace with Prompt and get:
:Prompt A,B

The Input command can also be used another way. When you just put the Input command by itself, the graph screen will be shown and the user can move the cursor around. When the user presses ENTER, the (x,y) coordinates of the cursor will be stored to the X and Y variables, respectively.

:Input

To use the Input command, you should first be in the Program editor for your program. In the Program editor, press the PRGM button, then arrow over to the I/O menu. Then, scroll down to Input and press ENTER. Now the Input command has been put into your program. You then have to type the text message and the variable that you want to ask the user for.

Graph Screen Method

This method has no automatic command. This must be done manually and, as you can imagine, takes a lot of space. If you value speed over design, then don't bother. Otherwise, this guide will show you how to do it.

Reading Keypresses

getkey.png

The getKey command is widely used in many programs because it allows the program to directly access user input. The getKey command returns the number of the last key pressed, and resets to 0 every time it is executed.

Every key has a number assigned to it, except for ON (which is used for breaking out of programs). The numbering system consists of two parts: the row and column. The rows go from one to ten, starting at the top; and the columns go from one to six, starting from the left. You just put the row and column together to find the key's number. The only confusing parts for beginners are the arrow key numbers.

When the getKey command is used, it's value automatically resets to 0, so the next time it is used, it no longer returns the last pressed key. Because of this, the getKey command is usually stored to a variable. Storing getKey to a variable allows the program to keep track of which key was pressed, taking different actions depending on what the key was. This opens up a variety of possibilities for the programmer. For example, using getKey inside a loop allows the program to wait for a keypress and store it:

:Repeat Ans
:getKey
:End
:Ans→K

You can also put getKey in the condition of a loop, to make the loop repeat until any key or a particular key is pressed by the user. The same thing can be done with conditionals as well. This is useful if you don't want to store getKey to a variable, but you still want to have the user press a key. It's perfect for a "PRESS ANY KEY TO CONTINUE" screen.

:Repeat getKey
:End

Note that you can get a keypress at any time by directly assigning to a variable, like so:

:getKey→K
:If K=45
:Output(1,1,"Do Something")

To use the getKey command, you should first be in the Program editor for your program. In the Program editor, press the PRGM button, then arrow over to the I/O menu. Then, scroll down to getKey and press ENTER. Now the getKey command has been put into your program.

Final Notes

Once you mastered this, you've mastered half of all programming. Literally. The other half is output. That's all a program is. A program gets user input and gets results, which are usually shown to you. Good luck to the rest of your TI-Basic venture

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/userinput


Operators

Just like other programming languages, TI-Basic has the standard set of core operators built-in (math, relational, and logical), although they each have their own syntax and rules.

Math Operators

There are five math operators: +, -, *, /, and ^. Anybody who has ever done even basic math should know and recognize at least the first four operators, but for those who don't, their meaning is pretty straightforward:

+
Adds two numbers together
-
Subtracts one number from another
*
Multiplies two numbers together
/
Divides one number by another
^
Raises a number to a power

There are two similar negative symbols on the TI-83 calculators — the subtraction symbol (the - key) and the negation symbol (the (-) key). These aren't interchangeable. However, it's almost always clear from an expression which one is being used, so the - symbol will be used to represent both throughout most of this guide.

Relational Operators

There are six relational operators: =, , >, , <, and . Just like with the math operators, these operators are used in almost every math class, and thus most people should know them.

=
X=Y is true if X is equal to Y
X≠Y is true if X is not equal to Y
>
X>Y is true if X is greater than Y
X≥Y is true if X is greater than or equal to Y
<
X<Y is true if X is less than Y
X≤Y is true if X is less than or equal to Y

Because the calculator does not have a separate time for logical values (true and false), they are represented by the numbers 1 and 0. This becomes important when dealing with piecewise expressions.

Logical Operators

There are four logical operators: and, or, not(, and xor. Their interpretations are mostly intuitive when thinking about the meaning of the English word:

and
X and Y is true if both X and Y are true
or
X or Y is true if at least one of X and Y is true
xor
X xor Y is true if only one of X and Y is true
not(
not(X) is true if X is false

Again, as with the relational operators, 1 is used to for 'true', and 0 is used for 'false'. It so happens that the logical operators treat all nonzero values as though they were 1 (true), so the expression '2 and 3' will be true just as '1 and 1'.

Here is a truth table of the various values:

A B A and B A or B A xor B not(A)
0 0 0 0 0 1
0 1 0 1 1 1
1 0 0 1 1 0
1 1 1 1 0 0

Order of Operations

The TI-83 series of calculators has nine priority levels for evaluating expressions. All the functions on a priority level will be calculated from left to right before moving on to the next priority level. Of course, calculations within parentheses are done first. Here is a table of the priority levels:

Priority Level Functions
1 Functions that precede their argument (such as √( or sin(), except for negation
2 Functions that follow their argument (such as 2 or !)
3 ^ and ×√
3.5 Negation
4 nPr and nCr
5 Multiplication, division, and implied multiplication
6 Addition and subtraction
7 The relational operators =, , <, >, ,
8 The logic operator and
9 The logic operators or and xor
10 Conversions such as ►Frac

TI refers to the routine that determines order of operations as the Equation Operating System (EOSTM). Unfortunately, this cool name hasn't become common usage.

Test your knowledge

Here are some sample problems on logical operators, in order of complexity. For the more difficult ones, it may be best to break them up into smaller parts and work in steps.

# Question
1 0 and 1 or 1
2 0 and (1 or 1)
3 4 and -4 xor (.6 and 0)
4 not(1) xor (1 and 1 xor 1)
5 1 and 0 xor (6*4 and 0) or not(0 and 6)
6 1 and (1 xor not(5 xor 1 and 0)) xor not(1 xor not(1 or not(1)))

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/operators


Calculator Linking

One of the most important features of the TI graphing calculators is their linking, where they communicate with another TI calculator or a computer across a link cable that is connected between them. There are a few different link cables that TI has created, and they each have their own advantages and disadvantages:

  • Graph Link — This is the classic link cable that has been around since the TI-83 was first released. It works with every calculator before the TI-84+CE, and it comes in black (for the PCs) or gray (for the Macs). It works with the Graph Link software, which doesn't work very well with the newer calculators. The TI-84+CE no longer has an I/O port so this cable cannot be used to transfer data.
  • USB Link — This is the new link cable that is designed to be much faster, since it uses the USB port of a computer rather than the COMM port that Graph Link uses. Besides the port, it also only works with the TI Connect software instead of the Graph Link software.
  • Mini USB Link — This is only available on the newer TI-84+/SE calculators, since it actually uses the second smaller USB port on the TI-84+/SE calculator instead of the usual I/O port. It works pretty much the same way the USB Link does, and in fact uses the same TI Connect software.

In addition to the official link cables, you can also make your own using parts of other cables. Putting together a link cable is a rather delicate operation, and requires a considerable amount of knowledge of electronics and linking. This isn't recommended unless you know what you are doing — if you screw up, you can really mess up your calculator!

Calculator to Calculator

There are two commands that you can use when linking one calculator to another: GetCalc(, and Get(. The GetCalc( command was designed such that you can receive a variable from another calculator; unfortunately there are very specific requirements for the sending calculator to actually send the variable (it must be in a preemptible state like Pause or Menu(, and cannot be executing an assembly program). Whilst this can seem a difficult task to actually create a fully functional and fun multiplayer game, the multiplayer page shows workarounds to make such a program achievable — the key to which is fully understanding the nature of GetCalc(.

The Get( and Send( commands were created for use with the CBL (Calculator-Based Laboratory) and CBR (Calculator-Based Ranger) devices in math and science classes. These devices collect real-time data from various sensors that you can connect to them, and allow you to view and analyse the results. At the same time, they were originally used by the TI-82 calculator for receiving and sending variables respectively between calculators, and actually still operate in that capacity.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/linking


Controlling Program Flow

Controlling flow defines the order in which a program runs, what line of code will be executed next; to repeat or skip a group of commands. There are three main parts of controlling flow: conditionals, loops, and branching. Each of these parts is used in different situations and to serve different functions. Together they are an integral part of all programs.

When dealing with conditionals and loops, the decision whether the conditional or loop will be executed is based on Boolean Logic — the principle that something can only be true or false at any given time. While any nonzero value is evaluated to true (i.e. it will be executed), a zero value is evaluated to false (i.e. it will be skipped over, not executed).

Conditionals

Conditionals are used to make decisions in programs. The program can carry out different actions, depending on if certain conditions occur — directing the flow of program execution. Conditionals determine if code will be executed or not.

There are three different types of conditionals: If, If-Then, and If-Then-Else. There are certain advantages and disadvantages to each conditional, and there are also certain situations where each conditional should be used.

If Conditional

The first, and simplest, type of conditional is the If. It is used when you only want to execute one command. The If conditional needs the If command to work. The command that is immediately following the If conditional will be executed if the condition is true, but it won't be executed if the condition is false.

Format
:If condition
:Command

Because If conditionals are generally slow, you should replace them with Boolean conditionals when you are just changing a variable. You take the condition that is in the conditional, put parentheses around it, and multiply it by the value that you are changing the variable (the value should be left off when it is one since it is unnecessary).

:If X=3
:Y+2→Y
Use Boolean Conditional
:Y+2(X=3→Y

The reason that this works is the condition will evaluate to one if it is true and zero if it is false. Since this value is then multiplied by the value that you are changing the variable, the changing value will stay the same if the value is one but it will become zero if the value is zero. So, the Boolean conditional is faster than an If conditional when the condition is true, but it will be slower when the condition is false because zero is still stored to the variable.

Boolean conditionals also have another advantage over If conditionals. When you have several Boolean conditionals that deal with the same variable, you can combine them into one Boolean conditional. Boolean conditionals can have multiple conditions that change the variable by different values. If you change the variable by the same value in two or more conditions, you can factor the value out by multiplication. This works best with large values.

:A+5(K=26→A
:A-5(K=24→A
Combine Conditionals
:A+5((K=26)-(K=24→A

If-Then Conditional

The second type of conditional is the If-Then. It is used when you want to execute more than one command. Besides the If command, the If-Then conditional needs the Then and End commands to work. The Then command tells the calculator that there are multiple commands in the conditional to execute, while the End command signifies the end of the command block.

Format
:If condition
:Then
:Command(s)
:End

The commands immediately following the Then will be executed if the condition is true, but the commands won't be executed if the condition is false. Instead, program execution will continue after the End. Because If-then conditionals are twice as fast as If conditionals (they are larger, though, because of the added commands needed to use them), you might want to replace an If conditional with an If-Then conditional when speed is the top priority.

:If A=1
:Disp "Hello
Replace With If-Then Conditional
:If A=1:Then
:Disp "Hello
:End

With the If-Then and If-Then-Else conditionals, you can put conditionals inside of each other (known as nesting). You can also put loops inside conditionals. When you have two or more If conditionals that have a common condition (i.e. a compound condition made using the logic operators), you should take the common condition out, make it into an If-Then conditional, and nest the If conditionals inside it.

:If A=1 and B=1
:C+2→C
:If A=1 and B=2
:D+1→D
Take Out Common Condition
:If A=1:Then
:C+2(B=1→C
:D+(B=2→D
:End

This will speed up the program execution when the If-Then conditional is false. Instead of testing each If conditional and its conditions, the If-Then conditional (and the nested If conditionals) will be skipped over if the first condition is false. Remember to put the closing End command for the If-Then conditional, otherwise you will get an error.

If-Then-Else Conditional

The third, and last, type of conditional is the If-Then-Else. It is used when you want to execute one or more commands if a condition is true and one or more other commands if the condition is false. This is equivalent to two separate If-Then conditionals with opposite conditions, but it is faster because there is only one condition test (since only one of the conditions can be true at one time). Besides the If command, the If-Then-Else conditional needs the Then, Else, and End commands to work.

Format
:If condition
:Then
:Command(s)
:Else
:Command(s)
:End

The commands between the Then and Else will be executed if the condition is true, while the commands between the Else and End will be executed if the condition is false. This is an important part of If-Then-Else conditionals because it determines what order you put the commands, whether they should go in the true or false part of the conditional.

When using an If-Then-Else conditional and only one command is executed if the condition is true or false, you can replace the If-Then-Else conditional with a simple If conditional. You switch the order of the commands so the false command comes first (because that command will be executed by default), and place the If conditional between the two commands. This primarily works when the commands are store commands, but it also can be used when you are building a string of text that you display.

:If B:Then
:"Hello→Str1
:Else
:"Goodbye→Str1
:End
Replace with If conditional
:"Goodbye→Str1
:If B
:"Hello→Str1

To put the conditional commands in your program, you need to first be in the Program editor. You press PRGM and then scroll over to EDIT. Once in your program, you press PRGM again and scroll over to CTL. The If, Then, and Else commands are in the first three spots (respectively), while the End command is in the seventh spot. You press ENTER to put the commands in your program.

Operators

Operators are used if you want to make compound conditions that are true depending on two or more conditions. When using operators, the left side is being compared to the right side. The operators can be used with any of the three different types of conditionals, as well as the Repeat and While loops.

There are two kinds of operators: conditional and logic. The six different conditional operators are: =, ≠, >, <, ≥, and ≤. The four different logic operators are: and, or, xor, and not. Conditional operators can be used (joined) with logic operators.

The =, ≠, >, <, ≥, and ≤ operators all compare and test two conditions. = returns true if the conditions are equal. ≠ returns true if the conditions are not equal. > returns true if the first condition is greater than the second condition. < returns true if the first condition is less than the second condition. ≥ returns true if the first condition is greater than or equal to the second condition. ≤ returns true if the first condition is less than or equal to the second condition.

Format
:If condition = condition
:If condition ≠ condition
:If condition > condition
:If condition < condition
:If condition ≥ condition
:If condition ≤ condition

The one instance where you don't need the ≠ conditional operator is when comparing a variable to zero. Because every nonzero value is treated as true, you don't need to compare if the variable's value is nonzero since any value will work. Instead, you can just put the variable by itself.

:If C≠0
Remove ≠ Operator
:If C

There is a simple truth table that is used to show how the logic operators work. The truth table is based on Boolean Logic, the principle that a condition can only be true or false. A true value is represented by one or any nonzero number. A false value is represented by zero. A and B are just conditions.

A B and or xor not(A)
1 1 1 1 0 0
0 1 0 1 1 1
1 0 0 1 1
0 0 0 0 0

The and, or, and xor operators compare and test two conditions, while the not operator only tests one. and returns true if both conditions are true. or returns true if one or both conditions are true. xor returns true if either condition is true (but not both). not returns true if the condition is false.

Format
:If condition and condition
:If condition or condition
:If condition xor condition
:If not(condition)

One way that the not operator can be used is for switching something from true to false or on to off, and vice versa. When dealing with a variable, not inverts the variable's value; so you should use not instead of comparing a variable to zero because not returns true when the variable is zero. At the same time, don't try to use not in every condition because there are many ways of writing a condition.

:If A=0
Use not Operator
:If not(A

The not operator is also used when applying DeMorgan's Law. DeMorgan's Law can be used for conditions in which there is an individual not operator around two separate unary conditions (i.e. they don't have conditional operators) joined by the and or or operators. It allows you to remove the second not operator and then change the and to or, and vice versa.

:If not(A) and not(B
Use DeMorgan's Law
:If not(A or B

The and and or operators can be replaced using math logic. Since and is only true when all the conditions are true, you can multiply the conditions together for the same effect (you can leave off the multiplication sign). Only one condition has to be true for or to be true, so adding the conditions together works as well. For conditions that have operators attached to them, you just put parentheses around them so they are treated as Boolean values. However, math logic is somewhat slower compared to the logic operators.

:If A and B
:If A or not(B
Replace Operators
:If AB
:If A+not(B

When using the and operator, if the first condition is false, the second condition will not be tested. The and and not operators have the highest importance (precedence) of the logical operators, so they are evaluated first. This is useful when you have a condition that combines the and and or operators (where the and operator comes first), because you don't need to include parentheses around the and operator. However, parentheses are sometimes needed simply to provide clarity.

:If (A=1 and B=2) or (A=2 and B=1)
Remove Parentheses
:If A=1 and B=2 or A=2 and B=1

To put the operators in your program, you need to first be in the Program editor. You press PRGM and then scroll over to EDIT. Once in your program, you press 2nd and MATH. The conditional operators are in the TEST menu, while the logic operators are in the LOGIC menu. You press ENTER to put the commands in your program.

IS>( and DS<(

Two specialized conditional commands are available: IS>( and DS<(. These commands are equivalent to If conditionals, except the next command will be skipped when the condition is true. They have the variable update built-in, so they are smaller than using regular If conditionals.

The IS>( and DS<( commands each take two arguments, but they differ in functionality. The first argument is the variable, and it can be a real variable (A-Z or θ). The second argument is the value, and it can be either a number, variable, or expression.

IS>( adds one to the variable (increments it by one), and compares it to the value. The next command will be skipped if the variable is greater than the value, while the next command will be executed if the variable is less than or equal to the value.

Format
:IS>(variable,value)
:Command

DS<( subtracts one from the variable (decrements it by one), and compares it to the value. The next command will be skipped if the variable is less than the value, while the next command will be executed if the variable is greater than or equal to the value.

Format
:DS<(variable,value)
:Command

These commands are not without problems, however. Because the skipping feature is usually not needed, you will have to make sure that the value is always greater than (or less than) the variable, so that the next command is executed. This is not always possible to do. An undefined error will occur if the variable doesn't exist before the command is used, which happens when the DelVar command is used. Finally, these are not looping commands, so they shouldn't be used in that manner.

To put the IS>( and DS<( commands in your program, you need to first be in the Program editor. You press PRGM and then scroll over to EDIT. Once in your program, you press PRGM again and scroll down the CTL menu until you find the commands. You press ENTER to put the commands in your program.

Loops

Loops cause a segment of code to repeat until a stated condition is met. Instead of having to write out something or do an action several times, you just do it once and put it inside a loop.

There are three different kinds of loops: For, While, and Repeat. There are certain advantages and disadvantages to each loop, and there are also certain situations where each loop should be used. For loops should be used when you know how many times the loop will be executed, whereas Repeat and While loops are the converse. The For loop is the fastest of the three loops.

For Loops

The For loop takes four arguments: the variable (A-Z or theta), the starting value, the ending value, and the increment. It counts from the starting value to the ending value at the specified increment.

The variable is used to keep track of how many times the For loop has been executed. Because it is set to the starting value when the For loop begins, you don't need to initialize the variable before. The ending value is the value that the variable ends at. The increment determines how much the variable's value will be increased each time through the loop. The default increment is 1, so the increment can be left off when it is 1 (it is optional). The increment can be positive or negative.

After each time the For loop is executed, the variable is checked to see if it is equal to or greater than the ending value. If the variable is, then the loop is exited and program execution continues after the End command. (The End command determines the boundaries of the loop.) If the variable isn't, the variable is incremented by the increment and the loop is executed again.

Format
:For(variable,start,end[,increment])
:Command(s)
:End

One of the common uses of For loops is making delays. Although you can use the Pause command, this brings the program to a halt and the user has to press ENTER to get out of it. With a For loop, you can make a small delay that will only last as long as you want it to last and it doesn't require the user to do anything. You just use an empty For loop (no commands inside of it). The larger the difference between the starting and ending values, the bigger the delay.

:For(X,1,200)
:End

Sometimes you might want to prematurely exit out of a For loop (stop it before it is completely finished). You can do this by changing the variable inside the loop. You just need to make the variable larger than the ending value.

:For(A,5,100)
:110→A
:End

To put the For loop command in your program, you need to first be in the Program editor. You press PRGM and then scroll over to EDIT. Once in your program, you press PRGM again and scroll over to CTL. You then scroll down to For (or press the 4 key) and press ENTER. The End command can be found in the same menu, just lower at the seventh spot on the menu (press the 7 key).

While Loops

A While loop executes a block of commands between the While and End commands while the specified condition is true. The condition is tested at the beginning of the loop (when the While command is encountered), so the loop will be skipped entirely if the condition is false when the loop is first entered. To ensure that the loop will be executed, you need to declare the values of the variables in the condition before the loop.

After each time the While loop is executed, the condition is checked to see if it is false. If it is false, then the loop is exited and program execution continues after the End command. If the condition is true, the loop is executed again.

Format
:While condition
:Command(s)
:End

When using While loops, you have to provide the code to break out of the loop (it isn't built into the loop). If there is no code that ends the loop, then you will have an infinite loop. An infinite loop just keeps executing, until you have to manually exit the loop (by pressing the ON key). In the case that you actually want an infinite loop, you can just use 1 as the condition. Because 1 is always true (based on Boolean Logic), the loop will never end.

Format
:While 1
:Command(s)
:End

To put the While loop command in your program, you need to first be in the Program editor. You press PRGM and then scroll over to EDIT. Once in your program, you press PRGM again and scroll over to CTL. You then scroll down to While (or press the 5 key) and press ENTER. The End command can be found in the same menu, just lower at the seventh spot on the menu (press the 7 key).

Repeat Loops

A Repeat loop executes a block of commands between the Repeat and End commands until the specified condition is true. The condition is tested at the end of the loop (when the End command is encountered), so the loop will always be executed at least once. This means that you sometimes don't have to declare or initialize the variables in the condition before the loop.

After each time the Repeat loop is executed, the condition is checked to see if it is true. If it is true, then the loop is exited and program execution continues after the End command. If the condition is false, the loop is executed again.

Format
:Repeat condition
:Command(s)
:End

When using Repeat loops, you have to provide the code to break out of the loop (it isn't built into the loop). If there is no code that ends the loop, then you will have an infinite loop. An infinite loop just keeps executing, until you have to manually exit the loop (by pressing the ON key). In the case that you actually want an infinite loop, you can just use 0 as the condition. Because 0 is always false (based on Boolean Logic), the loop will never end.

Format
:Repeat 0
:Command(s)
:End

To put the Repeat loop command in your program, you need to first be in the Program editor. You press PRGM and then scroll over to EDIT. Once in your program, you press PRGM again and scroll over to CTL. You then scroll down to Repeat (or press the 6 key) and press ENTER. The End command can be found in the same menu, just lower at the seventh spot on the menu (press the 7 key).

Nesting Loops

One important aspect of loops is putting them inside other loops (known as nesting). Besides nesting any of the different kinds of loops inside each other, you can also nest loops inside conditionals. When nesting loops, you need to remember to put the appropriate number of End commands to close the loops.

The easiest way to keep track of lots of nested loops is to code the first part, add an End immediately after the conditional, and then hit [2ND][DEL] on the line with the End, then hit [ENTER] a lot of times.

Branching

Branching allows the calculator to jump from one point in a program to another. Sometimes you don't want every part of the program to be executed. You may want to skip over a certain part of a program if a certain condition occurs.

Branching uses the Lbl and Goto commands. Lbl and Goto work in pairs; you need to have both for branching to work. The Lbl command specifies a location in a program. The label can be any one or two alphanumeric character combination (from A-Z, 0-9, and θ), but ideally you want it to be only character to save memory. The Goto command causes program execution to jump to the specified label with the same character combination, and then continue from there.

Format
:Lbl character1[character2]
:Goto character1[character2]

When using branching, you have to provide the break-out code (it isn't built-in). If there is no code that ends the branching, then program execution will continue indefinitely, until you manually exit it (by pressing the ON key). If conditionals are commonly used, but in the case you want infinite branching, you should instead use a While or Repeat loop.

:Lbl A
:Goto A
Replace with Loop
:Repeat 0
:End

To put the Lbl and Goto commands in your program, you need to first be in the Program editor. You press PRGM and then scroll over to EDIT. Once in your program, you press PRGM again and scroll over to CTL. You then scroll down to Lbl (or press the 9 key) and press ENTER. The Goto command can be found in the same menu, just lower at the tenth spot (press the 0 key).

Disadvantages of Branching

Although branching may seem like a good alternative to loops, it should be used sparingly. Branching should only be used when a loop isn't practical and when something only happens once or twice. This is because branching has several disadvantages associated with it.

The biggest disadvantage of branching is that it's slow. When the calculator reaches a Goto command, it stores the label name in memory and goes to the beginning of the program. It then searches through the program until it finds the Lbl command with the matching label name. If the label is deep within the program and you have a large program, this can bring the program to a crawl.

Another disadvantage of branching is that it can lead to memory leaks when used to exit conditionals or loops (anything that uses an End command). The calculator stores the End command in memory, and it is only released when the calculator reaches it.

If the conditional or loop is exited with branching, however, the End command is never released from memory, and the calculator will continue using that memory. If this is done enough times, the calculator will eventually run out of memory, causing a memory leak. When there's less memory, the program also runs more slowly. Memory leaks don't have any real affect on the calculator, as the memory is released when the program exits.

The last disadvantage of branching is that it makes program code difficult to read and maintain. While loops are straightforward, following a set pattern, branching can lead to anywhere in a program. Trying to figure out how branching affects the program code can cause some serious headaches.

Reworking Branching to Remove Memory Leaks

One of the simplest memory leaks that occurs is using branching to exit out of a loop when a certain condition of an If conditional is true. If the loop is an infinite loop (i.e. Repeat 0 or While 1), you should take the condition from the If conditional and place it as the condition of the loop. This allows you to remove the branching, since it is now unnecessary.

:Repeat 0
:getKey→B
:If B:Goto A
:End:Lbl A
Place Condition in Loop
:Repeat B
:getKey→B
:End

Of course, the only reason that this memory leak fix is possible is because of the If conditional (since the If conditional doesn't need a closing End command). When dealing with an If-Then or If-Then-Else conditional, you will have to rework the conditionals so the branching has its own If conditional. Depending on how many commands there are in the conditionals, you might be able to just use an If conditional or you might need to use an If-Then conditional.

:If B:Then
:Disp "Hello
:Goto A
:End
Use Separate If Conditionals
:If B
:Disp "Hello
:If B
:Goto A

This memory leak fix will work most of the time, but it isn't applicable when one of the values of the variables in the condition is changed by one of the commands inside the condition. The way to get around this is by using another variable for the If conditional that the branching uses. You initialize the variable to zero, assign the variable whatever value you want in the conditional, and then check to see if the variable is equal to that value in the branching conditional.

:If A=1:Then
:3→A:4→B
:Goto A
:End
Use Another Variable
:Delvar CIf A=1:Then
:3→A:4→B:π→C
:End
:If C=π
:Goto A

So What Is Branching Good For?

Despite its many disadvantages, Lbl and Goto statements actually have their uses. For example, you may want to have a label at the end of the program that you Goto everywhere you want to exit the program. This is useful if you have a lot of clean-up (such as deleting large temporary variables) every time the program exits.

If K=45:Goto Q
...
Lbl Q
DelVar [A]DelVar L1
ClrHome

Goto statements are also good in programs that call themselves very many times. Every time a Repeat or While statement is encountered, the program has to set aside a portion of memory to remember about that statement. In recursive programs, this can add up (a good example is a recursive program to fill in an arbitrary shape). Gotos require no such overhead, and if the program is small, they're not as slow as they are in larger programs.

Just remember that since Goto-Lbl constructs are slow when the label is far from the beginning of the program, and you shouldn't use them in speed-critical situations. Also, they make your program hard to read for when you or anyone else edits it, especially if they jump backwards.

Subprograms

Subprograms are programs called from inside other programs (at any time while the program is running). Although they are listed in the program menu and can be executed independently like any other program, subprograms are primarily designed to do a particular task for the other program.

The prgm command is used to execute another program as a subprogram. You insert the prgm command into the program where you want the subprogram to run, and then type (with the alpha-lock on) the program name. You can also go to the program menu to choose a program, pressing ENTER to paste the program name into your program.

Format
:prgmname

To create a subprogram, you take the code from the parent program and put it in a new program. When naming your subprograms, you should try to name them Zparentn or θparentn, where parent is the name of the parent program and n is the number (if you have more than one). Because subprograms are relatively unimportant by themselves, you want them to appear at the bottom of the program menu.

When the subprogram name is encountered during a program, the program will be put on hold and program execution will transfer to the subprogram. Once the subprogram is finished, program execution will go back to the program, continuing right after the subprogram name.

Although subprograms can call themselves or other subprograms, this should be done sparingly because it can cause memory leaks if done too much or if the subprogram doesn't return to the parent program. Branching is local to each program, so you can’t use Goto in one program to jump to a Lbl in another program. All variables are global, so changing a variable in one program affects the variable everywhere else.

To put the prgm command in your program, you need to first be in the Program editor. You press PRGM and then scroll over to EDIT. Once in your program, you press PRGM again and scroll over to CTL. You then scroll down until you get to the prgm command, and press ENTER to put the command in your program.

Advantages & Disadvantages of Subprograms

There are several advantages of using subprograms. First, and foremost, subprograms reduce program size by eliminating redundant code. Instead of having to type the code multiple times for a task that occurs more than once in a program, you just type it once and put it in a subprogram. You then call the subprogram whenever you want to perform the task in your program.

Second, subprograms increase program speed by making programs as compact as possible. You separate conditional tasks from the program (they either happen every time or they are skipped over), and put them in a subprogram; you then call the subprogram instead. This improves program speed because the calculator doesn't have to go through all of the conditional code anymore.

Third, subprograms make editing, debugging, and optimizing easier. Instead of going through the entire program, looking for the code you want to change, you can focus on one subprogram at a time. This makes the code more manageable, allowing you to more thoroughly look at each subprogram and to better keep track of which subprograms you have looked at.

Lastly, subprograms are reusable, allowing multiple programs to share and use the same code. Breaking a program into smaller, individual subprograms, which each do a basic function or task, allows other programs to use those subprograms. Consequently, this reduces program size.

The primary disadvantage of subprograms is that there are additional programs that the user needs to use your program. If you give someone your program, you will have to also give them your subprograms. Your program won't work properly anymore if somebody deletes your subprograms or forgets to include them with your program. Although this is mostly out of your hands, users will think your program is at fault.

The simple solution to this problem is to put the subprogram back in your program when you finish it. This should only be done if the subprogram was just used once or twice and it won't slow the program down. All you have to do is paste the code from the subprogram in place of the program call. You could also put all of the programs used into a group and distribute it as so.

Exiting Programs

Exiting programs (terminating the execution of a program) is done with the Return and Stop commands. The two commands are different and each have advantages.

In most cases, Return and Stop both stop program execution and return to the homescreen (even from inside loops). Return and Stop function differently, however, when used in subprograms. The Return command will stop the subprogram, and program execution will resume in the calling program after the line where the subprogram was called. In contrast, Stop will stop both the subprogram and any calling programs and go to the homescreen. Return should generally be used instead of Stop because old versions of some utilities such as DCS cannot safely run programs with the Stop command.

:ClrHome
:Input "Guess:",A
:Stop
Replace Stop with Return
:ClrHome
:Input "Guess:",A
:Return

When the calculator reaches the end of a program, it will automatically stop executing as if it had encountered a Return; therefore, Return is unnecessary on the last line of a program.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/controlflow


User Settings
MODE.PNG FORMAT.PNG TBLSET.PNG

The TI-83 series of calculators has many options to select from that influence either the effect of commands or the way numbers or graphs are displayed. Outside a program, these can be changed by accessing the Mode, Format, or TblSet screens (shown above), and selecting the correct options. When editing a program, going to these screens and choosing an option will instead paste a command that sets that option for you.

These commands are given below, divided by the screen where it is found:

Mode Settings (MODE)

Graph Format Settings (2nd FORMAT)

  • RectGC and PolarGC determine how coordinates of the cursor are displayed and stored.
  • CoordOn and CoordOff determine whether the coordinates of the cursor are displayed at all.
  • GridOn and GridOff determine whether the grid is displayed.
  • AxesOn and AxesOff determine whether the X and Y axes are displayed.
  • LabelOn and LabelOff determine whether the X and Y axes are labeled (if they are displayed)
  • ExprOn and ExprOff determine whether the equation graphed or traced is displayed.
  • Time, Web, uvAxes, uwAxes, and vwAxes (visible in Seq mode) determine the way sequences are graphed, the default being Time.

Table Settings (2nd TBLSET)

  • IndpntAuto and IndpntAsk determine whether values of the independent variable in the table are calculated automatically.
  • DependAuto and DependAsk determine whether the values in the table are calculated automatically for all equations.

Miscellaneous Settings (2nd CATALOG)

Using these settings in a program

A fair amount of these settings are important to programmers because, if set to the wrong value, they can easily mess up the program. At the beginning of the program, therefore, it's a good idea to set these settings to the correct value. At the very minimum, programs that use the graph screen should set AxesOff if necessary, since AxesOn is the default and a very common setting. This is a part of program setup.

However, another important consideration is that it's somewhat rude to change the user's settings without permission, so your program should change as little as possible. How to reconcile these diametrically opposite goals? There are several ways that work for different settings:

Use GDBs (Graph DataBases)

The graph screen settings can be backed up in (and retrieved from) a GDB file by the StoreGDB and RecallGDB commands. If you store to a GDB at the beginning of the program, and recall from it at the end, you will have preserved all settings that deal with the graph screen.

Change math settings implicitly

Instead of changing settings like the Degree/Radian or the Real/a+bi setting, you can use certain commands that will force calculations to be done with that setting regardless of the mode. For example, you can use the degree symbol or radian symbol to make ambiguous calculations like sin(30) into unambiguous ones like sin(30o). Similarly, by adding 0i to a number, you force it to be complex, so that calculations done with it will never cause an ERR:NONREAL ANS (even if you're in Real mode).

Ignore uncommon settings

You might ignore settings that are too uncommon to matter. For example, setting the Full command is unnecessary, because very few people would ever use a split screen, and people that do probably will also figure out why your program breaks when they do so.

Be rude when you must

For something like Float, there's no way to avoid changing the user's settings in a way you can't restore. If you have to change a setting so your program works, do it, and mention the issue in the readme. If you changed a setting to an uncommon value, change it back to "Float" (in general, to the default value) when you're done.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/settings


Memory Management

The TI-83 and TI-84 series of calculators feature a considerable amount of memory available for storing variables, programs, groups, and even assembly applications (the last two are only available on the TI-83+/TI-84+/SE calculators). However, as you start putting those things on the calculator, the memory slowly gets used up, and if you don't do anything, the calculator will eventually run out of memory — giving you the dreaded ERR:MEMORY error.

Before getting into memory management, it is important that you know there is a major difference between the TI-83 calculator and the rest of the TI-83 and TI-84 series of calculators. In particular, the TI-83 just has RAM (Random Access Memory) memory, while the rest of the calculators have RAM memory as well as Flash ROM (Read-Only Memory) memory, also known as archive memory.

RAM is the faster memory of the two, and it is what is primarily used whenever you run a program. Its one downfall is that it tends to get cleared very easily after crashes. Most people have probably noticed this when their calculator crashed, and they turned it back on, and it said RAM cleared. In addition, variables in RAM can be overwritten accidentally by a program that uses them.

Flash ROM, on the other hand, is the more reliable memory, and it is what is used when you want to store a program for long-term. Its one downfall is that you can't access something stored in ROM. The only exception to this is assembly programs and applications, which are programmed in the calculator's own programming language and thus can access anything on the calculator.

There are several different commands you can use for managing your calculator's memory:

  • DelVar — DelVar is useful for deleting variables, which is the most obvious way to manage memory, and it is what most people are interested in. The DelVar command can delete any variable that you want, with exception to specific elements of a matrix or string or system variables.
  • ClrList/ClrAllLists — Similar to DelVar, ClrList and ClrAllLists only work with lists and they set the dimensions of one list or all lists to zero respectively. This essentially causes the list(s) to be deleted, since you can't do anything with a zero element list.
  • Clear Entries — When executing programs or doing math on the calculator's home screen, the calculator keeps a history of these entries (you can cycle through them by pressing 2nd ENTER). If you do a lot of stuff on the home screen, the entries history can become rather large.
  • Archive/UnArchive — When using variables and programs, you need to move them from archive to RAM; and when you are done using them, you move them back to archive. While you can archive programs on the home screen, that is not possible from inside a program (although you can use an assembly library to do that).
  • GarbageCollect — As you archive and unarchive variables and programs, the calculator keeps storing things until it eventually needs to clean the archive memory. Rather than simply leaving this until the calculator finally forces you to do it, which takes a fair amount of time, you can run the GarbageCollect command periodically.

Since the TI-83 calculator only has RAM memory, it does not have the Archive, UnArchive, and GarbageCollect commands. If you plan on porting a program to the TI-83, you shouldn't use any of these commands, since they will cause the program to be corrupted. In the case of lists, however you can use the SetUpEditor command instead of UnArchive to get around this problem.
Also note that trying to use DelVar or ClrList with an archived variable does not work, and will actually return an ERR:ARCHIVED error.

Accessing the Memory Menu

When accessing a variable or program from the memory menu, you press 2nd MEM. You then select 2:Mem Mgmt/Del and press one to display a scrollable list of all the files on the calculator. You use the up and down keys to move the cursor on the left. On the top lines of the screen you will see how much free RAM and ARC (archive) memory there is.

Once you have found a file you want to delete, press DEL. If the file is not a variable, the calculator will prompt you to confirm the deletion, and you have to select 2:Yes. Once you have found a file you want to archive, press ENTER. An asterisk will appear to the left of the file name, indicating that it is archived. Some files, such as applications, will not allow you to unarchive them since they can only reside in ROM.

Archiving may sometimes not be possible, however, if the calculator does not have sufficient free ROM available. This occurs primarily when a person can't bring themselves to delete a file because they feel like every file is important. At this point, the only option is to delete some files off of their calculator to make room. As part of memory management, a good policy is to keep the calculator's memory organized and to delete any files that you don't need.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/memory-management


Time And Date Commands

The TI-84 Plus and TI-84 Plus SE, which have a built-in hardware clock, introduce several commands for dealing with time. Some of these rely on the built-in clock, while others are used for formatting times and dates and could technically have been introduced on earlier calculators. However, the only time/date command that is available on the pre-84 calculators is dbd(.

All of these commands except dbd( can be found only through the command catalog (2nd CATALOG). dbd( can also be found in the Finance menu — 2nd FINANCE on the TI-83, and APPS 1:Finance… on the TI-83+ or higher.

Despite its name, the Time command has nothing to do with the clock. It is a mode setting for sequence graphs.

Low-Level Commands

  • startTmr — This command returns the current value of a timer that is updated every second when the clock is enabled. This value doesn't correspond to any actual time, but can be used with checkTmr( to get a time difference.
  • checkTmr( — checkTmr(X) is equivalent to startTmr-X. This can be used to get the time elapsed since startTmr was used.
  • ClockOn, ClockOff — Enables or disables the hardware clock.
  • isClockOn — Tests if the clock is enabled or not.

Time Commands

  • setTime( — Sets the current time, in hours, minutes, and seconds. If the clock is enabled, this time will be updated every second.
  • getTime — Returns the current time as the list {hours, minutes, seconds}. This command is unaffected by time format.
  • setTmFmt( — Sets the time format - 12 hour, or 24 hour.
  • getTmFmt — Returns this time format setting.
  • getTmStr( — Returns the current time as a string, affected by time format (though you can override it with an optional argument).

Date Commands

  • setDate( — Sets the current date (year, month, and day). If the clock is enabled, this date will be updated as needed.
  • getDate — Returns the current date as the list {year, month, day}. This command is unaffected by date format.
  • setDtFmt( — Sets the date format - 1 for month/day/year, 2 for day/month/year, or 3 for year/month/day.
  • getDtFmt( — Returns this date format setting.
  • getDtStr( — Returns the current date as a string, affected by date format (though you can override it with an optional argument).

Time/Date Manipulation

  • timeCnv( — Converts a number of seconds into a list of {days, hours, minutes, seconds} representing the same time lapse.
  • dayOfWk( — Returns the day of week (Sunday through Saturday encoded as 1 through 7) of a specified date.
  • dbd( — Returns the number of days between two dates — this command is available on all calculators, not just the 84+/SE.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/time-and-date


Planning Programs
toolbar-separator.png This article is part of the planning stage of the development cycle.

Before writing any of the code for a program, you should carefully plan out the program. This may seem like an unnecessary step, time that could be better spent, but it will pay major dividends in the end. Planning not only results in better quality programs, but many times it will also cut down the coding time (since you don't have to waste time rewriting the program) — a win-win situation!

The first thing you want to do when planning a program is to decide what the program will do. Beginner programmers often say that they want to create a cool game, but they don't get much farther than that. For them to have a real chance of creating their program, they need to determine what the objective of the program will be, and then build off of that. For program ideas, see the project-ideas page.

When coming up with an idea for a program, you should try to be realistic about the limitations of TI-Basic, and what a program can and can not do. For example, a game that needs lots of speed to be worthwhile for the user to play, such as Phoenix or Mario, really isn't very practical in TI-Basic beyond only moving a few things on the screen at any one time. In addition to speed, TI-Basic also suffers from limited graphics capabilities.

Once you have determined what the program will do, you need to decide what features the program will have. This can include: potential program options, the interface (home screen or graph screen), main menu, an about screen, user help, and any other things you may want. The more thorough you are with planning your program, the easier the coding will be; it is to your benefit to do a good job.

If you can't come up with any ideas for your program or you are unsure of if the ideas that you have come up with make sense, you should get input from the TI community. The four most friendly, active user forums are:

Since these are some of the people who will be using your program when it is finished, you should ask them to evaluate your program concept and to offer some constructive criticism. They might also be able to give you some new ideas that you never thought of.

Even if you thoroughly plan a program and get community input, it's simply not possible to think of everything up front. While making changes later on when a program is in heavy development can be a lot more work than making those changes at the beginning, there's nothing wrong with changing or modifying your plans, if you believe the program will be better with the change(s).

Research Before Coding

Before doing any coding, you should do some research to determine what the best algorithms are for use in your program. One of the most common problems is a poorly though out algorithm, which may not work properly with other parts of the program.

When you do research you ensure that the algorithm is appropriate and that it will work effectively. This helps eliminate flaws in your algorithm, which can cause a multitude of errors if left unfixed. If you think your program through before you start coding, you can save yourself lots of time because you don't have to do several rounds of testing and debugging to get your program to work the way it should.

One of the ways to test an algorithm and how effective it will be in your program is to take a very small problem and trace by hand how your chosen algorithm would work in that situation. This allows you to see if the algorithm will actually work in the given situation.

If the algorithm doesn't work, you can immediately start looking for another algorithm. This saves you lots of potential time because you would have to come up with another algorithm had you just started coding it. Only when you are confident with the algorithm should you start the coding.

Translate It Into Pseudocode

The next step in the process is turning the program plans into pseudocode. Psuedocode involves using English (or whatever language you speak) in place of the TI-Basic code to describe what the program will do to perform the desired functions and tasks. This prevents you from getting caught up in the TI-Basic syntax, allowing you to more clearly focus on the program.

You should first start by looking at the big picture of the program and then break it down into smaller and smaller details. Using an outline as the base, this means you would put the most important things first and then gradually add everything else. This allows you to mentally picture what the program is going to look like and to make sure you don't forget anything. Remember to leave many times more space than you think you'll need for an outline, you'll probably end up discovering a few areas you hadn't thought of yet that need to be taken care of.

An important part of creating useful pseudocode is adding comments throughout. It is very easy to get lost in your logic or have problems come up that you don't have any idea on how to resolve. Besides telling you what the code is supposed to do (i.e. making coding easier), it will also force you to slow down and think through the logic of your program. Still, comments are only as good as you make them.

Use Many Small Programs While Coding

A single large program quickly becomes unwieldy and difficult to manage. While you're still editing the program, it's best to keep it in many small pieces. When you're done, you can combine them into one program again.

One of the benefits of this approach is that you can convert pseudocode into a main program almost right away. For example, imagine this pseudocode program:

Main Menu - user enters difficulty, etc.
Initialize variables
Main Loop:
 Player movement
 Draw player
 Enemy movement
 Draw enemy
 Check Win/Loss Condition
End Main Loop
If we won the game
 Display win message
Otherwise
 Display loss message
Cleanup

You could translate this into a basic program almost directly. Here's how we do it (note that we don't write any code yet):

prgmMAINMENU  // user enters difficulty, etc.
prgmINITVARS  // initialize variables
Repeat Z
prgmMOVEPLR  // moves player
prgmDRAWPLR  // draws player
prgmMOVENMY  // moves enemy
prgmDRAWNMY  // draws enemy
prgmWINLOSE  // sets Z to 1 or 2 if we won or lost
End
If Z=1:Then  // we won
prgmWEWON  // says "You win!"
Else
prgmWELOST  // says "You lose!"
End
prgmCLEANUP  // delete used variables

As you progress in writing the actual code, you create and edit each individual program (for example, you would create and edit prgmMAINMENU and write a menu in that program). Of course, if these sub-programs are big enough, you can split them up into their own sub-sub-programs in the same way.

When all the subprograms are finished, the program will work as it is, in 50 or so pieces (so you can test for bugs and tweak the individual programs). However, if you want to release your program, you probably don't want there to be 50 small programs to send. You can use the Recall feature (press [2nd][STO] to get to it) to combine the programs.

Go through the main program. Every time you get to a sub-program call, clear that line and press [2nd][STO]. The Recall option will come up. Press the [PRGM] key and select the appropriate sub-program from the EXEC menu. The calculator will paste that sub-program into the main program. When you're done, all the code is in your main program (and you can delete the now-unnecessary sub-programs)!

<< Creating New Program Versions Overview Portability >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/plan


Commenting Your Code
toolbar-separator.png This article is part of the coding stage of the development cycle.

When you are in the process of writing a program, everything about the program (i.e., variables, program structure, branching labels, etc.) is fresh in your mind and it's easy to remember. But what would happen if you stopped working on the program for a year, and then decided to start working on it again?

All or most of your previous knowledge of the program would be gone, and you would have to spend some time (or lots of time, depending on the program) to figure out how the program works again. While this is only a hypothetical example, this problem is a real concern for lots of people who have multiple projects going at any one time.

Thankfully, this problem can be easily prevented by simply adding comments to your code. A comment is a brief note that describes some functionality or feature of your code. You don't need to comment everything, but the two main things that you should comment are:

  • Program Structure — Loops and branching with appropriate label names
  • Variables — What their purpose is and any possible values

The amount of free RAM is the only limit on comment size, but you should generally try to keep your comments clear and concise. In addition, if your comment is more than a couple lines in length, you should split it up into multiple lines. This makes it easier to read and update, if needed.

Text Comments

There are a couple different ways that you can add text comments to your code, with each having their own advantages and disadvantages. The first way is to make the comment a string literal (i.e., place a quote before the comment text), and then just place it on its own line.

:"Comment here

The advantage of this comment method is that it is extremely simple to use and update. You can make your comment almost anything you want (the two characters you can't use are the store command and a quote), and the calculator just reads it as a string.

The disadvantage of this method is that it prevents you from using the Ans variable, since the comment will be stored to Ans when the calculator reads it. The comment also slows the program down because the calculator has to execute it each time.

The second way to add a text comment to your code is by placing the comment in a conditional or loop, and using zero as the condition. Based on Boolean logic, the condition will always be false, which causes the calculator to not execute the conditional or loop, and subsequently skip right over the comment nested inside of it.

:While 0
:Comment here
:End

The advantage of this comment method is that it doesn't mess with any of the variables, and you can use the store command and quote character. The disadvantage is that it takes up some additional memory to use the conditional or loop, and this problem only worsens the more comments you use.

Indenting Code

Another way to comment code is by indenting it, which allows you to easily identify control structures and blocks of code. Just like how there is a built-in colon that denotes the beginning of each new line, you can place your own colons before any statements on a line.

:While 1
::Disp "Hello
::Disp "Goodbye
:End

Although there is no restriction on how many colons you can place at the beginning of a line, one colon is generally sufficient. However, if adding two or three colons helps you better visualize the code, then that's what you should go with.

It is usually discouraged to use this method. Not only does it take up additional memory by adding bytes to the program, it also affects some commands. For example, the following method will not work. The intention of the code is to display only "FALSE".

:2→A
:If A=1
::Disp "TRUE"
:Disp "FALSE"

By adding the extra colon, an extra line is added. This specific line is skipped due to the If statement being false. However, Disp "TRUE" is run as well as Disp "FALSE".

Descriptive Variables

Yet another way to comment code is by using descriptive variables that reflect where and how they are used. This is primarily related to using the real variables (A-Z and θ), since they are the most commonly used variables, and are much smaller and faster than other variables.

Of the real variables, the standard variables and situations are:

  • I and J for the looping variable in For( loops
  • X and Y for the X and Y screen coordinates respectively.
  • K for storing the keypress with the getKey command.

Each of these variables is mnemonic — for example, K is the first letter in keypress — making them fairly easy to remember.

Advanced Uses

You can modify the text comments so that you can turn them on or off. You just use a conditional with a variable as the condition, and then change its value from false (i.e., the comments are off) to true (i.e., the comments are on). Based on Boolean logic, the easiest system for the variable value is one for true and zero for false.

You also need to display the comments on the screen, so that you can read them during program execution. If you are using the home screen, you should use the Pause command and its optional argument. While program execution is halted until the user presses ENTER, the Pause command allows you to display the entire comment on one line, and you can even scroll the comment left or right to read it, if necessary.

:If A:Pause "Comment here

You should use the same variable for all of the comments, so that the comments work in unison. The variable can be whatever you want, but the simplest variable to use is a real variable (A-Z and θ). You just need to remember to set the variable to zero at the beginning of the program, so that the comments are turned off by default.

<< Techniques Overview Subprograms >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/comments


Code Conventions
toolbar-separator.png This article is part of the coding stage of the development cycle.

Code conventions are a set of guidelines for writing programs, primarily focusing on the structure and appearance of the code. Although code conventions are generally subjective and informal, just the individual preferences of each programmer developed over time, there are several common conventions that most programmers follow and are considered to constitute good programming practice.

Following code conventions not only makes your code consistent, helping to make it easier to read and understand, but also eliminates a lot of the difficulty in maintaining it. Code conventions are also important in group projects, where multiple people are working together and everybody needs to be on the same page.

Naming

The general convention for naming programs, subprograms, labels, and custom lists is to choose a name that tells you what it is (in the case of programs and subprograms) or that relates to how it is used (in the case of labels and lists).

For example, if your program is a Minesweeper clone, then a good program name is something like MINES. If your MINES program has a subprogram, start it with θ or Z so that it appears at the bottom of the program list.

If you have a highscore function built-in to your game, then you should use a custom list that is related to your program's name (i.e., LMINE would make sense for the MINES game mentioned above).

In the case of a label name, you should make it mnemonic — Lbl UP would be an appropriate choice for the code that moves the screen up.

Formatting

The general convention for formatting code is to place related statements together on the same line. This is most applicable with variable declarations, If-Then conditionals, and short loops, although you can certainly put whatever statements that you want.

The way you get multiple statements on the same line is by separating each one with a colon, which is also used to denote the beginning of each new line. The program editor on the calculator allows sixteen characters per line, so if the statements are wider than that, they will cause the line to wrap around to the next line (and however many more lines are needed).

Structure

The general convention for structuring code is to use a loop, except for those situations where using a loop is impractical; in those cases, using a Goto is the preferred convention.

When deciding which loop to use, you need to look at what its functionality will be. If you want the loop to be executed a set number of times, then you should use a For( loop. If you want the code inside of the loop to be executed at least once, then you should use a Repeat loop.

The While loop is very similar to the Repeat loop, so the way to decide when to use either one is by thinking of the loop condition. If the loop is going to keep running as long as the condition is true, then you should use a While loop. If the loop is going to run until the condition is true, then you should use a Repeat loop.

Variables

The general convention for using variables is to use the most appropriate variable whenever possible. There are several different kinds of variables available, including reals, lists, matrices, and strings, and they each have their own time and place.

Reals are used for keeping track of one value, and because they are both small and fast, you should use them before using other variables. Lists are used for keeping track of multiple values, and because they can be created, you should use them for saving highscores and other important data.

Matrices are used for keeping track of two-dimensional values, which means you should use them for making maps on the screen. Strings are used for keeping track of characters, which means you should use them when you want to display text on the screen.

Sample Program

The following sample program is a modified form of the program on the movement page. The main things you should notice are the real variables grouped together on the first line and the use of the Repeat loops for the code structure.

PROGRAM:MOVEMENT
:4→A:8→B
:Repeat K=105
:Output(A,Ans,"X
:Repeat Ans:getKey→K:End
:Output(A,B," "
:A+(Ans=34)-(Ans=25
:Ans+8(not(Ans)-(Ans=9→A
:B+(K=26)-(K=24
:Ans+16(not(Ans)-(Ans=17→B
:End
<< Program Setup Overview Techniques >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/code-conventions


Debugging Programs
toolbar-separator.png This article is part of the revising stage of the development cycle.

Going through the process of debugging your programs may seem like a lot of unnecessary work, but it is better that you find and correct the errors then having the user of your program tell you that your program doesn't work. On this page, we've tried to simplify debugging for you by breaking it down into general steps that you can follow. Just remember to always strive for bug-free programs.

Backup & Document

Before debugging, make a backup of your program. This is to ensure that you don't lose your program in its current form. During the debugging process it is easy to mess up your program, overwriting or deleting necessary pieces of code. If you just spent several hours working on your program, you don't want to have all of that work wasted.

You should also backup your program before changing anything. This is so you will have a version of your program that you can return to if you mess up your program while doing further debugging. Instead of having to undo any coding mistakes that you made, you can just go back to the last updated version of your program.

You also want to document your program and the variables you use. This is important because it makes it easier to come back to the program in the future (if you need to). Documenting a program entails listing what the program does, how it does it, and anything else that might be important. For documenting the variables, you should list out all of the variables, including what they are used for and what values they can have.

Simplify the Code

You want to remove any code that is not related to the problem. If you are unsure of what code is related to the problem, look at what its function is. If the code is changing variables or controlling program flow, then it may be important to keep it. If it is just print statements or checking conditionals, you can probably remove it without it affecting the code.

Once you have identified the code that contains the error, you will want to create a new program and put the code in it. If the error still exists, you will want to remove parts of the code, repeatedly testing the code afterwards each time. If the error disappears, you know that the last part of the code that you removed is what caused the error.

One of the most common problems that programmers make when debugging their code is making lots of changes at once. This is usually not very effective because it can lead to other problems within the code or, if it results in removing some of the errors, you don't know which changes corrected the errors. It also tends to make the debugging process very unorganized because you will have to re-test parts of the code, and sometimes you won't even know which parts need to be re-tested. What you should do instead is fix each problem individually and then test the program. This will take you longer, but your program will have fewer errors and problems.

This can further be improved upon by breaking the program up into modules, testing and debugging the individual modules separately from the main program. The advantage of testing the modules by themselves is that it is easier to find errors. Instead of having to look at the whole program, you can look at an isolated part. Once you have removed all of the errors in the module, you don't have to test it again. After going through all of the modules, you then just have to debug the main program that calls the modules.

Analyze The Error

When you are trying to fix an error in your program, you will want to gather as much data about it as possible. To do this you should run your program several times, keeping track of when the error occurs, where it is happening, and what type of error it is.

Once you think you have a solid grasp of the error, you will want to repeatedly test the code that contains the error. If you can consistently produce the error, you will know that you are on the right track to fixing it. If you can't produce the error, however, that means you need to do more extensive analysis.

One of the most effective ways of debugging programs is to walk through the code. This involves sitting down with a printed version of the program, carefully going through its logic. Walking through the code will allow you to see potential solutions to the errors in your program.

There's another way to figure out where your bugs start, especially with Lbl errors. Place equations such as 1/4 around the path of the problematic code. Make every equation different. When the game crashes or acts up, go to the home screen and recall Ans. Whatever number Ans shows you (for our example, it would be .25) is where the code goes awry. Go to that part of the code and run further testing.

Once you have a potential solution, you will want to look at how it should work in the code, and then test it to see if it actually works like you believe. The more thorough you are at analyzing the solution, the easier it will be to tell if it will fix the error. Once you know that the solution will fix the problem, you can then apply it to your program.

Looking at the variables and their values is essential when you are debugging. You will want to take note of how they gradually change throughout the program. If you know which part of the program contains the error, you can then check the variables that are used within that part. Make sure the variables contain values within their correct limits. If they don't, you need to go to the code before and after the error, and check the value of the variables. Make sure the variables are functioning properly, and that you aren't doing anything to change them.

When writing code you will often make assumptions about it. You need to be aware of these assumptions when you are debugging, so you can make sure they are sound. If your program is not functioning properly, you should test all of your assumptions. One of the most common assumptions that programmers make is that the variables they are using are working properly. Most programmers will thoroughly debug their code, but they're not as thorough when debugging variables. Debugging can become very frustrating if you don't thoroughly debug both.

Debugging Tools

When you first start debugging your programs, you will want to check to see that the errors you are getting aren't because of a misuse of a command or a misunderstanding of a command's arguments. You should consult the TI-83+ manual to see what the syntax of the command is and how to use it properly. Many errors that you recieve can easily be remedied if you just consult the manual. In fact, if you use the manual when you are programming your program, you can avoid a lot of the typos and superficial errors during debugging.

The TI-Basic language has a rather useful feature for debugging programs: when it comes across an error while running your program, it will give you an error menu — telling you what the error is and giving you the option to see where the error is in your code. You will want to take the information that it gives you, and then see if you can figure out why it's producing an error.

After the error occurs, you should recall some of your variable's values to see what they are. This might give you an indication of what the error is (if a variable is not in the range it's supposed to be), where in a For( loop you are (just recall the variable you used for the loop), and many other helpful hints.

Many times you will make a simple mistake, such as forgetting to close a string or leaving an argument off of a command. You have to be careful, though, because sometimes the error that the calculator reports isn't the actual error in your code. You might have errors in your code that the calculator doesn't notice because it is still valid code, and it isn't until later that the errors cause problems. These errors are very hard to track down.

Using print statements is one of the oldest and most tested methods for debugging programs. If you come upon a problem in your program, and you can't seem to figure out what's causing it, you should add several print statements throughout the code. When you run your program, you will be able to see what is actually happening. You can do this to see the code that the program is running or to see what values the variables have.

If you don't like using print statements or you think they aren't effective enough, an alternative that you can try is inserting breakpoints (pause statements). Once you think you have identified the code that has the error, you can set breakpoints around it. After restarting the program, look at what happens to the code before and after the breakpoints. If this doesn't give you enough information about the error, you might need to use more breakpoints. The advantage of using breakpoints is that you can pause the execution of your program, allowing you to slowly look at the program and at what's causing the error. Two of the best places to put breakpoints are in program flow statements and inside loops.

Changing the code to solve a problem is an effective way to debug programs. You go to where the problem is, and you start changing parts of the code. You can change whatever you want to, but you should have a general idea of how the code works. If you don't know your code very well, this can cause even more errors. You should also remember to make a backup of your code before you change anything.

If changing the code doesn't help in solving the problem, you might want to try creating test code. Creating test code allows you to focus on the problem, making it easier to see and fix. You look at the code in your program that has the problem, and then you create a new program with similar code. You then experiment with that code, switching things around or adding code to it, looking at how it affects the operation of the code. You can also do this as a way to learn some of the more confusing aspects of the TI-Basic language.

Be Prepared For Setbacks

After working on debugging a program for a prolonged period of time, with no progress and no new ideas on how to fix the error, you stop being able to effectively debug your program.

One of the simplest remedies is to just take a break from debugging and do something else. Take a walk outside around the neighborhood or take a nap. Many times after taking a nap, you will suddenly get the answer to the problem in an epiphany. In addition, it is just a good rule to take frequent breaks from programming so that you don't get burned out so easily.

Although it may seem like debugging your program will be a monumental task requiring lots of work, it is essential that you do it. If you are to release your program to the public, you don't want users complaining that it doesn't work correctly or that it contains errors.

Another cause of feeling overwhelmed is if you are not very good at debugging. When you are just starting out, you will be able to fix the simple or obvious errors, but you will have a hard time tracking down some of the more complicated errors. The only way to get around this is by repeatedly debugging programs until you have figured out the errors for yourself. The more debugging you do, the better you become at it. It just takes practice.

Often when you are debugging a program, and it seems like you just can't find the error in it, you will stop thinking logically and start thinking irrationally. Your only desire is to get the program to work correctly, so you decide that you will do that by whatever means necessary. If you still can't figure out the problem, you might start blaming the calculator or the TI-Basic language.

While blaming the calculator or the TI-Basic language will provide you with temporary relief concerning the error in your program, you have to remember that they don't do any of the thinking. They just follow what your program says to do. You are the one that is responsible for the code that you produce.

Get Outside Help

If you have tried everything that you know to do and you are still unable to fix the problem, you should now start looking for outside help. You should ask other programmers or go to programming forums. Either one of these should be able to help you with your problem.

Asking other programmers for help is a good alternative to getting mad at yourself because you can't figure out the problem. Because you wrote the code, you may make assumptions or have biases when debugging it. You know the code so well that you can't be objective. When another programmer looks at it, though, they don't have any of those hang-ups. In addition, when you're explaining the problem to the other programmer, many times the solution will come to you. Asking the other programmer for help also benefits the other programmer because they improve their confidence debugging programs.

If you asked another programmer for help and they could not find and fix the problem, you should then go to programming forums. The advantage of programming forums is that several programmers are working together, building off of each other's ideas. This is the ideal situation because the more people looking at the code, the greater the chance that the problem will be found and fixed.

Here are some programming forums that you should go to if you ever need help with a problem:

<< Program Cleanup Overview Optimization >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/debug


Setting Up A Program
toolbar-separator.png This article is part of the coding stage of the development cycle.

At the beginning of a program, you typically setup everything that the program will use while it's running. Of course, there are lots of things that you may decide to include in your individual program setup, but the three main things that you should include are: the home screen, graph screen, and initializing variables. There are also some general, but crucial mode settings that should be taken care of.

General Settings

There are some general mode setting that you'll want to pay attention to. Most of those should be what you want, but there is always a chance that a program forgot to switch back to the standards, or that the user was playing around with the calculator.

In the mode menu, there are probably four different modes you need to worry about. These are numeric notation, decimal, real/complex mode, and screen display.

Numeric Notation

How numbers are displayed/returned: Normal, Scientific, and Engineering. Scientific will have one digit on the integer side, and Engineering will have two digits. The standard is Normal.

Decimal

In programs that use pinpoint precision numbers or require complex formulas or calculations, the number of decimals returned can greatly affect the program. Float will automatically adjust to the number of digits the calculator considers significant. Fix 1-9 will fix the calculator to display 1-9 digits, no matter what. This means that the calculator may sometimes give weird results such as 3.100000, or pi=3.

Real/Complex Mode

The default mode, Real, will give ERR:NONREAL ANS whenever a complex number is obtained as a result. If you want to use complex numbers, you should change this setting to a+bi or re^θi (the distinction between these two is only a display one).

If you're going to be using complex numbers, you should switch away from Real mode. Otherwise, it's an inessential setting. Switching to Real mode doesn't have any real (he he) purpose to it, since it doesn't provide any extra functionality - unless of course you like it when your calculator throws errors.

Screen Display

This affects the screen display. Full is probably the one of the only ones you have ever seen. Horiz displays a horizontal split-screen, with the graph on top and home screen on bottom. G-T displays a vertical split-screen, with graph on left and table on right. The standard is Full.

Home Screen

Since the home screen that your program uses is the same home screen that the rest of the calculator uses, the previous program call(s) and any other text is typically still displayed on the screen. Obviously, you don't want to be displaying text and have it interrupted by other text, so you need to clear the home screen. The ClrHome command is what you use.

When using the ClrHome command, you simply place it on a line. The whole home screen will be cleared of any text; there's no way to clear a smaller portion of the ClrHome because it takes no arguments.

:ClrHome

Graph Screen

The typical TI calculator user uses the graph screen to graph, which means they use axes, stat plots, Y= equations, and sometimes the grid. They might also like drawing things with the drawing commands or the Pen. However, while working in a game in use of the graph screen, you really do not want these functions to appear, which would completely mess up your program.

First, you need to disable all these annoying thing by the following code:

:ClrDraw     // Clears the graph screen of all its contents
:AxesOff     // Disables X and Y axis scaling view
:FnOff       // Disable Y= equations
:PlotsOff    // Disables stat plots from appearing
:GridOff     // Disables grid from appearing

After that, you setup the window dimensions to use a friendly window. This not only makes drawing much easier, but it is faster and smaller. One way to do this is shown below:

:0→Xmin:1→ΔX
:0→Ymin:1→ΔY

Initialize Variables

If you have any important variables that you use in the main program loop, you should initialize them here, so the program will be able to use them and not have a delay. This is especially important with large variables (such as lists, matrices, and strings), since initializing those variables inside the main program loop will definitely have an impact on its speed.

:{1,2,3,4→A
:[[1,2][3,4→[A]
:"1234→Str1

Putting It All Together

Putting all the parts of program setup together, here is a typical way to start a program:

PROGRAM:SETUP
:ClrHome
:ClrDraw
:AxesOff
:FnOff
:PlotsOff
:GridOff
:0→Xmin:1→ΔX
:0→Ymin:1→ΔY
:{1,2,3,4→A
:[[1,2][3,4→[A]
:"1234→Str1

Of course, you only have to include the things that you actually use. If you don't have any important variables to initialize, then simply leave that off. In the same fashion, you don't have to clear the clear the home screen if your program just runs on the graph screen.

<< Usability Overview Code Conventions >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/setup


Cleaning Up After a Program
toolbar-separator.png This article is part of the coding stage of the development cycle.

Imagine you just finished playing a round of Blackjack, and now you're back on the main screen. You enjoyed the game, but something is just not right. Not only is there text on the home screen, but there's graphics on the graph screen, and it appears that there's some leftover variables taking up a considerable amount of your precious memory. It seems that the Blackjack game forgot to clean up after itself.

Cleaning up after a program is one of the most important parts of any game. A quality game features good gameplay, but more importantly it doesn't leave the calculator in disarray afterwards so the next program that is run isn't affected by it. While program cleanup can involve whatever the game programmer wants, there are a few standard parts to it.

Deleting Large Variables

The first, and arguably most important, part of program cleanup is deleting variables. After a program finishes running, it should delete any large variables that it created during its execution. The program should only keep variables if they are used for storing important information, such as highscores or map data. You can delete a variable using the DelVar command (provided that the variable is not in the archive).

The user does not want to have their memory cluttered up with lots of variables because it makes scrolling through the memory menu that much harder. They also don't want to lose any of their memory because it prevents them from using it for any other things they want to do (such as running other programs).

Restoring the Graph Screen

After deleting large variables, the next part of program cleanup is to restore the graph screen. Besides clearing the graph screen (using the ClrDraw command), you should recall the graph database (GDB) variable that has the previous window and graph format settings stored in it. (Please note that GDBs do not contain text, graphics, or stat plots.)

You want to make sure to clear the graph screen when exiting programs because this ensures that the next program that the user runs won't have to deal with whatever text or graphics your program left behind. It also helps the user because they won't have to manually clear the graph screen themselves.

At the beginning of a game that uses the graph screen, select whichever GDB you want to use (GDB0 through GDB9) and then use the StoreGDB command to save the window and graph settings into that GDB. Now when the program is finished executing, recall that GDB with the RecallGDB command to recreate the graph screen with the previous graph and window settings that were stored in it. You should then delete the GDB.

Clearing the Home Screen

Once the graph screen is restored, the next part of program cleanup is to clear the home screen using the ClrHome command. Clearing the home screen ensures that the next program the user runs will not have to deal with whatever text the program left behind. It also helps the user, because they will not have to manually clear the home screen by pressing the CLEAR key; you have already done it for them.

Besides clearing the home screen when cleaning up, you should also remember to remove the "Done" message that shows up after a program finishes executing. This "Done" message is a clear indicator that your program just finished running (which can be bad if you are in class and your teacher is near by), and it also does not look very good.

When you display text, a number, a variable, or an expression with a display command (either Disp or Output() on the last line of the program, you can remove the command and just put argument by itself. The argument will be displayed instead of the "Done" message that is normally displayed after a program finishes executing, and it will also be stored into the Ans variable.

:ClrHome
:Disp "Hello
Remove Disp
:ClrHome:"Hello

If you do not display any text on the last line, or you do not have any particular text that you want to be shown, you can still remove the "Done" message by just putting a single quotation mark. This will have the same effect, but there will be no text and the cursor will be placed on the second line.

:ClrHome
Put a quote
:ClrHome:"

In addition to removing the "Done" message, this text also acts as a way to clear the Ans variable. For example, if you had a large variable stored in Ans (such as [A]), which subsequently would cause Ans to also be large, this text would make Ans release that excess memory back to the calculator. You could also add the Clear Entries command before the final text just for good measure.

To remove the "Done" message without moving the cursor (slightly larger):

:ClrHome
:Output(1,1,"             //no space, just a quote

List Editor Cleanup

If you used the SetUpEditor command for lists that your program uses, that also causes the list to appear in the "List Editor" the next time the user accesses it (STAT>Edit…). This probably isn't desired behavior, because it looks unprofessional, and because your program's list is likely to contain highscores and other data of that nature.

To fix this, add a SetUpEditor without any arguments to the end of your program. This will reset the List Editor to the default settings (it will show the contents of L1, L2, …, L6). This isn't perfect, since the user may have been editing his own lists there, but it's the best you can do, since TI-Basic can't find out about the user's previous settings.

If you don't want to restore L1 through L6, you can do:
:SetUpEditor L<name>
:Archive L<name>
:UnArchive L<name>

This will remove L<name> from SetUpEditor.

Putting It All Together

Putting all the parts of program cleanup together, here is a typical way to end a program:

PROGRAM:CLEANUP
:SetUpEditor
:DelVar Str1DelVar [A]
:RecallGDB 1
:DelVar GDB1
:ClrDraw
:ClrHome:"

Of course, you only have to include the things that you actually use. If you don't use any large variables, you don't have to delete them. In the same fashion, you don't have to clear the graph screen and restore the graph screen settings if your program just runs on the home screen.

Advanced Cleanup

If you have a lot of number variables that you used in your program like A, B, C, continuing through Z; you may want to consider using a hexcode to help clear all the variables rather than have a large number of DelVar statements. Although this code takes more memory and requires a subprogram, it can save a lot of typing. Lets take a look at the Delvar Hexcode. This hexcode will take a string in Ans of the name of a variable to delete, and will delete it so long as it is prefixed correctly. To start building the cleanup routine, make a new program containing just the hexcode in it. Save it as something you will remember; I called mine "ZDELVAR". Next, we need to put the code for the routine into our main program. The code looks like this:

"ABC"→Str1
For(θ,1,length(Str1)
" and "+sub(Str1,θ,1
Asm(prgmZDELVAR
End
DelVar Str1

Let's take a closer look at how it works. We store all of the variables we want do delete into String 1. Now we want to run the hexcode for each letter in our string, so we add in a for loop. The starting position will be 1, and the ending position will be however long String 1 is. We know that the hexcode takes an input in Ans, and that real variables have to be prefixed with " and " for the hexcode to work (note that this is the boolean and found in 2nd+Math). So lets take the string " and ", and then add to it the current letter we are on. Now that we have the format we need for the hexcode, run the hexcode! When we finish deleting all the variables, delete String 1. It's as simple as that! All you have to do is put which variables you want deleted into String 1!

If you wanted to delete all the strings, pictures, gdb's, or matricies you can do that too. Simply add the code for the routine again, but change the " and " to the proper prefix and change the variable names!

<< Subprograms Overview Debugging >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/cleanup


Usability (User-Friendliness)
toolbar-separator.png This article is part of the planning stage of the development cycle.

Imagine you are using a program for the first time. You have no prior knowledge about the program; someone just put the program on your calculator without giving you any instructions and now you are trying to figure out how to use it. After literally pressing all of the keys on the calculator and trying all sorts of key combinations, you give up and and delete the program.

This example isn't based off any one particular program, but it does resonate with lots of program users who have had a similar experience. What this problem really is about is poor user-friendliness — more commonly known as usability. The definition of usability is simply how easy it is for people to use a program.

While usability can take on many different forms, there are some essential things that you can do to make a program more user-friendly.

In-Program Help

Probably the easiest way to make a program user-friendly is by including some in-program help. While you ideally want your program to be so easy to use that a user can simply pick it up and figure out how to play it, not every game is so straightforward, and the average user probably needs some help.

The best place to include help in a program is as one of the options in the program's main menu. When the user comes across the menu, they will see the help option and they can select it to view the help. The help does not need to cover every minute detail about the program, but rather just explain the objective of the game and detail what keys are used for controls.

:Menu("Some Game","Option 1",1,"Option 2",2,"Help",3
...
:Lbl 3
:Disp "Game Objective
:Disp "Key = Function

Because most people do not like using help unless they have to, you should try to limit your help to one or two screens at most. At the same time, if you have an extremely complex game with all sorts of features and lots of keys are needed to operate it, then it would be appropriate to include help for all of those things. The general guideline is that the amount of help needed correlates to the size of the game.

Protect the User

The next thing you can do to make a user-friendly program is to protect the user from themselves. Often times in a program you will want to think about what could go wrong and try to either prevent it from happening or tell the user what's wrong. Preventing it from happening involves you, the programmer, programming in safety protections for the user so that they aren't even aware that something went wrong.

Say the program calls for the user to type in a number between 1-1000, and the user types in 5000. If your program just goes on with this value, it will probably crash at some point later on. Rather, it's necessary to check the value, and display an error message and ask for the number again if it's wrong. The error message does not need to be complicated or long — just enough so that you can provide some direction on what input you are expecting the user to enter.

:Disp "Enter a Number
:Input "Between 1-1000",A
:While A<1 or A>1000
:Disp "Must Be 1-1000!
:Input "Number",A
:End

Of course, just checking to see that the number is in the appropriate range is sometimes not enough. You might also want to check to see whether the user tried to enter text or a list for input. Because there is no viable way to perform those checks when dealing with a real variable, a better option would be storing the input to a string and performing the validation on it, and then converting the string to a real variable.

Include Helpful Features

Another part of making a user-friendly program is to include helpful features. Since the target audience is often in high school, a feature sure to be appreciated is a "teacher key." This is a special key that the user can use to quickly exit the program. When the teacher comes around, they then want to be able to get back to the home screen so that they don't get their calculator taken away.

This problem is quite easy to prevent with a teacher key. In every program there is a main loop that runs throughout the life of the program. You need to add a check for whatever teacher key you want at the place in the main loop where you check for user input. While you can have any key function as the teacher key, the community standard is usually MODE or DEL. (It is probably best for you to continue this so that users don't have to deal with figuring out which key is the teacher key.)

:While main loop not finished
:Display something
:Perform calculations
:Get user input
:If teacher key pressed, exit program
:End user input
:End main loop

Progress Indicators

In games that use maps, the program has to go through the list of maps and then load the appropriate one for the user to use. Depending on the size and number of maps, this can take a while. If the user doesn't know what is going on, they probably will think the program stalled or something else went wrong.

While there are a couple different ways you can cut down on the loading times for maps (see subprograms and compression), the easiest way to solve the problem is by simply telling the user what is going on and showing the user some progress. You don't have to do anything fancy (in fact, you probably shouldn't because that would just waste valuable memory), just something to help the user understand the situation.

For example, say you are randomly placing mines throughout the map (it's a Minesweeper game), you then could just display a "Placing Mines" message on the screen and have a loop for the progress indicator that matches the current map loading:

:Output(3,2,"Placing Mines
:For(X,1,20
: // fill the map with mines
:Output(4,6,5X
:End

Follow the KISS Principle

The last important point of usability is following the KISS principle. For those who haven't heard of KISS, it is an acronym which stands for Keep It Simple Stupid. The basic point of KISS is to not clutter your program with unnecessary features and useless fluff. It also entails making the program easy to figure out for those who don't have access to a readme.

It is not uncommon to see a TI-Basic math program (i.e., quadratic solver) that has a menu, about screen with scrolling credits, and includes some game in case you somehow get bored solving quadratic equations. While those things by themselves aren't bad, they are completely inappropriate in a math program. There is a certain elegance that comes with "programs that do one thing and do it well." This is known as the Unix philosophy, and should really be what every program strives for.

<< Portability Overview Program Setup >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/usability


Portability
toolbar-separator.png This article is part of the planning stage of the development cycle.

Portability is the ability to run a program on more than one calculator, with little to no changes made to the program — you can literally transfer the program to a calculator, and then start using it. This ability is important because all of the TI-83 series calculators are very similar in TI-Basic support and calculator hardware, so people expect when they find a TI-83 series program it will work on their calculator.

There are five primary things that you need to consider when making a program portable:

  • Making sure not to use assembly programs
  • Making sure not to use new commands (see compatibility)
  • Making sure not to use undocumented functionality (see compatibility)
  • Making sure not to use extra characters
  • The calculator's memory and speed

Assembly Programs

Although assembly programs allow you to make your programs look nice, and to use functionality that isn't normally possible or viable in TI-Basic (such as creating parallax scrolling using xLIB), they are not portable because they need to be compiled to work on each calculator.

This is because assembly programs are programmed in the calculator's own machine language, and use memory addresses that are specific to a particular calculator model. This means, for instance, that a TI-83 assembly library that inverts the graph screen will not work on any of the new TI-83 series calculators.

The TI-83 also uses a different format to run assembly programs than the other TI-83 series calculators: Send(9prgmNAME). This use of the Send( command does not work on any of the other calculators, and in fact will result in a ERR:SYNTAX error. Instead, the rest of the TI-83 series calculators provide three commands — Asm(, AsmPrgm, and AsmComp( — for running and compiling shell-independent assembly programs.

Two additional commands for running assembly programs have been added to the TI-84+ and TI-84+SE calculators: OpenLib( and ExecLib. These can be used for running routines from Flash application libraries that have been specifically written for use with them; the only application so far is usb8x, which is used for interfacing with the USB port.

Apart from use of these last two commands, however, most assembly programs ought to be compatible between the TI-83+/SE and TI-84+/SE

New Commands

With each release of a TI-83 series calculator, TI has added new commands to the calculator. The TI-83+ calculator introduced Archive, UnArchive, and GarbageCollect, which are designed to work with the Flash memory available on the calculator. This is in addition to the assembly commands that were mentioned earlier.

The TI-84+ and TI-84+SE calculators introduced several new time and date commands, some of which use the new built-in clock, while others are used for formatting times and dates; and the aforementioned OpenLib( and ExecLib for running routines from Flash application libraries. The new OS (2.30 or later) also includes some additional commands for statistics: Manual-Fit, invT(, LinRegTInt, and χ²GOF-Test(.

Undocumented Functionality

Along with documented changes, different calculators and OS versions have some undocumented differences. These are given below grouped by the first calculators they occur on:

TI-83+ or higher:

  • Large font on the graph screen — Use the syntax Text(-1, row, column, text) to display text in the large font instead of the typical small font associated with the graph screen.
  • Fast circle drawing — If you put a complex list, such as {i}, as the fourth argument of Circle(, the circle is displayed using its symmetries to only do 1/8 of the trigonometric calculations; this cuts the display time down to only about 30%. This is not available on the color calculators however.

OS version 1.15 or higher:

  • The % Command — The % symbol is an undocumented command that is a useful shortcut for percents — it divides by 100, so it will convert numbers to percentages. For example, 50% will become 50/100 or 1/2, which is just what 50% should be.
  • The sub( Command — If only one argument is given, and it contains an expression that evaluates to a real or complex number or list of numbers, the argument will be divided by 100. A simpler version of the % command above.

TI-84+ and TI-84+ SE:

  • Using the Text( command for small text will sometimes erase the row of pixels below the text (usually not noticeable, when text is displayed on an already-white background). See the command itself for more information.

Extra Characters

At three points in TI-83 series history, TI allowed more characters to be used in TI-Basic. However, this means that if you use a new character, it will not work on older calculator models.

  • First group: This includes the lowercase letters, Greek letters, and international characters. These characters will work with all calculators starting with the TI-83+, but there may be some issues with computer programs such as the TI Program Editor.
  • Second group: The ~ @ # $ & `; \ | _ % characters were introduced only with OS version 1.15 (and will work on all higher versions).
  • Third group: The … ∠ ß x T ← → ↑ ↓ x ∫ √ EFh_LUpBlk.gif F0h_LDnBlk.gif 7Fh_LinvEQ.gif characters and subscripts 0 through 10 were introduced only with OS version 1.16 (and will work on all higher versions).

Calculator Memory & Speed

The TI-83 is the oldest TI-83 series calculator, and it only has 27KB of RAM and a 6MHz processor. A program cannot really even take up the whole 27KB of RAM, since there is the in-game use while running the program. In addition, the 6MHz processor is slower than any of the other calculator processors, so if a game is only marginally playable on the TI-83+SE (with its much speedier 15MHz processor), then there is no way it would even be playable on the TI-83.

This primarily affects large, complex games (like the RPG's made by Kevin Ouellet, among others), but can also affect games that need a lot of speed to be fun. For example, if you have a Mario-like game where you need to keep track of and display multiple enemies on the screen, this can be quite time-consuming on the TI-83. In fact, the game would probably slow to a crawl, and you would spend most of your time waiting for things to load.

This problem doesn't only plague the TI-83, but also the TI-83+. Because the TI-83+ only has 184KB of memory (24KB RAM and 160KB Flash), each of the aforementioned RPG's by Kevin Ouellet would literally take up all of the available memory on the calculator: Metroid II, for instance, takes up over 123KB in Flash, and you need to have several of the almost fifty programs unarchived in order to actually play the game.

The TI-83+ also only has an 8MHz processor (which is just marginally faster than the TI-83's 6MHz processor), while the TI-83+SE and TI-84+SE each have a 15MHz processor. So, if a game is specifically tailored to run on those two calculators (meaning that the speed of the game is just fast enough), there is no viable way that the TI-83+ would be able to run the game at a sufficient speed (even taking into account optimization).

Thoughts to Consider

There are some additional ways that you can avoid portability problems:

  • Use SetUpEditor instead of UnArchive for a list — this is better, and doesn't lose compatibility with the TI-83.
  • If possible, replace all lowercase letters from your program with lowercase stat variables from the VARS>Statistics… menu, or just use uppercase letters everywhere.
  • Instead of using dayOfWk(, use the day of week routine which uses the dbd( command instead.
  • Place all of the calculator specific code into subprograms that the main program calls: one program is your game functions that work on the respective calculators and the other program is the primary all-calculator code for the program.
<< Planning Programs Overview Usability >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/portability


Optimization
toolbar-separator.png This article is part of the revising stage of the development cycle.

A dictionary would define optimization as the process of making something better. In the field of TI calculator programming, it refers to improving code to use less memory, whether as program size or in the size of variables used, or to run faster. It should be your goal, in virtually all cases, to make your programs as optimized as possible.

Line-by-Line Optimization

Optimization techniques fall naturally into two classes. The first, which we'll call "line-by-line optimization", refers to ways of rewriting a line of code, or several lines, so that it does basically the same thing, but is smaller or faster. Typically, each such optimization doesn't have a huge effect. But since many lines can be improved this way, these optimizations add up over the entire program to produce a smaller and faster result.

Read the basic techniques of line-by-line optimization. Then, consult the following pages to see techniques for specific topics:

Alternatively, you can read the optimization walkthrough for a look at applying the optimizations in a real program.

Algorithmic Optimization

An algorithm refers to your method of solving a problem. Algorithmic optimization, then, relies on choosing the best method to solve a particular problem. Unlike line-by-line optimization, even a single optimization of this type can have drastic results — but it also requires critical thinking and a case-by-case approach.

Most programmers, after thinking about the methods they will use for a while, never spend much time on this kind of optimization. It becomes important when you're pushed in a corner: your program has become so large that it doesn't have enough memory to run, or takes half a minute to load each screen.

Identify the bottleneck in your program — what is it that takes up all the memory, or that the program spends so much time doing? Then consider several fundamentally different approaches to solving that particular problem (be it the problem of storing a large matrix or of displaying a tilemap). Write routines implementing each approach, fully optimize all of them, and compare the results. And make sure that you're not missing an approach too radical to think of. Virtually all of the techniques you find in this guide have been discovered by frustrated programmers doing exactly this kind of thinking.

Read the algorithmic optimization tutorial for a demonstration of the process of algorithmic optimization in a real programming situation.

<< Debugging Overview Code Timings >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize


Code Timings
toolbar-separator.png This article is part of the revising stage of the development cycle.

This page documents the speed of certain commands in TI-83 Basic. Although the times given here will vary from model to model and even from calculator to calculator (due to battery levels, free memory, and other factors), one thing that does not change is the relative speed of the commands. So, if you come here to see if a For( loop is faster than a While loop, the information will be useful on any calculator.

Elsewhere on this site, you might see assertions like "foo() is faster than bar()" without any reason or proof. The information on this page is the reason and proof behind them.

Testing Format

In order to be able to compare speed results between commands, there needs to be a common format that is used for all of the tests. However, there are actually two different formats that you can use depending on which TI-83 based calculator you have.

The first format is for those with a TI-83, TI-83+, or TI-83+SE, and it is just a simple For( loop that is executed a set number of times over the command:

:For(n,1,[number]
: <command(s) to be tested>
:End

You measure the time by getting out a stopwatch, and trying to estimate the number of times the run indicator moved. The run indicator is the little, one pixel wide bar in the upper right corner of the calculator that moves when you run a program. Each completed run indicator you count as eight, and then any leftover pixels you simply add to the total.

Of course, because the run indicator moves quite fast, this testing format can be plagued by human error. If you have any second guessing or are unsure if a timing was correct, you should run the test again. You can then take the average of the two times as your result.

The second format is for those with a TI-84+ or TI-84+SE, and it involves using the built-in startTmr and checkTmr( commands. You first store startTmr to a variable (usually a real variable), and then run your command inside of a For( loop. You then check the time with the checkTmr( command using the variable from before that startTmr was stored to.

Here is a basic template to use:

:startTmr→T
:For(n,1,[number]
: <command(s) to be tested>
:End
:checkTmr(T)/[number]

The n variable can be found by pressing [2ND][0][LOG]. This variable has a static memory address, so it won't affect the accuracy of the timings.

Making [number] higher increases accuracy, but takes longer. Also, make sure not to modify the variables n or T inside of the For( loop.

While this format eliminates human error from counting, it's prone to its own faults. A major one is that startTmr and checkTmr( always return whole numbers, but time is continuous. Depending on how close the start and end of the loop were to a clock tick, the number of seconds may be off by up to one second in either direction. This error is greatly reduced by conducting more trials: an error of ±1 second is reduced to ±0.001s per trial by running 1000 trials.

If there is a need to use one or more variables during a test, you should initialize the variables to a known value before running the test. You can do this either on the home screen or before the format code (in which case, you should also put a Pause to separate the variable initialization from the code test). If the code being tested contains and If statement on the fist line, it is highly advisable to add the closing parenthesis to the For( loop.

Contributing your own Tests

Feel free to experiment with code timings, and to put your results up on this page. However, be sure to list the calculator model and the OS version (found in the About menu) that you used! Unless stated otherwise, all tests on this page were done with a TI-83+ and OS version 1.19.

That's it for details and explanations. Now come the actual timings!

Program Main Code

If statements

This very first section is a difficult one to approach, because the nature of our testing method affects it. It turns out that the For( command, when it doesn't have a closing parenthesis after it, will slow down If statements with a false condition inside the loop. This doesn't affect the speed of any other commands (except IS>( and DS<( which are rarely used), nor does this effect occur with a true condition, nor with If-Then-End blocks (just with a single If and a command following it). These two pieces of code will be affected, for instance (the second will be much faster):

:For(I,1,100
:If 0:
:End
:For(I,1,100)
:If 0:
:End

The following table summarizes all of these effects. It would have been too cumbersome to maintain the same format as elsewhere, so the number is simply the total number of pixels.

Conditional type For(A,0,2000 For(A,0,2000)
If 0: 1520 79
If 1: 79 82
If 0:Then:End 80 83
If 1:Then:End 89 91

Conclusion: The ending parenthesis situation, when it is applicable, is a major factor, slowing the statement down nearly 20 times. For this reason, I suggest that if there's any chance at all the condition is false (which is always the case, or else why are you testing for it in the first place?) to leave on the parenthesis on the For( loop. Of course, this doesn't affect If-Then-End commands.

It was long held, because of a misunderstanding of this effect, that If commands were slower than If-Then-End (prior versions of this page were not entirely innocent, either). As you can see, this is not the case, as long as you are aware of the effect shown above. Though there are slight differences in the timings, they are so small that you can ignore them.

Relational Operators

In all programs, there is a lot of chances that you will see relational operators used to determine what to do. But will each of them take the exact same time to work?
Format Bars Pixels Total
= 10 4 84
10 5 85
> 10 5 85
10 5 85
< 10 5 85
10 6 86
and 10 6 86
or 10 6 86
not( 8 6 70
xor 10 5 85

Conclusion: If you can reverse your operations, then do it to save some time.

int( vs. iPart(

As you may know, int( and iPart( have the same use, for positive numbers at least.. In programs where you store more than one variable in 1 number, you normally use int( or iPart(, but which is the best one to use?

Format Bars Pixels Total
iPart(1 10 1 81
iPart(1.643759 10 1 81
int(1 8 7 71
int(1.643759 10 2 82

Conclusion: Unless there are 6 or more decimals, you should consider using int( because of it's speed, but with several decimals, iPart( stays the same so it goes faster.

The getKey Function

I hope you all know the getKey function, it is probably the most used in games and custom menus. It takes time, but we still don't know if it is fast…

Format Bars Pixels Total
Getkey 7 5 61
Getkey→B 11 0 88

Conclusion: getKey is pretty fast, but storing to the variable takes a lot of time. So, if you don't need to have the value of the key pressed, don't store it and use the special variable Ans instead.

For(, Repeat and While Loops

There are many types of loops that you should know already: For(, Repeat and While loop. But if we have the choice, which one is faster?

:For(A,0,2000
:While 0 :End
:End

12 bars +2 pixels (98 pixels)

Also see that with For(A,B,C loops implementation, you can do an If statement:

If B≤C, then C+1→C (at the end)
If B>C, store B into A

:For(A,0,2000
:For(B,1,0
:End
:End

12 bars (96 pixels)
:For(A,0,2000
:Repeat 1
:End
:End

13 bars +2 pixels (106 pixels)

Conclusion: There is one loop that is best. Use the right loop for the task you need to do.

:For(A,0,2000
:End

4 bars +4 pixels (36 pixels)
:Delvar A
:While A≤2000
:A+1→A ;No use of Ans because there should be other code in the loop that would mess up with Ans...
:End

23 bars (184 pixels)
:Delvar A
:Repeat A>2000
:A+1→A ;No use of Ans because there should be other code in the loop that would mess up with Ans...
:End

22 bars +7 pixels (183 pixels)

Conclusion: For the same use, please use a For( loop…

Graphing Code

The pxl-Test( Function

Many TI-BASIC programmers reported issues of when pxl-Test( is a conditional, it takes up to 40% more time.

Format Bars Pixels Total
pxl-Test(15,15 ;pixel turned off 12 1 97
pxl-Test(15,15 ;pixel turned on 12 1 97
If pxl-Test(15,15: Then: (empty line): End ;pixel turned on 20 0 160
If pxl-Test(15,15: Then: (empty line): End ;pixel turned off 18 6 150
pxl-Test(15,15: Then: (empty line): End ;pixel turned on 24 2 194
pxl-Test(15,15: Then: (empty line): End ;pixel turned off 22 7 183

Conclusion: For my calculator, at least, it didn't give me the errors reported by others. So don't use pxl-Test(:If Ans, but If pxl-Test(, it goes faster and takes a byte less. Also, it doesn't matter whether pixel is on or off.

Pixel and Point Modifying

The objective in having games on the 83+ is mostly because it has good graphics that are entertaining. This is why we need to open or close pixels in order to draw. I made my test with a window size of: Xmin=0, Ymin=-62, Ymax=0, Xmax=94

Format Bars Pixels Total
Pt-On(15,-15 14 0 112
Pt-On(15,-15,2 20 1 161
Pt-On(15,-15,3 18 2 146
Pt-Off(15,-15 14 0 112
Pt-Off(15,-15,2 20 1 161
Pt-Off(15,-15,3 18 2 146

Conclusion: So like we see, Pt-On/Off is the same time of execution.

Format Bars Pixels Total
Pt-Change(15,-15 14 0 112
Pxl-On(15,15 9 4 76
Pxl-Off(15,15 9 4 76
Pxl-Change(15,15 9 4 76
Line(15,-15,16,-15 16 2 130
Line(15,-15,30,-15 32 6 262
Line(15,-15,30,-15,0 34 6 178
Horizontal -15 82 5 661
Vertical 15 60 3 483

Conclusion: Line(, Horizontal and Vertical are all slow, but they can save bytes. If there are under 4 or 5 pixels to turn on, Pxl-On( works much faster than any of them. However, if you have a lot of pixels to turn on/off, it is much better to use them than the Pxl-/Pt- commands. Also, Pt-Change( is the same speed wise as Pt-On/Off.

Text( vs. Output( vs. Disp(

In all your programs, there is probably something that displays text on the screen. There are many ways to do so, so I will look at them to see which one is faster. The codes will be displaying the same string, "I DIE!", so that I can give you valuable timings. In order to find the timing of display, ClrHome is after all of the commands.
Format Bars Pixels Total
Text(-1,16,12,"I DIE! 54 4 436
Text(16,12,"I DIE! 41 1 329
Output(3,2,"I DIE! 37 6 302
Disp "I DIE! 51 2 410

Conclusion: For immobile text, if you need to be big, you should use Output(, but if you need it into graph screen, then think about the time it takes…

Format Bars Pixels Total
Output(3,2,A 16 6 134
Text(-1,16,12,A 36 7 295
Text(16,12,A 27 0 216

Conclusion: For variables' values, same thing applies.

Optimizing your Code

Parentheses and Quotes

Normally, you shouldn't close parentheses and quotation marks to save a byte. I will test if it goes faster.

Format Bars Pixels Total
Output(3,2,"I DIE! 20 6 166
Output(3,2,"I DIE!" 20 6 166
(5+6)→B 13 6 110
(5+6→B 13 5 109
5+6→B 13 2 106

Conclusion: The only reason you need to get out the quotations marks are because you save 1 byte, you don't get faster. Also, taking off closing parenthesis goes faster. However, it is better if you can get rid of the parentheses entirely.

Multiplication, Division and Addition

Most TI-BASIC programmers tell you not to put the multiplying * sign, but do they know if it goes faster?
Format Bars Pixels Total
A*B 13 4 108
AB 13 2 106

Conclusion: If you multiply, don't put the * sign.

Format Bars Pixels Total
If AB: Then: (empty line): End ;Condition true 20 5 165
If A and B: Then: (empty line): End ;Condition true 20 5 165
If AB: Then: (empty line): End ;Condition false 18 7 151
If A and B: Then: (empty line): End ;Condition false 19 2 154

Then you could possibly use the AB format because there is 1 byte less and no speed loss and if the condition is mostly false, AB goes faster…

Format Bars Pixels Total
If C+B: Then: (empty line): End ;Condition true 20 6 166
If C or B: Then: (empty line): End ;Condition true 20 6 166
If C+B: Then: (empty line): End ;Condition false 19 3 155
If C or B: Then: (empty line): End ;Condition false 19 7 159

Same as for the last tests, but you don't save any space.

Format Bars Pixels Total
If A(C+B: Then: (empty line): End ;Condition true 25 4 204
If A and (C or B: Then: (empty line): End ;Condition true 25 1 201
If A(C+B: Then: (empty line): End ;Condition false 23 4 188
If A and (C or B: Then: (empty line): End ;Condition false 23 7 191

Conclusion: So as we can see, in multiple conditions, where it should be true a lot of time, you should use the and and or operators instead of multiplication and addition.

Format Bars Pixels Total
A/B 20 6 166
AB^-1 28 2 226
The following timings were taken on a TI-84+ SE with OS version 2.40
Format Bars Pixels Total
1/B, when B=1 15 0 120
B^-1, when B=1 14 1 113
1/B, when B=pi 20 2 162
B^-1, when B=pi 19 2 154

Conclusion: When dividing two numbers, don't use the ^-1 operation. It goes really slow! But if you're only taking an inverse, use the ^-1 operation instead of dividing from 1.

Variables

Some variables types are supposedly faster than others. Let's find out!

Format:
1→_
ClockOn
startTmr→C
For(T,1,E5
_
End
Disp checktmr(C)/E5

Variable Time
N 0.00275
Xmin 0.00275
N 0.0321
Ans 0.0321
[A](1,1 0.00328
L1(1 0.00385
Str1 0.00385
Ans(1 0.00482

Conclusion: Use Finance Vars! Although, it is your choice: a 2 byte, really fast variable (i.e., the finance variables) or a 1 byte, slow variable (i.e., the real variables). Also, just because Ans wasn't any faster, doesn't mean you shouldn't use it! It can make your code a lot smaller, and may be faster in some situations.

Recalling Lists

As you know, lists are arrays of variables, that you can modify specifically, one by one. You can use pre-defined lists, such as ∟1, ∟2, …, ∟6, and user-defined lists, LXXXXX where X represents any letter or number or nothing at all (except for the first character). It takes time recalling an element, but how much?

Format Bars Pixels Total
\L1\ 13 6 110
\L1\(1 15 0 120
\L\A 15 3 123
\L\A(1 16 6 134
\L\AA 15 5 125
\L\AAA 15 4 124
\L\AAAA 16 2 130
\L\AAAAA 16 2 130
A 9 6 78

Conclusion: If you can, use pre-defined lists as temporary buffer, but not for long-term storage, it is so easy to get it modified in a math class. And if you can, use real variables instead of lists if you have very few elements and that the data storage is not long-term.

Imaginary vs. Decimals

If you have looked in some tutorials, they talk about having many different variables held in one variable, by using either imaginary numbers in rectangular form (A+Bi), or decimal points (XX.YYMMDDNNIIJJ). It saves space for keeping track of saved games, and sometimes time if you use it correctly. But which ways are the fastest?

Format Bars Pixels Total
real(4+4i)+imag(4+4i 23 4 188
real(4+4i 14 6 112
imag(4+4i 14 6 112
int(4.4)+10fPart(4.4 15 2 116
int(4.4 8 6 70
10fPart(4.4 11 1 89

Conclusion: If you can, try not to use imaginary rectangles, they are slower than their int( and fPart( equivalent and they store the exact same amount of data. Besides that, a complex variable is twice as big as a real variable, and if you use one in a list it will make even the real elements twice as big.

Calculating powers of 10

The calculator has at least three ways to calculate some power of 10: using the small E command (limited to integer powers), using the 10^( command, and typing out 10^. How do these compare?

Format Bars Pixels Total
E1 6 6 54
10^1 9 0 72
10^(1 12 4 100
E99 6 7 55
10^99 50 6 406
10^(99 12 6 102

Conclusion: The E command wins out by far, but it's limited, so you can't always use it. In those cases, typing out 10^ is slightly faster than the 10^( for small arguments (the breaking-even point seems to be around 10^9), but is a lot slower for large arguments. Of course, there's also the size to consider, so the command seems to be a pretty safe bet.

IS>( vs. If command

This is what happened when I compared IS>( to If conditionals:

Format Bars Pixels Total
IS>(B,10):Disp 24 2 194
If B>10:B+1→B:Disp 34 3 275

Conclusion: IS>( works faster, but its flaws might not make it very useful.

Alternate methods

getKey routines

These are two different methods of moving an X on the homescreen.
Darkstone Knight's alternate method. (123 bytes, 12 bars, 7 pixels, 103 pixels total)

:ClrHome
:1.01→A
:For(D,0,200)
:getKey
:If Ans
:Output(iPart(A),(smallcapitalE)2fPart(A)," /one space/
:A+(Ans=34 and A<8)-(Ans=25 and A≥2)+sub((Ans=26 and fPart(A)<.16)-(Ans=24 and fPart(A)>sub(1→A
:Output(iPart(A),(smallcapitalE)2fPart(A),"X
:End

and the original method using piecewise expressions. (109 bytes, 13 bars, 104 pixels total)
:ClrHome
:1→A
:1→B
:For(D,0,200)
:getKey→C
:If C
:Output(A,B," /one space/
:A+(C=34 and A<8)-(C=25 and A>1→A
:B+(C=26 and B<16)-(C=24 and B>1→B
:Output(A,B,"X
End

So which one you use depends on your value of 1/200th of a pixel per iteration vs. 14 bytes of size.

<< Optimization Overview Writing Program Documentation >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/timings


Releasing Your Program
toolbar-separator.png This article is part of the releasing stage of the development cycle.

Many programming guides give you excellent advice on programming, but stop at the point when the program is finished, tested, and optimized. After all, most people can manage to release a program somewhere, one way or another. But in reality, an inexperienced programmer may well release his work quietly and in an unassuming form, which people will simply glance over without stopping. This tutorial will tell you how to avoid this, and make your program get all the attention it deserves.

Where to Release

First, it's important to know where to go to upload your program to the Internet. Although you might want to create your own website and release all your games there, that alone will not get your program noticed. Sure, having your own site might get you some publicity, but the best way to get your game noticed is by releasing it at one (or all!) of the large program archives.

Of these, ticalc.org is by far the largest (and most popular), but it's also likely you'll spend longer waiting for your program to be put up there. With CalcGames and United-TI, you only have to wait a day or two. With TI-Basic Developer, you only have to wait a few minutes, or you could do it yourself.

What to Release

There's more you'll want to submit than just the program itself. Here are the elements you'll want to put together — some of these are called optional by the file archive websites, but they are mandatory if you want the program to be successful.

The program itself (obviously)

If you were programming on the calculator, you'll need to transfer the program to your computer to submit it. You'll need a calculator-to-computer cable, and software such as TI-Connect. If you don't know where to get these, or have problems using them, see linking.

Now, you have one or more files from your calculator on the computer. If there's only one, you're good to go. If there are several files involved, you should consider combining them in a group file (usually .83g or .8xg). Or keep them like they are, but then make sure to mention what each file is for, in the readme.

Although, if you don't want to worry about having to ungroup, or group the files, another option for monochrome calculators is Basic Builder. Basic Builder packages your programs, in an app. More information, is given at this page.

The readme

A critical step in submitting a program. Make sure to read our tutorial on writing a readme if you've never done it before (and possibly even if you have). Usually, longer is better than shorter (it's worse if someone doesn't understand how your program works, than if they have what they already know explained to them again) — unless it's a five-act play, in which you might consider removing the nonessentials. Generally, the longer and better your program, the longer your readme can be; you don't need any more than the minimum for, say, a quadratic solver. For a huge program, a 2-4 page plain text file is appropriate.

Also, please don't make the readmes in Microsoft Word 7 file format! A .txt file is sufficient, and in fact recommended. However, if you're just itching to put screenshots, pictures, and format your whole paragraph accordingly, a .pdf file would be a good idea. PDF files can be read by most computers automatically, but if not, Adobe reader, is free. It might be a good idea, to put a file with a link to an adobe download station. Most likely http://get.adobe.com/reader/ will be the link to get adobe reader. You might also want to mention that it's free. Make sure you have that .txt file that gives the information on where to find adobe.

The screenshot

All four websites listed above let you add a still or animated screenshot of your program. This is very easy to do — see the making a screenshot page — and goes a long way toward making your program look good (if it actually is good). An attractive screenshot will encourage visitors to download your program more than the most flowery prose. Show your program at its most impressive here.

Getting a screenshot is easy using TI Connect. In 1.7 and 1.6, the screenshot button should look like a camera. Click it.

The title

The title will tell visitors what your program is all about. One common mistake is making the title the same as the 8-character name of the program. Don't do this — the title is the first thing people will see, and you want to make it clear. Of course, if the program is called prgmTETRIS it's okay to call it Tetris (though Grayscale Tetris, if that's the case, could be even better). But if the program is called prgmQUADSOLV, please make the title Quadratic Solver instead!

The description

Don't forget this! It should have three parts:

  • What the program is about. "Solves all quadratic equations over the complex numbers."
  • The program's best qualities. "A grayscale interface at the low size of 13 bytes!"
  • Any requirements. "Requires xLIB, Omnicalc, Symbolic, and DAWG to work correctly. Also, create and unarchive GDB7."

The first two parts are positive; the third is negative, but necessary (imagine if your program crashes without warning if GDB7 is not created. 99% of your users will be lost, even if this is explained in the readme, and write negative reviews). You want to make this section as short as possible, and the best way to do this is to avoid the requirements in the first place. Even if your game is in the "games for xLib" category, the one who is looking for a game might not see this, and not download, or install xlib.

Putting this together

The program and the readme should be combined in a .zip archive: this is a community-wide standard. The file upload form (this is different for all websites, but contains the same basic information to be entered) should have fields where you can submit everything else. You might also consider adding the screenshot to the .zip archive, in addition to its normal location.

Here are the links to the file upload forms of all the websites mentioned on this page.

Note: You need to create an account at the respective website before you can upload files there.

Marketing

Marketing your program can start as early as when you first get the idea for your program, although many people won't take you seriously until you have at least a basic engine to show for your efforts. Other good points at which to advertise the program include a beta-testing period before you release it to the masses, and of course when it's finally released. For more marketing tips, see our marketing tutorial.

<< Marketing Overview Creating New Program Versions >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/releasing-your-program


Algorithmic Optimization

This page is pretty good describing the process of finding better algorithms.

http://tibasicdev.wikidot.com/algorithmic-optimization

Optimization

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/pages:algorithmic-optimization


Optimization: Conditionals

Use If conditionals when you only want to execute the one command on the next line.

:If A=1
:Then
:C+2→C
:End

can be

:If A=1
:C+2→C

Because conditionals are generally slow, you should replace them with piecewise expressions if you are just changing a variable. You take the variable and add or subtract the expression, multiplying it by the value that you are adding to the variable. Using piecewise expressions can sometimes be slower than If conditionals to avoid storing zero into the variable if the expression is false.

:If A=3
:B+2→B

can be

:B+2(A=3→B

You don't need to put the value in front of the expression when it is one.

:B+1(A=2→B

can be

:B+(A=2→B

You can take piecewise expressions a step further by combining multiple If conditionals that deal with the same variable and put them into one piecewise expression.

:If A=3
:B+5→B
:If A=6
:B-3→B

can be

:B+5(A=3)-3(A=6→B

If you are adding and subtracting the same value from the variable in the piecewise expression, you can factor the common value from each expression. This works best when you are adding and subtracting a big number.

:B+11(A=1)-11(A=2→B

can be

:B+11((A=1)-(A=2→B

You can sometimes reorder a list of If conditionals so that the last possible outcome doesn't even need an If conditional. This mainly works when the program is going to do a certain action and there are no other alternative actions that can occur.

:If not(A
:Goto A
:If A>0
:Goto B
:If A<0
:Goto C

can be

:If A<0
:Goto C
:If A
:Goto B
:Goto A

If-Then-End conditionals should be used when you want to execute multiple commands.

:If A=1
:C+1→C
:If A=1
:D+1→D

can be

:If A=1
:Then
:C+1→C
:D+1→D
:End

If you have two or more If conditionals that have a common expression, you should take the common expression out and make it into an If-Then-End conditional and nest the If conditionals inside it.

:If A=1 and B=1
:C+2→C
:If A=1 and B=2
:D+1→D

can be

:If A=1
:Then
:C+2(B=1→C
:D+(B=2→D
:End

If you are displaying lots of text based on If conditionals, you should put the text together and then just use the sub command to get the appropriate part of the text. This will display the text if none of the conditions are true, so this may not always be desired.

:If A=3
:Disp "Hello
:If A=4
:Disp "World

can be

:Disp sub("HelloWorld",1+5(A=4),5

The If-Then-Else-End conditionals should be used if you want to execute multiple commands when an expression is true or false. Instead of putting two If-Then-End conditionals that have math opposite expressions, If-Then-Else-End conditionals are faster because you don't need to do two checks; only one of the conditionals can be true at one time.

:If B
:"Hello→Str1
:If not(B
:"Goodbye→Str1

can be

:If B
:Then
:"Hello→Str1
:Else
:"Goodbye→Str1
:End

When using an If-Then-Else conditional and only one command is executed if the expression is true or false, use an If conditional between the two commands instead. You might also have to change the order of the commands, depending upon the commands.

:If B
:Then
:"Hello→Str1
:Else
:"Goodbye→Str1
:End

can be

:"Goodbye→Str1
:If B
:"Hello→Str1

When a line is either drawn or erased depending on a condition, you can put that condition as the optional fifth argument for the Line command.

:If B:Then
:Line(1,2,3,4
:Else
:Line(1,2,3,4,0
:End

can be

:Line(1,2,3,4,B

When you have a If-Then or If-Then-Else conditional that has a Goto command as one of the nested commands, you can sometimes remove the conditional and replace it with multiple If conditionals. Doing this prevents a memory leak from happening.

:If A
:Then
:Disp "Hello
:Goto A
:Else
:Disp "Goodbye
:B+2→B
:End

can be

:If A
:Disp "Hello
:If A
:Goto A
:Disp "Goodbye
:B+2→B

If you have If:Then:End statements with an "End" at the end of the program, the End can be removed.

:If randInt(0,1
:Then
:Disp "Heads
:Else
:Disp "Tails

However, if the last line returns a value, it will show up on the home screen after the program ends.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-conditions


Optimization: Deleting Variables

Instead of setting number variables to zero (to delete them), use the DelVar command. DelVar works with all of the variables, and the calculator automatically sets the variable to zero the next time it's used. However, DelVar is also slightly - so for repeated resetting, it is often faster store 0 to the variable.

:0→A
can be
:DelVar A

The DelVar command doesn't need a line break or colon following the variable name. This allows you to make chains of variables.

:DelVar A
:DelVar B
can be
:DelVar ADelVar B

Besides making chains of variables, the DelVar command also allows you to take the command from the next line and put it immediately after the last DelVar command.

:DelVar A
:Disp "Hello
can be
:DelVar ADisp "Hello

The only exception is with the Lbl command. Don't put the Lbl command immediately after a DelVar with this optimization, or else the label will be ignored. For instance, the following code exits with ERR:LABEL:

:DelVar ALbl 0
:Goto 0

Even though the ClrList command exists for clearing lists, DelVar should be used instead.

:ClrList L1
can be
:DelVar L1

There is a drawback to using Delvar for Lists. If you use Delvar L1 instead of ClrList L1, L1 will disappear from the list editor. This can easily be remedied outside of the program, but inexperienced calculator users who execute your program and then need to view the list that was used by your program may not know how to do this.
Furthermore, ClrList L1 is 1 byte smaller than Delvar L1.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-deleting


Optimization: Exiting Programs

Although the Return and Stop commands can both be used for exiting programs, Return should be used instead of Stop. While Return stops only the current program and allows the parent program to continue running, Stop causes all of the programs to stop and then returns the user to the homescreen (unless called from an Assembly program).

:ClrHome
:Disp "Hello
:Stop
can be
:ClrHome
:Disp "Hello
:Return

You don't have to use Return or Stop if you can organize the program so that it just naturally quits. If the calculator reaches the end of a program, it will automatically stop executing.

:ClrHome
:Disp "Hello
:Return
can be
:ClrHome
:Disp "Hello

When you have a display command that displays text as the last line of the program, you can remove the command and just put the text. This text will be displayed instead of the "Done" message that is normally displayed after a program finishes executing.

:ClrHome
:Disp "Hello
can be
:ClrHome:"Hello

Even though you don't display any text as the last command, you may still want to get rid of the "Done" message. You can do this by putting a single double-quote as the last line of the program.

:ClrHome
can be
:ClrHome:"

If you modify the Ans variable on the last line of the program, Ans's new value will be displayed instead of the "Done" message.

:ClrHome
:For(A,1,5
:B+A→B
:End
can be
:ClrHome
:For(A,1,5
:B+A→B
:End
:B

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-exiting


Optimization: Logic and Relational Operators

Because the calculator treats every nonzero value as true and zero as false, you don't need to compare if a variable's value is nonzero. Instead, you can just put the variable by itself.

:If C≠0
can be
:If C

Instead of comparing a variable to zero, use the not( logical operator. Because not( returns the opposite value of the variable, true will become false and false will become true.

:While A=0
can be
:While not(A

When making expressions that combine the and and or operators where the and operator comes first, you don't need to include parentheses around the and operator. The and operator has a higher precedence than or, so it is evaluated first. This can become complicated with complex expressions, so you might want to leave some of the parentheses for clarity.

:If (A=1 and B=2) or (A=2 and B=1)
can be
:If A=1 and B=2 or A=2 and B=1

If you are comparing two unary expressions (expressions with no comparison operator) with the and operator, you don't need the and operator. For and to be true, both values must be nonzero. So, multiplying them will produce the same effect because if either one of the values is zero, the product of both values will also be zero.

:If A and B
can be
:If AB

A similar technique can be applied to expressions with comparison operators, except some restrictions are required.
With unary expressions, to test If A and B is true you multiply them. With equations, you can multiply the left sides of each together and you can do the same for the right sides. However, a value being 0 could return a different result than anticipated, so it is best to use this technique when the values are not 0.

:If A=B and C=D
can be
:If AC=BD

As and is similar to multiplying, the or operator is similar to addition. Adding two values together yields a non-zero result if one of the conditions is true. When you are comparing equations using the or operator, you can add the two together (This is not used for unary expressions because the plus symbol and or symbols are both one-byte tokens). For this the only restriction is that all values must have the same sign (or be 0), or you can circumvent this by using abs(. This is necessary because if two variables have the same value except one is negative, this expression could return false.

:If A=B or C=D
can be
:If A+C=B+D

The most unused logical operator is xor (exclusive or). The xor operator is useful when comparing two expressions and checking if one but not both are true. In fact, xor is specifically designed for this purpose.

:If A=2 and B≠2 or A≠2 and B=2
can be
:If A=2 xor B=2

Many times a compound expression can be shortened by combining expressions that have the same meaning or replacing expressions that can be written another way. Think about what the expression means and then think about how to make a shorter equivalent expression. There are many ways of writing an expression, so there are usually ways to rewrite it.

:If A>B or A<B
can be
:If A≠B

If you have the not( operator around an expression, you can usually change the logical operator to the math opposite. This allows you to remove the not( operator.

:If not(B=C and A=D
can be
:If B≠C or A≠D

DeMorgan's Law can be used for expressions in which the not operator is around two separate unary expressions joined by the and or or operators. It allows you to remove the second not operator and then change the and to or and vice versa.

:If not(A) and not(B
can be
:If not(A or B

Min is useful when you are comparing one variable or value to several other variables to see if they are all equal to the variable or value. To use min( you just create an expression with the min( function and put the common variable or value inside it followed by an equal sign and a left curly brace. You then list out the variables that you are comparing the variable or value to, separating each one with a comma.

:If A=10 and B=10 and C=10
can be
:If min(10={A,B,C

Max( is useful when you are comparing one variable or value to several other variables to see if at least one is equal to the variable or value. You do the same thing as the min( function, just replacing min with max.

:If A=10 or B=10 or C=10
can be
:If max(10={A,B,C

You can put a comparison operator inside the min( or max( functions to compare when several values or variables are equal to one variable and several values or variables are equal to another variable. This works especially well with three or more variables.

:If A=X and B=U or A=Y and B=V
can be
:If max(A={X,Y} and B={U,V

Abs( is useful when you are comparing a variable to two even or odd values using the or operator. You subtract the larger value from the smaller value, divide the result by two, and then put it on the left side of the equal sign. Next, you subtract the larger value by the result on the left side of the equal sign, and then take the variable being tested and subtract it by that value. You then put the abs( function around the result and place the expression on the right side of the equal sign.

:If A=45 or A=105
can be
:If 30=abs(A-75

X=n1 or X=n2 should become abs(n1-mean({n1,n2}))=abs(X-mean({n1,n2})) (simplified) if n1 and n2 are positive integers and n1+n2 is even. If there are three terms, then see if you can simplify two of them according to this rule. If you can't, then a string of or's will be faster than the max(X={n1,n2,… approach. If there are four terms or more, then use max().

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-logic


Optimization: Loops and Branching

When using loops you want to make them as compact as possible. This starts with moving invariant code outside the loops. You only want loops to contain expressions whose values change within the loops. If something only happens once, it should be outside the loop.

:For(X,1,5
:5→Y
:Disp X
:End
can be
:5→Y
:For(X,1,5
:Disp X
:End

You also want to minimize the calculations inside loops. This not only includes cutting down on the number of storages, but how often variables are used and what they are used for. This can increase the size, however.

:For(X,1,10
:A+length(Str1→A
:End
can be
:length(Str1→B
:For(X,1,10
:A+B→A
:End

Another way to minimize calculations inside loops is to use constant increments. This makes the loop faster, but it also makes it larger.

:For(X,0,10
:Disp 10X
:End
can be
:For(X,0,100,10
:Disp X
:End

You should combine two or more loops that are in close proximity if they use the same number of iterations and don't affect each other. Combining loops may take some ingenuity.

:For(X,1,10
:B+X→B
:End
:For(Y,1,10
:A+A/Y→A
:End
can be
:For(X,1,10
:B+X→B
:A+A/X→A
:End

Loop unrolling reduces the number of times you check the condition in a loop, with two or more of the same statements being executed for each iteration. If the loop is small enough, you can even unroll the whole loop. This will usually increase the size but also make it faster.

:5→dim(L1
:For(X,1,5
:2A→L1(X
:End
can be
:5→dim(L1
:2A→L1(1
:2A→L1(2
:2A→L1(3
:2A→L1(4
:2A→L1(5

For( loops are best used when you know how many times the loop will be executed. Because the fourth argument is optional (one is the default), you should always try to leave it off.

:For(X,1,8,1
:End
can be
:For(X,1,8
:End

You can sometimes rewrite For( loops and the commands inside them so you can remove the fourth argument.

:For(X,8,0,-1
:Disp X
:End
can be
:For(X,0,8
:Disp 8-X
:End

If you have an If conditional around the outside of a For( loop, you should see if there is a way to combine it with the For( loop using Boolean logic.

:If A>10:Then
:For(X,1,50
:End:End
can be
:For(X,1,50(A>10
:End

One of the common uses of For( loops is to slow programs down. Instead of For( loops, you should use rand(# or If dim(rand(#. Both of these create lists of random numbers, with a larger number meaning a larger delay; the second one preserves the Ans variable as well.

:For(X,1,75
:End
can be
:rand(25

This method generally works well for small delays, but it is better to use For( loops for large delays. This is because the rand(# technique is limited by the RAM storage availability, and has a maximum delay of 999 (being a list variable).

:rand(200
can be
:For(X,1,600
:End

Repeat loops will loop until the expression is true, and While loops will loop while the expression is true. Repeat loops are tested at the end of the loop which means they will be executed at least once. This allows you to not always have to set the variables in the expressions, which is the case with While loops. If the expression in a While loop is false before it is tested, the loop will be skipped over. This is sometimes desired if the expression fits that format.

:DelVar A
:While not(A
:getKey→A
:End
can be
:Repeat A
:getKey→A
:End

If you need a loop that loops forever (i.e., an infinite loop), use Repeat 0 or While 1 instead of Goto/Lbl.

:Lbl A
:Disp "Hello
:Goto A
can be
:Repeat 0
:Disp "Hello
:End

Goto/Lbl loops should be used sparingly. When Goto is encountered, it notes the Lbl and proceeds to search for it from top to bottom in the code. This can really be slow if the Lbl is deep within the program. It also has the tendency to make your code harder to follow and maintain. And, if you use a Goto to exit a loop or a conditional that uses an End command, it can lead to memory leaks (causing your program to crash).

:Repeat 0
:getKey→B
:If B
:Goto A
:End
:Lbl A
can be
:Repeat B
:getKey→B
:End

When all a For( loop does is store expressions to a list, you can replace it with a seq( (sequence) command. The sequence command can also be used with other variables.

:5→dim(L1
:For(X,1,5
:2A→L1(X
:End
can be
:seq(2A,X,1,5→L1

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-loops


Optimization: Math Operations and Keys

Multiplication signs are unnecessary and should be removed because the calculator does implicit multiplication. You should remember that implicit multiplication doesn't bind tighter than regular multiplication.

:5*A→B
can be
:5A→B

You don't need to put parentheses around a single variable or number by itself when doing multiplication or division.

:3/(A)
can be
:3/A

Multiplication and division have the same importance based on the order of operations (the rules that determine what order things are evaluated in), so they will be evaluated from left to right if both appear in an expression. If multiplication appears before division, you can remove the parentheses around an expression.

:A+(BA)/5→C
can be
:A+BA/5→C

Although multiplication and division have the same importance in order of operations, multiplication is in fact faster than division when doing math operations. So, you should multiply instead of dividing, especially if doing the multiplication is smaller than doing the division.

:(X+1)/2
:(B+C)/D
can be
:.5(X+1
:Dֿ¹(B+C

When adding a negative number to a positive number, switch the two numbers around and change the addition to subtraction. This allows you to get rid of the negative sign.

:-A+B→C
can be
:B-A→C

You can often times rewrite math expressions using the built-in keys and characters. When you have a number that has two or more zeros, it may be smaller to write it using the the little E character (which is designed for scientific notation). This character will multiply the number on its left (1 if no number is given) times 10 to the number given on the right.

:50000
can be
:5E4

If you want to use a variable to set the exponent of a number, you would have to use 10^X because the calculator doesn't allow ᴇX. This can be replaced with the 10^( key. This also applies to the e^( key, the 2 key, and the 3 character.

:10^A+e²-5²+9³
can be
:10^(A)-52+93+e^(2

If you have a fraction that has one as the numerator, you can replace it with multiplying the denominator by the ֿ¹ key.

:1/16
can be
:16ֿ¹

When you have a fraction that has an expression in the numerator that has parentheses around it and a variable in the denominator, you can sometimes eliminate the fraction by multiplying the variable by the ֿ¹ key and multiplying it by the expression from the numerator.

:If (A+B)/C
can be
:If Cֿ¹(A+B

If you raise a variable or value to some fractional power with one in the numerator, you can just take the denominator of the fractional power and then multiply it by the xroot character and the variable or value.

:A^(1/B
can be
:Bx√A

Always do all the operations you can ahead of time. This eliminates some of the operations that the calculator has to do.

:33+A(8/2→B
can be
:33+4A→B

Write and calculate expressions in one step instead of several steps.

:2BC→D
:3A→E
:D+E→F
can be
:2BC+3A→F

One of the basic math rules is that multiplying one times any variable is equal to the variable. So, you don't need to put the one in front of the variable.

:1A+3→B
can be
:A+3→B

When adding two variables of the same type together, you should add up the number of times the variable appears and multiply that value by the variable.

:A+3A→B
can be
:4A→B

Rewriting division with multiplication is useful when multiplying is smaller. You take the denominator and then change it to the equivalent for multiplication.

:(X+1)/10
can be
:.1(X+1

The distributive identity should be used when you have three or more variables that share a common number or variable. You take that common number or variable out and distribute it to all of the variables.

:CA+CB+C²→D
can be
:C(A+B+C→D

The multiplicative inverse identity is used when you have an expression where the same variable or value is in the numerator and denominator. You can remove the variable or value because it is canceled out.

:2A/(2BA
can be
:1/B

When you have a fraction that has a fraction as its denominator, you can sometimes use the division inverse identity. If the numerator of the first fraction is one, you can flip the second fraction causing the first fraction to disappear.

:1/(4/A
can be
:A/4

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-math


Optimization: Putting Ans Into Practice

The Ans variable (last answer) is a temporary variable that can hold any variable. Ans is changed when there is an expression or variable storage or when pausing with the Pause command. It is mostly useful when you are just manipulating one variable. To use Ans just put an expression on a line by itself; it will automatically be stored to Ans. You can then change the expressions on the next line where the variable was called and put Ans there instead. Ans is faster than normal variables, but slower than Finance/Window variables and constants.

:getKey→A
:B+(A=26)-(A=24→B
can be
:getKey
:B+(Ans=26)-(Ans=24→B

If you have more than one line that calls the variable, you should just keep the variable. However, for the first line that calls the variable you should change the variable to Ans.

:getKey→A
:B+(A=26)-(A=24→B
:C+(A=34)-(A=25→C
can be
:getKey→A
:B+(Ans=26)-(Ans=24→B
:C+(A=34)-(A=25→C

When there is a common expression that is on multiple lines, it is sometimes smaller to put the expression on its own line and then change the expression on the other lines to Ans.

:30+5A→B
:Disp 25A
:Disp 30+5A
can be
:30+5A→B
:Disp 25A
:Disp Ans

When you use the same text many times in close proximity, you should put that text on its own line and replace it with Ans wherever it occurs.

:Disp "Hello
:Disp "Hello
:Disp "Hello
can be
:"Hello
:Disp Ans,Ans,Ans

For complex calculations, there are often multiple parts that are the same. You should take out the most common part and put it on its own line. If there are several common parts, you should take out the part that will result in the greatest size reduction. You then replace that part, wherever it occurs, with Ans.

:2A/(BC)+(BC)2→A
can be
:BC
:2A/Ans+Ans2→A

When dealing with text there are often situations where the same text is repeated multiple times. Rather than writing out the long string of text, it is sometimes possible to rewrite it using Ans. Put the common part of the text on its own line and on the next line concatenate (add together) with Ans however many times is needed to make the string.

:"                     →Str1 //20 spaces
can be
:"      //5 spaces
Ans+Ans+Ans+Ans→Str1

If you use the sub( command to get the appropriate part of some text based on certain conditions, you can sometimes get rid of the sub( command and just use Ans. You would put each piece of text on its own line, and then put the condition before it.

:Input sub("GiveTake",1+4(A=1),4)+" candy?",Str1
can be
:"Give
If A=1:"Take
Input Ans+" candy?", Str1

With Repeat loops, you can sometimes put Ans in the condition instead of the variable. Even if Ans were 0 at the beginning of the loop, the code will work, since a Repeat loop will always cycle once before the condition is checked.

:Repeat A
:getKey→A
:End
can be
:Repeat Ans
:getKey→A
:End

When the condition in a Repeat loop has a common part that is repeated multiple times, you should put the common part at the end of the loop and replace the common part in the condition with Ans.

:Repeat A=2 and B=1 or A=2 and B=3
:getKey
:A+(Ans=26)-(Ans=24→A
:End
can be
:Repeat Ans and B=1 or Ans and B=3
:getKey
:A+(Ans=26)-(Ans=24→A
:A=2
:End

Many times in If-Then-Else conditionals the same expression or string of text appears in both the true and false parts. You should put this expression or string of text before the If-Then-Else conditional and then replace it in the conditional with Ans.

:If B
:Then
:Disp "Hello
:2Bnot(A→C
:Else
:Disp "Hello
:3→D
:End
can be
:"Hello
:If B
:Then
:Disp Ans
:2Bnot(A→C
:Else
:Disp Ans
:3→D
:End

When you have two or more strings of text that share a common part, you should take that common part out. You then can replace it with Ans and concatenate Ans to the strings.

:Disp "Hello World
:Disp "Goodbye World
can be
:"World
:Disp "Hello "+Ans
:Disp "Goodbye "+Ans

When you have two If conditionals that have math opposite conditions and they display text, it is sometimes possible to remove one of the conditionals and use Ans. Take the text from the first condition and put it on its own line. Then put the second conditional and the text on the next line. You then put the display Ans on the last line.

:If A≤B
:Disp "Higher
:If A>B
:Disp "Lower
can be
:"High
:If A>B
:"Low
:If A≠B
:Disp Ans+"er

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-ans


Optimization: Storing Variables

Although it is common to initialize variables for planned use, you should avoid initializing variables that you don't need or that are initialized further down in the program. The reason is because storing to variables really slows a program down (especially inside loops) and there is no point in initializing a variable twice.

:2→A
:If B
:Then
:2→A
:Else
:-2→A
:End
can be
:If B
:Then
:2→A
:Else
:-2→A
:End

When a number is used many times in a program, you should store it to a variable and then just call the variable instead of writing it out every time. This also applies to text that should be put in a string.

:Disp "Hello
:Disp "Hello
:Disp "Hello
can be
:"Hello→Str1
:Disp Str1,Str1,Str1

You can also put common variables or expressions in a string variable and then use the expr( command to reference them. This can be used in conjunction with other variable commands. This also gives you more variables to use.

:Disp 5int(B/7
:Disp 5int(B/7
can be
:"5int(B/7→Str1
:Disp expr(Str1
:Disp expr(Str1

You should reuse variables that have no specific function or that don't need to be saved.

:For(X,1,100
:End
:For(Y,1,50
:End
can be
:For(X,1,100
:End
:For(X,1,50
:End

When storing the same large number in two or more variables, you should store the large number in the first variable and then store the first variable into the rest of the variables.

:7112→A
:7112→B
:7112→C
can be
:7112→A
:A→B
:A→C

When calculating several repetitive trigonometric or other math functions in a program, it is sometimes faster to just store the values in a list and recall the values when needed.

:For(A,0,10
:Text(6A+1,1,10cos(A
:End
can be
:10cos(seq(A,A,0,10→L1
:For(A,0,10
:Text(6A+1,1,L1(A
:End

Matrices are faster than lists, so you should use them in speed sensitive situations, especially if you have 2 lists to store coordinates. While this is much larger, it is also faster.

:Pxl-Off(L1(I),L2(I
can be
:Pxl-Off([A](1,I),[A](2,I

If there are certain constants that arise throughout your program, it can be useful to store those constants to variables. Depending on the size of the constants, this can save a handful of bytes every time the constants are used.

:Line(154,0,154,216
:Line(0,216,154,216
can be
:154→A
:216→B
:Line(A,0,A,B
:Line(0,B,A,B

Note that the initialization of the constants costs extra bytes and a bit of speed. It is best if these values are truly constants that change very little throughout the program, otherwise the speed-to-space sacrifice may not be worthwhile.

<< Displaying Text Table of Contents Math Operations >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-variables


Optimization: The Graph Screen

Although the screen is 95 pixels wide and 63 pixels tall, the bottom row and far right column of pixels are unusable. So, most people set the graphscreen dimensions to 94 and 62. This itself should be replaced with storing 1 into deltaX and deltaY.

:0→Xmin:94→Xmax
:0→Ymin:62→Ymax
can be
:0→Xmin:1→ΔX
:0→Ymin:1→ΔY
can be even better
:ZStandard
:84→Xmin
:72→Ymax
:ZInteger

The Text command can display both variables and text at the same time on the same line. This allows you to sometimes remove multiple Text commands and just use the first one.

:Text(5,5,A
:Text(5,9,"/
:Text(5,13,B
can be
:Text(5,5,A,"/",B

The Pxl-On command is faster than Pt-On, and it should be used whenever possible. Pt-On is also affected by the screen dimensions, while Pxl-On is not.

:Pt-On(5,5
can be
:Pxl-On(5,5

The Line command has an optional fifth argument that controls whether the line will be drawn (the argument should be one) or erased (the argument should be zero). The default is one, and it should be left off when possible.

:Line(5,5,10,5,1
can be
:Line(5,5,10,5

When turning multiple pixels in a straight line on or off, use a For loop instead of using the individual pixel commands.

:Pxl-On(5,5
:Pxl-On(5,6
:Pxl-On(5,7
:Pxl-On(5,8
can be
:For(X,5,8
:Pxl-On(5,X
:End

When you are changing the same pixels from on to off or vice versa in a loop, use the Pxl-Change command instead of the individual pixel commands.

:For(X,5,8
:Pxl-On(5,X
:End
:For(X,5,8
:Pxl-Off(5,X
:End
can be
:For(N,1,2
:For(X,5,8
:Pxl-Change(5,X
:End
:End

When you have multiple pixels in a straight line that you turn on or off, you can sometimes replace the Pxl-On commands with Line commands.

:Pxl-On(5,5
:Pxl-On(5,6
:Pxl-On(5,7
:Pxl-On(5,8
can be
:Line(5,5,5,8

The Pt-On and Pt-Off commands have an optional third argument that should never be used when one is desired because one is the default.

:Pt-On(5,5,1
can be
:Pt-On(5,5

The optional third argument for Pt-On and Pt-Off should be used when you want to turn on or off a 3x3 outline of a box (the argument should be two) or a 3x3 cross (the argument should be three). This can be used instead of the individual commands.

:Pt-On(A,B-1
:Pt-On(A,B
:Pt-On(A,B+1
:Pt-On(A-1,B
:Pt-On(A+1,B
can be
:Pt-On(A,B,3

When wanting to clear large spaces of the graph screen, you should use the Line or Text commands instead of the pixel commands, when possible. Both of these commands are faster than the pixel commands.

:Pxl-Off(5,5
:Pxl-Off(5,6
:Pxl-Off(5,7
:Pxl-Off(5,8
can be
:Line(5,5,5,8,0

The Circle( command has an alternate syntax. When a complex list such as {i} is added as the 4th argument, "fast circle" mode will be turned on, which uses the symmetries of a circle to save on trig calculations, and draws a circle in only 30% of the time it would normally take. Since the Circle( command is speed-challenged at best, you should always use this optimization when drawing circles.

:Circle(0,0,5
can be
:Circle(0,0,5,{i
<< Loops Table of Contents Summary >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-graph


Optimization: User Input

The Input command has an optional display message argument that can be either text or a string. This display message can be used to tell the user what type of value to enter or to show what the variable is for. The Input command should be used instead of using a Disp command in conjunction with the Prompt command.

:Disp "Guess
:Prompt A
can be
:Input "Guess?",A

If you have two Input commands that have display messages that are positioned between a conditional, you can often remove one of the Input commands and then use the sub command to display the appropriate display message. This allows you to get rid of the conditional. You can also take out the common part of the display message and add it to the substring part of the display message.

:If A=1
:Then
:Input "Take candy?",Str1
:Else
:Input "Give candy?",Str1
:End
can be
:Input sub("GiveTake",1+4(A=1),4)+" candy?",Str1

The Prompt command can be used with more than one variable. If you have a list of prompt commands, you should put all of the variables on the first Prompt command, separating each variable with a comma. This allows you to get rid of the rest of the Prompt commands.

:Prompt A
:Prompt B
:Prompt C
can be
:Prompt A,B,C

The Prompt command should be used instead of the Input command when you have the display message show what the variable being stored to is. And if there are multiple Input commands, you can reduce them to just one Prompt command.

:Input "A=?",A
:Input "B=?",B
:Input "C=?",C
can be
:Prompt A,B,C

When doing calculations and user input, you should move the calculations before the user input. The delay before the user input is not important because people simply can't type fast enough to notice it.

:Input "NAME:",Str1
:3B/7→L1(1
:2A+5B→C
can be
:3B/7→L1(1
:2A+5B→C
:Input "NAME:",Str1

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-input


Optimizations: Displaying Text

If you have a string of numbers that you are displaying, you don't need to put quotes around the numbers. You should only use quotes if you want to keep any leading zeros.

:Disp "2345
can be
:Disp 2345

Use the Disp command instead of the Output command when displaying text on the first line of the homescreen. You can just add spaces to the text to move it to the correct location.

:Output(1,2,"Hello
can be
:Disp " Hello

When displaying the same text or variable on three or more lines, use a For loop. A For loop can also be used when the display is changing by a constant increment.

:Output(3,3,1
:Output(4,3,2
:Output(5,3,3
can be
:For(X,3,5
:Output(X,3,X-2
:End

When the text in an Output command is more than sixteen characters (26 on the color calculators), it will wrap around to the next line. When you have two or more Output commands that display text on different lines, you can sometimes put the text together and add blank spaces between it to make it go to the next line in the desired location.

:Output(1,6,"Hello World
:Output(2,2,"Version 1.0
can be
:Output(1,6,"Hello World Version 1.0

Using the Disp command, you can display text and variables at the same time by putting a comma between each one. Because this can hinder readability, this should only be done when just displaying variables.

:Disp A
:Disp B
can be
:Disp A,B

When you have a list of Disp commands that you pause, you can take the text or variable from the last Disp command and place it after the Pause command as its optional argument, allowing you to remove the last Disp command.

:Disp "A=
:Disp A
:Pause
can be
:Disp "A=
:Pause A

You can often remove Disp commands by storing to a string only the text differing with values of a variable, and then displaying the text added to the similar statements with one Disp command. This can be useful when you have two conditionals that are opposites that display similar text.

:If A≥10
:Disp "You Win
:If A<10
:Disp "You Lose
can be
:"Win
:If A<10
:"Lose
:Disp "You"+Ans

When you have two or more Disp statements inside an If-Then conditional, you can combine the Disp statements to change the If-Then conditional to an If conditional.

:If A>B
:Then
:Disp "A is greater
:Disp "than B
:End
can be
:If A>B
:Disp "A is greater","than B

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/optimize-text


The newList() Command

newlist.png

Command Summary

Returns a list filled with zeroes.

Command Syntax

newList(length)

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The newList() command returns a list of a specific length that is filled entirely with zeroes.

:newList(3)
           {0  0  0}
:newList(5)
           {0  0  0  0  0}
:newList(0)
           {}

This can be easily expanded to returning a list filled with any value: to return a list filled with a value x, just add x to the result of newList(). This works for strings as well, since "Hello"+0 simplifies to "Hello".

Advanced Uses

newList() can be used for making a comparison between a single value and a list. Normally, something like {1,2,3,4}=2 simply returns "false", since 2 is not a list and {1,2,3,4} is. To do a comparison element-by-element, use newList() to turn the single value into a list: in this case, 2+newList(4). Comparing {1,2,3,4} to 2+newList(4) will return {false, true, false, false} (you might use when() to get a single value out of this list).

This works to extend other operations to a number and a list, as well, though comparisons are the most useful application of this technique, since most operations already work this way.

Optimization

In many cases, an expression with newList() can be used to optimize a seq() command. First, observe that the simple

:seq(k,k,1,n)

which will return the list {1,2,3,…,n}, can be replaced by
:cumSum(1+newList(n))

The result is about twice as fast.

This is useful because many seq() expressions can be expressed using something like seq(k,k,1,n). For example:

:seq(k^2,k,1,n)

can be

:seq(k,k,1,n)^2

which is

:cumSum(1+newList(n))^2

This rearrangement is not always possible, but when it is, it gives a significant improvement in speed, with no real difference in size.

Here is a more complicated example (which is a sequence of probabilities with the binomial distribution). Notice the use of the with operator.

:seq(nCr(n,k) p^k (1-p)^(n-k),k,1,n)

can be

:nCr(n,a) p^a (1-p)^(n-a)|a=cumSum(1+newList(n))

Error Conditions

260 - Domain error happens when the length is not an integer ≥0.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:newlist


Piecewise Expressions

Piecewise expressions are a shortcut to handling conditions in math statements. They can be used for turning an If block or several such blocks into a single line. Although the TI-83 manual recommends them for graphing piecewise functions, they are very important to programmers as well — it would not be an overstatement to say that the use of piecewise expressions revolutionized TI-Basic when it was introduced. On recent operating systems (5.3+) for the TI-84+ CE, the piecewise( command was added, and it lets you see piecewise expressions on the homescreen and y= screen as they would be seen in a math textbook, if mathprint is on.

The Concept

The general form of a piecewise expression is (expr #1)(condition #1)+(expr #2)(condition #2)+…→result. Usually, condition #1, condition #2, and any other conditions are mutually exclusive — only one of them can be true at a time. In this case, the piecewise expression can be interpreted as follows:

  • if condition #1 is true, return the value of expr #1
  • if condition #2 is true, return the value of expr #2
  • if condition #n is true, return the value of expr #n

A classic example of a piecewise function is absolute value, which strips a number of its sign. Forget for a moment that the abs( command exists, and picture code that would do its job. A possible solution relies on the If command:

:If A≥0
:Then
:A→B
:Else
:-A→B
:End

Using piecewise expressions, we can write this as:

:(A)(A≥0)+(-A)(A<0)→B

Most of the parentheses are unnecessary, only here for clarity. If you're comfortable with piecewise expressions, you can strip the extra parentheses to get this version:

:A(A≥0)-A(A<0→B

Why does this work?

Believe it or not, the calculator does not make special cases for piecewise expressions. Instead, this technique relies on the convention known as Boolean logic. According to Boolean logic the number 1 represents "true" in logical expressions on the TI-83, while 0 represents "false".

In the case of a properly written piecewise expression, only one of the conditions will be true, and the rest will be false. That condition's expression will be multiplied by 1, and the others by 0. When the results are added, this gets rid of the unwanted expressions, leaving only the one with a true condition.

Optimization

Now that we know how this technique works, we can optimize such expressions while keeping the result the same. For example, here is part of the code for moving a cursor on the screen, as a piecewise expression:

:getKey→K
:(X-1)(Ans=24)+(X+1)(Ans=26)+(X)(Ans≠24 and Ans≠26)→X
:(Y-1)(K=34)+(Y+1)(K=25)+(Y)(K≠34 and K≠25)→Y

Notice that all three pieces of the first expression contain X, and all three pieces of the second expression contain Y. In such cases, we can take out the common part of the pieces, without changing the result:

:getKey→K
:X-(1)(Ans=24)+(1)(Ans=26)+(0)(Ans≠24 and Ans≠26)→X
:Y-(1)(K=34)+(1)(K=25)+(0)(K≠34 and K≠25)→Y

Finally, we can cancel the unneeded parts. Many of the parentheses are unnecessary, but it's also pointless to multiply something by 1, so we can get rid of the (1) parts entirely. Finally, the parts multiplied by 0 are redundant.

:getKey→K
:X-(Ans=24)+(Ans=26→X
:Y-(K=34)+(K=25→Y

The result is the movement code you may have seen elsewhere in the guide, in its fully optimized form!

Advantages and Disadvantages

Piecewise expressions are usually a better choice than clunky If statements to accomplish the same thing. They give the following benefits:

  • The result is usually faster to compute, and takes less memory in the program.
  • The expression takes less space on the screen to scroll through.
  • Piecewise expressions can be used where If statements can't (for example, equations).

However, there are a few drawbacks you need to be aware of:

  • Unlike an If statement, a piecewise expression will compute all its parts before returning the result.
  • Complicated logic can make piecewise expressions very messy and hard to understand.

So one situation in which piecewise expressions should be avoided is one in which part of the expression takes a long time to compute. For example:

:If N=1
:Then
:irr(I,100,L1→P
:Else
:P(1+.01I→P
:End

In this case, a very complicated calculation is done in the case N=1 (if L1 is large enough, it may take several seconds). But if N is not 1, the calculation is very simple and will finish quickly. If you made this code a piecewise expression, the very complicated calculation would always be calculated, even if it's not going to be necessary.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/piecewise-expressions


Friendly Graphing Window

A friendly graphing window is some configuration of window variables that's most useful for your program — most commonly, because it makes the coordinate value of a pixel come out to a round value, such as an integer, or .1 of an integer.

Setting up a square window

The most basic type of friendly window is one in which a vertical distance in pixels is equal, coordinate-wise, to the same horizontal distance in pixels. This means that the ratio between (Xmax-Xmin) and (Ymax-Ymin) is 47:31. Such a setup has the useful effect that drawing a circle (for example, with the Circle( command) actually results in a circle, and not an ellipse.

This can be accomplished simply with the ZSquare command, which will alter the values of the screen so that:

  • the coordinate of the center remains the same
  • the ratio (Xmax-Xmin) : (Ymax-Ymin) is 47:31 (approximately 1.516 : 1)
  • the resulting window is larger rather than smaller than the original.

A common technique is to run the ZStandard command first, so that the center of the screen is at (0,0).

Setting up an integer square window

However, it's possible to take friendliness even further, by adding the condition that coordinate values of a pixel come out to round values without long decimals. This can be done in several ways:

Using the ZDecimal command

This is by far the simplest — the ZDecimal command will set Xmin to -4.7, Xmax to 4.7, Ymin to -3.1, and Ymax to 3.1. As you can see, this satisfies the condition for a square window. Also, the coordinates of pixels have at most one decimal place: pixels that are next to each other differ by 0.1 in the appropriate coordinate.

Zdecimal is useful if you only need to do a few point/line commands, like if you were drawing a border around the screen using Horizontal and Vertical.

However, it has the drawback of still having a decimal point. Your drawing commands may look like Line(-3.1, -1.7, 3.1, -1.7) — if you didn't have to have that decimal point there, you'd save a considerable amount of space. This is possible, using the following three methods:

An integer window with (0,0) in the center

These methods are basically divided over where the point (0,0) should be. Putting it in the center ensures that drawing things in the middle of the screen takes up little space; also, you can achieve symmetry easily by appropriately negating numbers. On the other hand, the negative sign (you'll be using one 3/4 of the time, and 1/4 of the time you'll need two) can be annoying.

The following code sets up an integer square window with (0,0) in the center:

:ZStandard
:ZInteger
An integer window with (0,0) in the bottom left corner

This approach is optimal in terms of saving space on coordinates: they are all positive numbers with at most two digits. For this reason, it is the most widely used. The following code sets up such a window:

:ZStandard
:84→Xmin
:72→Ymax
:ZInteger
An integer window with (0,0) in the top left corner

This approach is useful for when point and pixel commands need to be used together. Although putting (0,0) in the top left makes every Y-coordinate negative, the window has the useful property that it's very easy to go from point commands to pixel commands: the pixel (R,C) corresponds to the point (C,-R), and equivalently, the point (X,Y) corresponds to the pixel (-Y,X). It's somewhat trickier to set up, though:

:ZStandard
:84→Xmin
:-72→Ymin
:ZInteger

Why friendly windows are useful

Throughout this article, we've only made glancing comments as to why you'd want to use friendly windows. Here is a more exhaustive explanation:

Graphs come out nicer

Even with a square window, graphs become more accurate, because they reflect the actual proportions of the equation being graphed. For example, try drawing a circle in the standard graphing window — you'll get some stretched out oval. Now ZSquare and try again. The result is much better, right?

With an integer square window, certain other imperfections of the calculator's graphing go away. For example, try graphing Y=1/(X+1) in the standard graphing window. Pretty accurate, but instead of the asymptote there's a slightly diagonal line. That's because the asymptote doesn't end up corresponding to a pixel of the graph: one pixel, the curve is a very negative number, the next it's a very positive number, so the calculator tries to connect them.

Now ZDecimal and graph 1/(X+1) again. The nearly vertical line at the asymptote disappears: because the value X=-1 matches a pixel on the graph, so the calculator realizes that something is undefined there.

Another similar problem occurs with graphing Y={-1,1}√(9-X²). In most graphing windows, this graph, which should come out to a circle, has some gaps near the sides. In an integer square window, such as with ZDecimal, the gaps disappear, and you're left with a perfect circle.

Coordinates are round numbers

This is a more programming-related application. If you happen to need to draw something on the screen, in a program, you're likely to need a lot of Line( or Pt-On( commands at fairly specific locations. On a normal window, such a "specific location" might end up being (2.553,0.645) or something equally ugly, with unpredictable results if you try to round it to the nearest nice value (since you don't know exactly the point at which pixels change).

With a friendly window (for this purpose, an integer window with (0,0) in the bottom left is the friendliest), every single pixel has a round coordinate value. If each value is no more than a 2-digit number, you can even compress all the coordinates of a line into a single number — this technique was used, for example, in Bryan Thomas' Contra game.

Point and pixel commands are compatible

In the case of an arbitrary window, it's fairly difficult to convert from a pixel coordinate to a point coordinate and back: the exact formula is X=Xmin+CΔX, Y=Ymax-RΔY if (X,Y) is the point and (R,C) is the pixel (going from pixel to point is even more painful). However, there are many cases in which you do need to go back and forth — for example, if you need to draw both text and lines at a coordinate. With friendly windows, this formula becomes much simpler — such as (X,Y)=(C,-R) for the last integer window we discussed.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/friendly-window


Animation

Animation is the rapid display of images on the screen to create an appearance of movement: it works by displaying an image and then moving it to a new location after a short delay has occurred. While there are many different things that you can do for animation (the possibilities are practically infinite; heck, there is an entire program directory at ticalc.org devoted to animations), almost every animation depends on For( loops.

A For( loop is a special kind of While loop, with all of the loop construction built-in, it has the the variable that the loop uses, the starting value, the ending value, and the increment. This is important because you can use all of those things to dictate how many times the animation is displayed, the speed of the animation, and even the animation itself (using the For( loop variable as the coordinates or the text that is displayed).

Animation is commonly used at the beginning of a program or on loading screens to add some visual pop or pizazz, which gives a program an edge over similar programs. At the same time, this does not mean that you can't go overboard with animation; too much animation becomes annoying and lengthy after a while. Selective animation — where it makes sense and complements the program — has the best impact in a program.

You also want to keep in mind the calculator that the animation is running on. If you created your animation on the TI-83+SE or TI-84+SE, then the animation probably won't display as you intended on a TI-83 or TI-83+ calculator (calculators that have a much slower processor; 6MHZ and 8MHZ respectively are slower compared to 15MHZ for the TI-83+SE and TI-84+SE). Of course, there are a few other things that you need to consider, so you should read the portability page for more information.

Animation Examples

This is an example of moving text: the variables of the X or Y coordinate of the text are changed by the for( command.
The spaces before "looks" and after "huh?" are needed to delete the old text.

ClrDraw
AxesOff
For(A,1,20
Text(A,40,"This
End
For(A,1,19
Text(28,A+9," looks
Text(28,69-A,"cool
End
For(A,50,35,-1
Text(A,40,"huh?
Text(A+6,40,"<16 spaces>
End
Running this code gives this program:
Text_example_looped.gif

You can also draw and erase shapes and lines.

ClrDraw
For(A,1,10)
Line(30,40,40,40
Line(40,40,40,30
Line(40,30,30,30
Line(30,30,30,40
Line(30,40,40,40,0
Line(40,40,40,30,0
Line(40,30,30,30,0
Line(30,30,30,40,0
End

TODO: Add more examples

  • Using pictures
  • Drawing/Erasing text (changing position, size, letter by letter)
  • Drawing/Erasing shapes (changing position, size, color)

One of the most common examples of animation that you see in games is wiping the graph screen (you can certainly wipe the home screen as well). This is usually done at the end of the game, after the player has lost, or as a transition from one level of the game to the next.

Wiping the screen involves using one or more Line( or Horizontal/Vertical commands, and then displaying the line from one side of the screen to the other:

:For(X,Xmin,Xmax,ΔX
:Vertical X
:End

As you can see, a vertical line is displayed from the left side of the screen to the right side, effectively shading the entire screen. Since it uses Xmin ,Xmax, and ΔX, it will work on any screen.

Another common example is displaying text. This is commonly used on the title screen of a game to make the game stand out to the user. There are several different ways that you can display text, but some of the most common are: letter by letter, sliding it in from the screen side, overlapping each letter, and displaying the large text behind the small text.

Displaying text letter by letter involves placing the text in a string, and then displaying the respective substring based on where you are in the For( loop. More plainly stated, display each character by itself at the respective time.

The code for this is fairly simple:

:For(X,1,5
:Output(1,X,sub("HELLO",X,1
:End

Animation Length

The two different options for animation length are timed and infinite: timed means the animation lasts for a set amount of loop iterations, while infinite means the animation will go on indefinitely with no end (or at least until the user finally presses the ON key).

The way you go about making a timed animation is by simply using an additional For( loop enclosed around the animation. For example, if you want the animation from before to be displayed five times, you can just do:

:For(I,1,5
...
:End

There are actually three different ways to make an infinite animation: use a For( loop with a really large ending value (such as E5) or use an infinite While 1 or Repeat 0 loop. The infinite While or Repeat loop is the smaller of the two, but the For( loop has the advantage that it still allows the user to exit out of the animation.

Of course, the really long For( loop is not a true infinite loop, since it will eventually end at some point. For our purposes, however, it works quite well because the calculator will actually power down after a certain amount of inactivity (the TI-83+ and above have a built-in APD feature).

The last way is adding prgm and then your program name, which you put at the end of your program. This makes it loop itself infinitely, until you press the ON key. This does use a little bit of storage every time, so use this one sparingly. Example:

PROGRAM:HI
:Disp "HI."
:prgmHI

Adding a Delay

If you try out any of the examples that have been shown so far, one of the things you will probably notice is that they display so quickly that you can barely see them being displayed until they are almost done. This behavior is acceptable for some animations, such as where there is lot of things being animated at one time, but it can cause havoc for a lot of animations. The way you fix this problem is by adding a delay.

There are two basic ways to create a delay: use a For( loop or use the rand command. The For( loop is just an empty loop, meaning there are no commands or functions inside of it. The rand command's alternate syntax — rand( — generates a list of random numbers, which is a rather time-consuming operation. Both of these delay methods can be worked so that they create a small or large delay simply by changing the size of the For( loop and the number of random numbers generated respectively.

For an example, here is the text animation from before, where the word HELLO is displayed letter by letter on the first line on the home screen, with each of the two respective delay methods added to it:

:For(X,1,5
:Output(1,X,sub("HELLO",X,1
:For(I,1,20:End
:End
:For(X,1,5
:Output(1,X,sub("HELLO",X,1
:rand(10
:End

Each delay method has its own advantages and disadvantages. The For( loop has the advantages that using it still allows the user to do something during the delay, and it does not have any additional memory overhead like rand does. The rand command has the advantage that it is smaller in size than the For( loop.

The rand command does use some additional memory for storing the temporary list of random numbers in Ans, which may be undesirable. To avoid this, you simply have to use this somewhat longer line: If dim(rand(#. Despite the presence of an If statement, you don't have to worry about the next line being skipped, since dim(rand(#)) will always be true.

The other concern when using the rand command is that if the number is large enough, the program will run out of memory from trying to generate such a large list, and subsequently return a ERR:MEMORY error. What number is too large is dependent on how much free RAM is available on the calculator, so for some people it might be 100 while for others it might only be 50. So, if you want to use a large delay, it might be better to go with a For( loop instead of a rand command.

Related to that concern is the issue of portability: a delay may be appropriate on your calculator, but it won't be on another calculator. For example, if you have a TI-83 and you use a delay for twenty iterations of a For( loop, that would be almost unnoticeable on the much speedier TI-83+SE and TI-84+SE calculators. Conversely, if you write your program on a TI-83+SE, the delay would be much longer on a TI-83 and TI-83+, to the point that the animation would slow to a crawl.

With exception to assembly libraries, there is no viable way to check what calculator a program is being run on. A good alternative is to find the appropriate delay for each calculator, and then take the average for the delay that you use. This happy medium is just a simple fix, and really all you can do is just keep the other calculators in mind when deciding how much delay to use.

Allowing User Exiting

One of the main considerations that you have to make when using animation in a program is whether the user can exit the animation at any time they want. This applies to animations of any length, but it especially applies to long animations. This is because the user has to wait until the entire animation is finished before they can move on to the rest of the program, which is extremely annoying from the user's point of view (see program usability for more information).

There are a couple different ways you can fix this problem. The first way is to add some getKey's throughout the animation to check for user key presses; and if you find any, you exit the animation.

Since the animations use For( loops, and we want to exit out of them before they have finished, you can do this by storing something at least equal to the end value to the variable used in the For( loop. For example:

:For(C,61,32,-1
:Pxl-On(C,47
:If getKey:32→C
:End

While this approach works quite well if your animation only consists of one For( loop, it doesn't work when you have two or more For( loops that you need to exit out of. The problem is that if you exit out of the first loop early, you then need to skip the rest of the For( loops in the animation.

Unfortunately, there is no real easy way to go about doing this. One option is to use branching to jump out of the For( loops to go to a While 0 loop internal subprogram. The reason for doing this, of course, is to avoid creating a memory leak.

Because using branching can get rather messy, another option is using an additional variable to act as a flag. You just set the variable to an off state (zero is the standard value), and then change it to an on state (achieved by inverting the flag variable's value) when the user has pressed a key.

For example, here is an animation that displays the word HELLO letter by letter, and then erases each letter starting from the "O". If the user doesn't exit the animation early, it will be played 100 times before it is finally finished. Note the first example uses the branching while the second example uses the A variable as a flag.

:For(I,1,E2
:For(X,1,5
:Output(1,X,sub("HELLO",X,1
:If getKey:Goto A
:rand(10
:End
:For(X,1,5
:Output(1,6-X," "
:If getKey:Goto A
:rand(10
:End:End
:While 0:While 0
:Lbl A
:End:End
:DelVar A
:For(I,1,E2not(A
:For(X,1,5not(A
:Output(1,X,sub("HELLO",X,1
:If getKey:not(A→A
:rand(10
:End
:For(X,1,5not(A
:Output(1,6-X," "
:If getKey:not(A→A
:rand(10
:End
:End

Those two options should generally suffice for most animations, but a third option available is to simply rewrite the animation. There is no hard and fast way to rewrite an animation, but it generally just involves thinking about the animation and seeing if there is an alternative way of implementing it.

One common way to rewrite animations where you are moving back and forth (or displaying and erasing text) is by combining the two For( loops into one, and using some additional variables to keep track of the current direction (or if it should be displayed or erased). When an edge is reached, you then just invert the variables values from negative to positive and vice versa.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/animation


Custom Menus

Menus are often used in programs to choose options, allowing a program to have multiple functions, or a game to have extra features. Though the Menu( command creates a perfectly functional menu, sometimes you want your program to use something more fancy, to have a differently-functioning menu, or just to stand out from the others with a menu that looks different.

However, a custom menu is usually 2 to 3 times the size of the same menu written with the Menu( command - the difference is between a menu that takes up 150-200 bytes and one that takes up 50-100 bytes.

Basic Menus

This covers the basics of creating a functioning custom menu. Remember to set up the graph screen before displaying the menu, to avoid something like axes covering the menu.

Numerical Input

The simplest way to create a custom menu is just to display the title, and a numbered set of options. Then, wait for a number key to be pressed, and act accordingly.

The following code is an efficient way of waiting until a number key is pressed, and converting it to a number N:

:Repeat 2>abs(5-abs(5-abs(Ans-83)))
:getKey
:End
:round(13fPart(Ans/13))→N

But you might not always need to convert the number at all. If all you're going to do with the option is go to a different part of your code, you might just want to use the getKey value for comparisons. And if you only have a small number of options, it's easier to check for them all explicitly rather than using the abs( command as above: for example, Repeat max(Ans={92,93,94}) will check for the keys 1, 2, and 3.

Arrow Key Input

If you want to get slightly more fancy, you could provide a cursor, such as an arrow or ">" symbol, that points to the selected option (there are many ways to display this). The first thing you'd do is display the title and the options, just as in the previous case (except you wouldn't need to number them). Then create a variable that stores the option currently chosen.

For the rest of the code, you would need a loop, structured roughly as follows:

Loop until a selecting key (such as enter) is pressed
Display a cursor at the currently chosen option
Wait for a key to be pressed
Erase the cursor
If an arrow key was pressed, change the chosen option variable
End of the loop

It is important that you actually wait for a key to be pressed, instead of just storing the key to getKey. The loop will work both ways, but if you don't wait for the key, then it will go through the loop even when no key is pressed, erasing and redrawing the cursor, which causes flicker. Another way to eliminate the flicker is to only erase the cursor if an arrow key was pressed.

You can use Boolean optimizations to quickly adjust the option based on the arrow keys:

:N+(K=34 and N<(# of options))-(K=25 and N>1→N

Another possible optimization is to use the row coordinate of the option, rather than the option number, for the value you store (but then you need to modify it by the row difference between two options, rather than 1, when arrow keys are pressed)

Labels vs. Values

The Menu( command goes to a label when an option is selected, whereas both of these methods return a value. It's fairly easy to go back and forth between these methods. To convert from a value to going to labels, add If statements like:

:If N=92
:Goto 1

To convert the Menu( command from going to labels to returning a value, use code like this:

:1
:Menu("TITLE","OPTION 1",1,"OPTION 2",2,"OPTION 3",3
:Lbl 3:Ans+1
:Lbl 2:Ans+1
:Lbl 1

1 is stored to Ans. If 1 is chosen, the Menu( command goes to Lbl 1, and this code finishes with Ans=1. If 2 is chosen, the Menu( command goes to Lbl 2, where Ans is increased to 2, then the code goes to Lbl 1 and finishes. If 3 is chosen, the Menu( command goes to Lbl 3, which has 2 Ans+1 commands after it, so Ans is increased twice: to 3.

However, it's usually easy to avoid using labels with menus.

Advanced Menus

This section covers advanced techniques your custom menus might use.

Multi-page Menu

(this section is based on this menu routine by Steve Hartmann)

A multi-page menu could be used for as many options as you wanted, and is another reason to use a custom menu routine. To create a multi-page menu, you would need a loop which displays the current page (most likely with some If statements), then does the necessary operations for a normal menu until either an option is selected or the left/right arrow keys are pressed. If an option is selected, obviously you exit the loop; otherwise, you change the page number but stay in the loop.

The most complicated situation you could be in is a multi-page menu operated completely by arrow keys. Here, you'd use a total of three nested loops: one for the page, another for the menu itself, and a third for waiting for a key.

Selecting Options

In an arrow-key operated menu, you have several options for the cursor. The simplest is to draw some sort of symbol next to the option currently selected. This could be embellished by animating the symbol - a little tricky, because it must be done inside a getKey loop. Here is an outline of the code to do so:

:Repeat K
:For(I,1,(some limit))
:(draw Ith step of animation)
:getKey→K
:I+(limit)*Ans→I
:End
:End

Inside the getKey loop, a For( loop goes through all the frames of an operation. This by itself would take too much time - even if you pressed a key, you would have to wait for the animation to cycle entirely. To prevent this, we add the line I+(limit)*Ans→I. Ans holds the value of getKey, which is 0 if no key was pressed, and not zero otherwise. So if no key was pressed, we're adding 0 to I, which does nothing. If a key was pressed, however, we add a large value to I which puts it beyond the range of the For( loop, to exit the For( loop immediately. If the For( loop has a small limit, like For(I,1,10), you can simply add getKey to I, since getKey is at least 11 if it's not 0.

Program Structure

Most people reading this page probably are familiar with the reasons to avoid Goto and labels, and do stay away from them usually. However, menus complicate the situation enough that a lot of calculator programmers give up and use labels anyway, creating a program that's impossible to understand or to maintain because of the complex web of Goto commands. This doesn't need to happen - you can structure your code so that labels are unnecessary. The important part is to create this structure first, and then build the program around it, rather than writing a program and trying to tack a menu onto it later.

Suppose your menu chooses among several options which should run and go back to the menu, and a final Quit option. The structure for your program could look like this:

:Repeat choice=Quit
:(menu that sets 'choice')
:If choice=Option 1:Then
:(run option 1)
:End
...
:If choice=Option 35:Then
:(run option 35)
:End
:End (the outermost loop)

The weakness in this code is that the variable your choice is stored in can't be modified by any of the options, or else you risk setting it to the value of an option that's yet to be checked for (which in that case will also run before you get back to the menu). To get around this, any options that modify this variable should DelVar it at the end of their If-Then-End block, then it won't interfere with anything else (theoretically, you could use the variable Ans, and then instead of DelVar add the line :0)

Examples

Some sample programs with a simple number menu, cursor-based menu, and animated cursor-based menu:

You can also download all three in one file.

You can find a sample multi-page custom menu program here.

Scroll Bar

Moreover, you can add a vertical scroll bar. The scroll bar is a nice feature which not only looks good but also gives the user an overview of the menu.

First, you need some variables. You can use a list, in this case L(SCBAR).

1 PStart The point where the scroll bar starts
2 PEnd The point where the scroll bar ends
3 ETotal All of your options or elements in total
4 EAbove All of the invisible options above the visible elements
5 EBelow All of the invisible options below the visible elements
6 LStart Point where the scroll bar would start if 100% of the elements were visible
7 LEnd Point where the scroll bar would end if 100% of the elements were visible

First, we need to calculate PStart and PEnd:

LSCBAR(6)+LSCBAR(4)*((LSCBAR(7)-LSCBAR(6))/LSCBAR(3))->LSCBAR(1) // P,,Start,, = L,,Start,, + E,,Above,, * (L,,End,, - L,,Start,,)/E,,Total,,
LSCBAR(7)-LSCBAR(5)*((LSCBAR(7)-LSCBAR(6))/LSCBAR(3))->LSCBAR(2) // P,,End,, = L,,End,, + E,,Below,, * (L,,End,, - L,,Start,,)/E,,Total,,

Simple percent math ;)

For the scroll bar you just draw 3 lines:

Line(93,-LSCBAR(1),93,-LSCBAR(2) // 93 is the X-Coordinate where the scroll bar will be drawn
Line(92,-LSCBAR(1)-1,92,-LSCBAR(2)+1 // Makes the scroll bar look better
Line(94,-LSCBAR(1)-1,94,-LSCBAR(2)+1

Finally, you could theoratically also draw a horizontal scroll bar, you just need to replace the variables with other values and the line commands.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/custommenus


Saving

The most efficient and versatile way to save data when a program exits is by using a custom list. The list can be named after your program, hold up to 999 values, and be archived for long-term storage. Below is an example of a simple saving routine that backs up the variables A,B, and C into ∟SAVE and archives the list. It then unarchives and restores the data from that list.

:{A,B,C→SAVE
:Archive ∟SAVE
:SetUpEditor SAVE
:If not(dim(∟SAVE
:{0,0,0→SAVE
:∟SAVE(1→A
:∟SAVE(2→B
:∟SAVE(3→C

The Explanation

First, use the syntax {value, value, value, …}→SAVE to back up as many values (usually variables) as you want. If ∟SAVE does not exist, it will be created with those values. If it does, the previous data will be overwritten and replaced.

:{A,B,C→SAVE

To prevent losing saved data, the list is stored in Archive memory. While in Archive memory, it will not be erased due to a RAM clear and cannot be overwritten by other programs. You might consider leaving this step out, however, to preserve compatibility with the TI-83 (which doesn't have Archive memory).

:Archive ∟SAVE

To load the saved data, it first must be moved out of archive memory, or an ERR:ARCHIVED will result. The most obvious method would be to use Unarchive ∟SAVE. However, using this command will cause problems if the list does not exist. The best command to use is SetUpEditor, which was intended for use with the built-in list editor.

As a side effect of setting up a list in the editor, SetUpEditor will create the list if it does not exist, unarchive it in archive memory, or leave it alone in RAM. In other words, SetUpEditor will always result in an unarchived ∟SAVE in RAM, without any errors (also see the relevant section on program cleanup). SetUpEditor can also be used on multiple lists separated by a comma.

:SetUpEditor SAVE

But what happens if this is the first time we're running the program? The answer is SetUpEditor will create our list for us, but it will have a length of 0. This allows us to check if we've saved data to it before: if we have, hopefully, it will have a length of more than that (in this case, 3). So this piece of code stores a default of {0,0,0} to the list if it's just been created (of course, you can put in anything you want as the default, or do something else entirely).

:If not(dim(∟SAVE
:{0,0,0→SAVE

Lastly, the stored data values are recalled into the variables to be restored.

:∟SAVE(1→A
:∟SAVE(2→B
:∟SAVE(3→C

Alternative Methods

You can also modify list entries (auto-save) directly during the game. Doing so saves the user from having to save the game before exiting, but may take more memory.
If you give the player the option to save in a linear/preset game, you can use variables and the Sto> key to create a way to save without using a list. This method branches off, and is infinitely expandable. Here is an example:

:ClrHome:Menu("Game","New",1,"Load",2,"Exit",3) 
:Lbl 2      // Ignore the other options for learning purposes. 
:If X=2
:Goto 45 :End     // Loads from where the player left off
...
:Menu("Save?","Yes",A,"No",45) 
:Lbl A :X → 2 :Goto 45 :End 
:Lbl 45 :Disp "Hi!" 
...     //Rest of code

Protecting Saved Games

It's quite a pain when you go through all that trouble to get users to follow the game through its entirety without the user changing his/her list data to give himself/herself ultimate powers. There are a few ways to protect this from happening.

Addition Method

To protect your saved lists, you can add up all the values of the list and store it to an element in the list right before the program leaves, and check it before allowing the user to reload that saved game.

Right before quitting:

:sum(∟SAVE,2→∟SAVE(1    // list element 1 is used to save the summation of all other list elements

Checking to make sure list elements add up:

:If sum(∟SAVE)≠2∟SAVE(1
:Disp "ERROR: DATA CORRUPTED

Extra list elements

Another method available to your disposal is to add extra elements that do nothing (or even better, cause errors!). No code will be provided as it is easy enough to add useless (or destructive) list elements. See program protection to get more details on destructive list elements.

Dual List method

Another thing you can do to protect saved games is to use 2 lists. Both lists will contain the same data, and can be compared to for changes made by users. To add further protection mix the order up (one list the opposite of the other).

Simple Dual List code

To get both lists the same:

:∟SAVE1→SAVE2    // make both lists the same

Checking to make sure both lists are the same:

:If not(min(∟SAVE1=∟SAVE2
:Disp "ERROR: DATA CORRUPTED

Backwards Order

To get both lists the same and into reverse order:

:seq(∟SAVE1(I),I,dim(∟SAVE1),1,-1→SAVE2

Checking to make sure both lists are the same:

:If not(min(∟SAVE1=seq(∟SAVE2(I),I,dim(∟SAVE2),1,-1
:Disp "ERROR: DATA CORRUPTED    // same as above, can change error type

CoSinTan Method

Simple, just add all the list elements except for the last one, then get sin(, cos(, or tan( of it. Then just store the result into the last element.

:sin(sum(∟SAVE,1,dim(∟SAVE)-1→∟SAVE(dim(∟SAVE

Obviously "dim(∟SAVE)" should be replaced with the dimensions of your save list, to save bytes. You can also replace sin( with any trigonometric function, such as tanh(, for added protection. Also make sure to execute a Degree or Radian command, to avoid the user being suspected for corrupting data if he's only changed a mode setting…

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/saving


Highscores

High scores typically involve saving a combination of strings (for names) and numbers (for the scores themselves) after the program is finished. The simplest high score system will only have a single score, while a complicated one might have a series of names with corresponding scores.

Managing High Scores

If there is only one high score, managing it is simple. All you have to do is check if your score is greater than the high score, and if so, change it.

:If S>∟HIGH(1
:Then
:Disp "NEW HIGH SCORE!
:S→∟HIGH(1
:End

Managing a table of multiple high scores and names would be more complicated. Here is an example routine for managing a high score table with 7 scores in ∟HIGH and 10-symbol-long names

:If max(S>∟HIGH:Then
:Disp "NEW HIGH SCORE!
:Input "YOUR NAME? ",Str1
:sub(Str1+" (9 spaces) ",1,10→Str1
:1+sum(S<∟HIGH
:sub(Str0,1,10Ans-9)+Str1+sub(Str0,10Ans-8,81-10Ans→Str0
:S→∟HIGH(8:SortD(∟HIGH
:7→dim(∟HIGH
:End

First, we should check if our score is even good enough to be in the high scores table. We're assuming that our high score table is kept in order, because we presumably initialized it that way (which will be discussed later), and we're going to keep it that way when we're done with this routine. So all we need to do is see if the score is greater than an element in our list:

If max(S>∟HIGH:Then

Next, we should input the high scorer's name. You can make this as easy or as hard as you want to, in this example I used Input for simplicity. We also pad this by appending spaces to the end then truncating the string to 10 letters, because we want it to be exactly 10 letters long.

Disp "NEW HIGH SCORE!
Input "YOUR NAME?",Str1
sub(Str1+" (9 spaces) ",1,10→Str1

Now, we find the place that the high score S got in the table. This line adds up the number of scores higher than the new one, and by adding one you get the new rank.

1+sum(S<∟HIGH

Now we insert Str1 into Str0 at the correct place. First we use sub( to find all the characters before the place we're sticking it in. Str1 is added onto this, and then we use sub( again to get all the characters that go after the new name.

sub(Str0,1,10Ans-9)+Str1+sub(Str0,10Ans-8,81-10Ans

We could do the same for lists, but there's an easier way. Since the list of scores is sorted, inserting an element into its correct place is the same as adding it to the end, then sorting the list. Finally, we remove the last score that was "bumped out" of the high score table.

S→LHIGH(8
SortA(LHIGH
7→dim(LHIGH

We're done!

End

Initializing the High Scores

Being able to add scores and names into the table would be useless without a table or names to begin with, so at the start of your program you should put in a block of code to do this.

:SetUpEditor HIGH
:If 7≠dim(∟HIGH:Then
:" (6 spaces)
:Ans+Ans
:Ans+Ans
:Ans+Ans+Ans→Str0
:0binomcdf(6,0→HIGH
:End

All SetUpEditor does is initialize the list. If ∟HIGH doesn't exist, it will create one with dimensions of 0. If the list does exist, nothing will be changed. As an extra check, you want to make sure that the list has 7 elements in it. If the list didn't already exist or didn't have 7 elements, the next block of code will execute.

Since the list not being there is a sign of the game being played for the first time, or that somebody tampered with the high scores, you should reset Str0 as well. We need Str0 to be 70 characters long for the names, but also add a space to the beginning and end for our computations when the person is ranked first or last.

Saving High Scores

We usually use a named list to store the high scores, due to the versatility of lists, and the fact that a named list probably won't get used by a different program (for more information, see Saving).

If we just have a score to deal with, it's simple to store it: just make it the first element of the list! However, with a complicated high score table, we'll have to store the names of the high scorers as well as their scores. So we have to find a way to convert a string to a list (and back).

This is simplest if you limit the variety of characters to be used for names (for example, uppercase letters and spaces). Then, you can store all the possible characters to a string, and use inString() to convert each character into a number - an index in that string. You would do this for all the characters, and append to the high scores. The following code is split up for clarity, but it could actually be combined into one line:

:" ABCDEFGHIJKLMNOPQRSTUVWXYZ
:seq(inString(Ans,sub(Str0,I,1)),I,1,70
:augment(∟HIGH,Ans→∟HIGH

Going the other way is equally simple. Unfortunately, there is no seq() command for strings, so you have to use a For loop instead, but other than that it's similar to the above code:

:" // 1 space
:For(I,8,77
:Ans+sub(" ABCDEFGHIJKLMNOPQRSTUVWXYZ",∟HIGH(I),1
:End
:Ans→Str0
:7→dim(∟HIGH

High Score Security

This is an optional side to high score saving. It's impossible to to make high scores completely tamper-proof, since someone could just look in the source code of your program and find out how you secure your high scores. However, you can use the random number generator to stop most casual cheaters (this is just one of many methods).

To do this, we first compute some number that depends on the entirety of the high score list. The most obvious is the sum of the elements. However, to obfuscate the process a bit more, you use the sum as the random number seed and save the first random number generated to the end of your list.

:sum(∟HIGH→rand
:rand→∟HIGH(78

To check if the high scores have been tampered with, you compute the sum of all the elements, and check if the first random number generated is the same as the one you saved. If it's not, somebody changed the scores, and the best way to punish the rascal is to reset them.

:sum(∟HIGH,1,77→rand
:If rand=∟HIGH(78:Then
(high scores are okay)
:Else
(the cheater has done his dirty work)
:End

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/highscores


Compression Techniques

Compression involves encoding data in an alternative format that has advantages over the un-encoded format. When determining whether to use compression, the main thing you should consider is its effectiveness (i.e., how much size and/or speed gain it results in). Of course, you need to decompress the data before you can use it again.

Graphing

One of the simplest ways of compressing data is by placing several related command values in a list, instead of listing out each individual command one after the other. A good example of this is when you are displaying a picture on the graph screen using several Pxl-On( commands. The Pxl-On( command has two arguments: an X and Y coordinate. After placing the coordinates in a list, we then just loop through the list with a For( loop:

:{10,10,25,25,50,50,60,60,35,35
:For(X,1,dim(Ans),2
:Pxl-On(Ans(X),Ans(X+1
:End

While this compression is effective, it can be improved upon. If you look at a number, it has an integer and fraction part. These two separate, but related parts can each be isolated using the iPart( and fPart( commands respectively.

Relating this back to our previous example, we should combine the two coordinates together, placing the Y coordinate as the integer and the X coordinate as the fraction. This effectively shrinks the list in half. For extracting each coordinate, you simply use the iPart( command to get the Y coordinate and multiply the fPart( command by 100 (E2) to get the X coordinate:

:{10.1,25.25,50.5,60.6,35.35
:For(X,1,dim(Ans
:Pxl-On(iPart(Ans(X)),E2fPart(Ans(X
:End

This compression technique was possible because the Pxl-On( command has two coordinates, but it would not be very effective if we were storing the Line( command's four coordinates: X1,Y1,X2,Y2. A better alternative would be to simply put all four coordinates together in the integer of the number. Probably the best example of this technique put to use is Bryan Thomas's Contra game.

The reason that this works is because a number can have up to 14 digits, so there are plenty of digits available for us to use. To extract each coordinate, you can use a combination of iPart( and fPart(, multiplying by the related power of 10. The following code draws a line for each element in the list:

:{15231561,42133313,62186251,48604839
:For(X,1,dim(Ans
:Line(iPart(Ans(X)/ᴇ6),iPart(ᴇ2fPart(Ans(X)/ᴇ6)),iPart(ᴇ2fPart(Ans(X)/ᴇ4)),ᴇ2fPart(Ans(X)/ᴇ2
:End

For color calculators, use the following code:

:{100100100100,001001001001,050050050050
:For(X,1,dim(Ans
:Line(iPart(Ans(X)/ᴇ9),iPart(ᴇ3fPart(Ans(X)/ᴇ9)),iPart(ᴇ3fPart(Ans(X)/ᴇ6)),ᴇ3fPart(Ans(X)/ᴇ3
:End

(Note that the lines may not display correctly if you don't have the right graph screen coordinates, so you should set your calculator to a friendly graphing window to make all of the coordinates easily-compressible two-digit numbers. In this particular example, the graph screen coordinates are supposed to be X=0…94 and Y=0…62, the standard for grayscale calculators. Color calculators should utilize X=0…264 and Y=0…164 and adjust the coordinates accordingly. Also note that the color version requires 3 digits per coordinate instead of the monochrome's 2 digits)

Complex Numbers

Besides using the integer and fraction parts of a number, you can also use complex numbers. A complex number has two parts: the real part and the imaginary part. Just like how you were able to separate the integer and fraction part of a number, you can also separate the real and imaginary parts of a complex number:

:real(-5+8i   // Returns -5
:imag(-5+8i   // Returns 8

While this doesn't have much application because using the integer and fraction part of a number is generally sufficient, it can sometimes be used in place of a 2-by-n matrix; you just use a list of complex numbers, where column 1 is the real part and column 2 is the imaginary part.

Now we'll move on to a different programming situation. In games you sometimes need a switch that tells whether something is in the on or off state. It is fairly common to see beginner programmers utilize two or more variables to keep track of the switch and alternate one variable based on the other's value.

This is an ample place for not only compression but just good logical thinking. If you remember that each variable is considered a Boolean; that means the value indicates either true or false. A false value is zero while a true value is anything else. So, you just need to check to see if the value of the variable is zero:

:If not(F    // Check if the flag variable is zero

Because the F variable can be either true or false, you have the switch built-in for you. To switch the variable, simply use the not(} operator:

:not(F→F    // Flip the value of the flag variable

Matrices

The most appropriate and needed place for compression is when storing lots of data, such as levels and maps. The most common variable used by people for storing data is matrices. This is because matrices are simple to use and they make sense since they are two-dimensional. However, matrices have one major disadvantage: size.

Instead of using matrices, which take up a large amount of memory, the better approach is to use either lists or strings when storing your levels. To load a level, you can extract the level data from the list and store it in the matrix during gameplay. Afterward, the matrix can be deleted.

Compression via Lists

Here is a sample level stored as a list, with each element representing a row to be displayed on the home screen:

:3→dim(L1
:If L=1:Then    // If level one
:4444→L1(1
:5623→L1(2
:4567→L1(3
:End

Using the iPart( and fPart( commands that we discussed previously, you can break apart each number into its own separate integer and fraction elements. This allows us to then store each number into a specific position in the matrix, looping through it with a couple For loops:

:{3,4→dim([B]
:For(Y,1,3
:L1(Y→Z
:For(X,1,4
:iPart(10fPart(Z/10^X→[B](Y,5-X
:End:End

Compression via Strings

The formula for storing a level as a string and converting it to a matrix is not much different than it was for the list:

:If L=1:Then    // If level 1
:"444456234567→Str1
:End
:1→F
:{3,4→dim([A]
:For(A,1,length(Str1
:exp(sub(Str1,A,1→[A]((fPart(A/4)!=0)+iPart(A/4),F
:F(F<4)+(F<4)+(F=4→F
:End

While this probably seems like a waste to go through all of this work just to compress a level, it is useful for large or complex level designs.. In addition, the calculator only has a limited amount of memory to begin with, so you need to take advantage of every opportunity to save memory.

Single Digit Numbers

We can compress a list of up to 14 elements into a single integer whose digits are the elements in reverse. Given an 8-element list stored in L₁:

{7,0,3,4,1,6,6,2}

To compress, use:

.1sum(L₁10^(cumSum(1 or L₁

which outputs:

26614307

You'll notice that the digits are in reverse. That might be a bit confusing, but having it in reverse makes it smaller and faster.

So now, we decompress:

int(10fPart(Ans/10^(seq(Z,Z,1,8

In general, replace 8 with the dimension of your list, or log(Ans) if the number of digits is unknown.

There you go. It is decompressed back into Ans. So, now we can compress single-digit data. But what about double-digits?

Double Digit Numbers

Double digits are a little more complicated, but they are also more useful because they allow up to 100 different positive integers instead of just 10.

Several methods were mentioned previously for decompressing 2-digit numbers, if you paid attention.

So, on to compressing! Say you had this 4-element list stored in L₁:

{24,47,36,42}

To compress it:

.01sum(L₁10^(2cumSum(1 or L₁

The answer:

42364724

The decompression:

int(E2fPart(Ans/10^(2seq(Z,Z,1,4

Digits of Any Length

One can generalize the above snippets of code to work for any length of digit. Our numbers are stored in L₁, and each have length N. To compress:

10^(-N)sum(L₁10^(NcumSum(1 or L₁

And decompress:

int(10^(N)fPart(Ans/10^(Nseq(Z,Z,1,1+iPart(log(Ans)/N)

However, due to the maximum precision of real variables (14 digits), it is impossible to store more than a couple of large numbers via this method.

References

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/compression


Making Maps

For many games, the gameplay consists of going through all of the maps in the game. For example, in a maze game where each map is a different maze, when you get through the first maze you go on to the second maze, and so on until you finish all of the mazes. Another common example is an RPG where the player can move their character around on the screen, and each screen is part of a larger map.

How to Store Maps

In order to keep track of all of the different things in a map, it obviously requires that you store the map to a variable. There are three different variables that you can use to store maps, and they each have their own advantages and disadvantages:

  • Matrices — Matrices are best used for two-dimensional data, and are easier to access and manage than both lists and strings. At the same time, matrices are the largest variable, which can be important if you are trying to keep your program as small as possible.
  • Lists — Lists are best used for one-dimensional data, and are faster to access than both matrices and strings. Lists also have the additional advantage that you can create your own custom lists, which decreases the likelihood that they will get messed with.
  • Strings — Strings can be adapted for basically any context, and they are smaller in size than both matrices and lists. In addition, unlike matrices and lists which have a set maximum size (99x99 and 999 respectively), strings can be as big as RAM will allow.

Generally speaking, it's best to use the most appropriate variable for the application. Going back to the maze game, for example, a matrix would probably be the preferred variable to use because a maze has a two-dimensional shape to it.

When storing a map in a variable, you have to assign numbers to represent the different things in the map: an empty space might be zero (0), a wall might be one (1), and the player might be two (2). You would then check for these numbers when determining what to do on the map or what to allow (such as movement by the player).

Here is an example of a simple 8x16 map stored in each of three different variables (note: the respective variable is all on one line, it's just split up to make it easier to read):

:[[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
 [1,2,1,0,0,0,1,0,0,0,1,0,0,0,1,1]
 [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1]
 [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1]
 [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1]
 [1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1]
 [1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0]
 [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1→[A]
:{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
 ,1,2,1,0,0,0,1,0,0,0,1,0,0,0,1,1,
 ,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,
 ,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,
 ,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,
 ,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,1,
 ,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,
 ,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1→L₁
:"1111111111111111
 1210001000100011
 1010101010101011
 1010101010101011
 1010101010101011
 1010101010101011
 1000100010001000
 1111111111111111→Str1

As you can see, the string map is the smallest of the three variables because you don't have to add all of the additional characters (the braces and the commas) like you do with the matrix and list. (You can actually get around this problem by storing your maps as a string, and then converting them to a matrix or list when you need to use them.)

How to Display Maps

Once you have your map stored in one of the variables, the next thing to do is to display it on the screen. The calculator has two different screens for displaying things — the home screen and the graph screen. The home screen is generally reserved for text, while the graph screen is generally reserved for graphics.

On the Home Screen

When displaying a map on the home screen, you use the Output( command together with a For( loop. You also need to decide what you want to display for the different things in the map. The easiest option is to just display the literal values stored in the map (i.e., 0, 1, 2, 3, etc.). A better option, although it's a little more complex, is to display a character that is representative of what the value stands for.

For example, in our maze map, we had spaces (0), walls (1), and the player (2). The spaces are what the player is going to be able to move on, so they naturally should not be displayed on the screen. A wall, on the other hand, is something that the player cannot move through, so it should be displayed on the screen. A good choice for a wall character is a 1 or an uppercase X. The player is what the user is in control of, so you want it to stand out. A good choice for a player character is an S or uppercase O.

Besides deciding what character you will use for each type of thing in a map, you also need to have a check for each one when displaying the characters. The most straightforward way to do this would be to have a separate If conditional that goes with each type of character. A better way to do this, however, is to put all of the characters in a string, and use the sub( command to access the appropriate character. For example, here is how you would display the maze from before:

:For(Y,1,8
:For(X,1,16
:Output(Y,X,sub(" XO",1+[A](Y,X),1
:End:End

As you can see, we decided to use an X for the walls and an O for the player. The other important thing to notice is that we used two nested For( loops to display the map. Since the maze is two-dimensional, two For( loops are needed: the first loop gets the Y-coordinates and the second loop gets the X-coordinates. Inside the second For( loop is where we access the respective (Y,X) coordinate of the matrix and display it using Output(.

Displaying a maze level stored in a list or string is very similar, but it requires you to use a simple formula to convert the respective coordinates on the screen: X+16(Y-1). For the string, you also need to use the sub( command to access the individual character in the string, and the expr( command to convert it to a number.

:Output(Y,X,sub(" XO",1+L₁(X+16(Y-1)),1
:Output(Y,X,sub(" XO",1+expr(sub(Str1,X+16(Y-1),1)),1

Where this formula comes from is that each row on the home screen is 16 characters wide, and the first row you just access the X coordinate by itself (i.e., when Y is 1, Y-1=0, and subsequently 16*0=0). If you create a similar map on the graph screen, you need to modify this formula to match the number of characters per row on the graph screen and to take into account that the graph screen coordinates start at zero.

Besides using the formula, the string can also be displayed one other way. The Output( command will wrap any text that goes over the 16 characters of a row to the next row (and likewise with that row), and subsequently you can use a single command to display the entire map across the whole screen.

Since every space is overwritten with the map, this does not require a ClrHome command to clear previously displayed characters. Unfortunately, there is no equivalent for the graph screen.

On the Graph Screen

Displaying a map on the graph screen is essentially the same as displaying a map on the home screen, except you can make the map much more detailed because the graph screen can be manipulated on a pixel level. There are several graphics commands available:

When displaying a particular part of the map, you can use a combination of these commands to create almost anything you want, whether it is a wall, a monster, a rock, or even a smiley face. For example, using our 8x16 maze level from before, instead of outputting the X character for the wall in the matrix, we can draw a wall using lines:

:For(Y,1,8
:For(X,1,16
:If 1=[A](Y,X:Then
:Line(4X-2,57-6Y,4X-2,53-6Y
:Line(4X-3,57-6Y,4X-3,53-6Y
:End:End:End

You should note that the window dimensions need to be X=0…94 and Y=0…62 for this example to show up correctly. In fact, with exception to the Pxl- and Text( commands, all of the graphics commands are dependent upon the window dimensions, so you should always use a friendly graphing window to ensure everything shows up as you intended.

There are several other ways to create graphics, and you should check out the graphics page for more information.

Where to Store Maps

After deciding on how you will store and display your maps, you then need to determine where you will store the maps: in the program itself or in a subprogram (or subprograms). When deciding which route to go, you need to think about how many maps you plan on having. If there aren't many maps (i.e., ten or less), they should usually all be stored in the program itself.

In the Program

For storing the maps in a program, you place each map inside its own If conditional and list the maps one after another. You then check to see which map the player needs and set up the variables for that map. Each map might also have some related information that goes along with it, such as the number of coins the player has to collect or the number of lives, so you would need to use an If-Then conditional instead:

:If A=1:Then  // Check if the player is at map 1
:{1,2,0,0,0,1,5,5,7,3,4,2,9,8,7,1→L₁
:3→B:4→C
:End

Once you have your maps stored in their individual conditionals, the next thing to do is decide where you you want to store them in the program. An obvious choice is just placing them right at the beginning of the program. In order to do this, however, it requires that you be able to access them. This normally entails placing a label before the maps, and then using a Goto to jump to them.

An important consideration when placing maps at the beginning of a program is what values you use for the If conditional variable. While you could use something simple like one or two, those values have a high probability of being accidentally entered in by the user or being set by another unrelated program, which would cause your program to store the respective map. What works better is to use random decimals (like .193 or 1.857) or math symbols (like e or π).

In a Subprogram

If there are several maps, you might want to consider placing them in a separate subprogram. The main reason is that when the maps are stored in the program, the program has to go through all of the code before the maps to reach a particular map. Depending on the size of the program, this can make for some major slowdowns in between maps. The internal maps also slow down the main program code itself.

Related to the first reason, the second reason to consider using a separate subprogram is that changing the maps is much easier in a subprogram. Instead of having to go through the entire program, looking for the map to change, you can just focus on one map at a time. This makes the maps more manageable, and also prevents you from accidentally changing other parts of the program.

The program code for the maps basically remains the same, it's just in another program. You might notice, though, that if you have lots of maps it takes a while for program execution to go back to the main program. This happens because program execution doesn't return to the main program until after it reaches the end of the program. You can fix this problem by placing the Return command at the end of each map conditional:

:If C=3:Then
:[[0,1,0][2,1,2][1,2,0→[B]
:3→A:3→B
:Return  // Stop program execution and return to main program
:End

Now that the maps are in a separate subprogram, you need a way to access them. When you want to access a map, you set the respective variable to the value of the map that you want, and then call the subprogram from the main program using the prgm command and the subprogram name:

:2→A
:prgmGAMELVLS

Unfortunately, storing the maps in a subprogram does have one major disadvantage. The user now needs another program to use the main program. If somebody tries to run the program and they don't have the maps subprogram, the main program will not work properly, and will actually return an ERR:UNDEFINED error when the program tries to call the non-existent maps subprogram. Even if this isn't your fault, the result is that your program looks very sub par.

Because of this problem, doing an all or nothing map separation (i.e., all of the maps are either stored in the program or in a separate subprogram) is usually a bad idea. The better alternative is to split up the maps so that the first ten maps (or so) are stored in the program, and the rest are stored in the subprogram. The user will now at least have some built-in maps to play, regardless of if they have the maps subprogram. The user simply won't have knowledge of the other maps available for them to play.

Sample Map-Based Game

This is a sample map-based game and the objective in each level is to get the "+" (plus sign), which causes you to advance to the next level. The game is played on the home screen using the arrow keys to move and CLEAR to quit. The maps are stored as lists in a separate program, along with the starting coordinates for your character.

(NOTE: Each list is all on one line, it's just split up to make it easier to read.)

PRGM:MAZELVLS
:If not(A:Then
:{1,2,1,1,1,1,2,2,1,1,1,1,1,1,1,1,
1,2,1,2,2,1,2,2,1,2,2,2,2,2,2,1,
1,2,1,2,2,1,2,2,1,2,1,1,1,1,1,1,
1,2,1,2,2,1,1,1,1,2,1,2,2,2,2,2,
1,2,1,2,2,2,2,2,2,1,1,2,2,1,1,1,
1,2,1,1,1,1,1,1,2,1,2,2,2,1,2,1,
1,2,2,2,2,2,2,1,2,1,2,2,2,1,2,1,
1,1,1,1,1,1,1,1,2,1,1,1,1,1,2,3→L1
:1→Y:1→X
:Return
:End
:If A=1:Then
:{1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,2,1,2,2,2,2,2,2,2,2,2,2,2,2,1,
1,2,1,2,1,1,1,1,1,1,1,1,1,1,2,1,
1,2,1,2,3,2,2,2,2,2,2,2,2,1,2,1,
1,2,1,2,2,2,2,2,2,2,2,2,2,1,2,1,
1,2,1,1,1,1,1,1,1,1,1,1,1,1,2,1,
1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1→L1
:8→Y:16→X
:Return
:End
:If A=2:Then
:{1,2,1,1,1,2,1,1,1,2,1,1,1,2,1,3,
1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,
1,1,1,2,1,1,1,2,1,1,1,2,1,1,1,2→L1
:1→Y:1→X
:End
PRGM:MAZE
:For(A,0,2
:prgmMAZELVLS
:" // 1 space
:For(I,1,dim(L1
:Ans+sub(" =+",L1(I),1
:End
:ClrHome
:Output(1,1,sub(Ans,2,dim(L1
:Repeat 3=L1(Ans+16Y-16
:Output(Y,X,"X
:Repeat Ans
:getKey→K
:End
:If Ans=45:Goto Q
:Output(Y,X," // 1 space
:min(16,max(1,X+sum(ΔList(Ans={24,26→C
:min(8,max(1,Y+sum(ΔList(K={25,34
:If 2≠L1(C+16Ans-16:Then
:Ans→Y:C→X
:End:End:End
:Lbl Q
:DelVar L1
:ClrHome
:"Lost
:If A=3
:"Winner

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/maps


Movement in Maps

Movement is commonly used in programs as a way to add user interaction. It is part of user input as it relies exclusively upon the getKey command to work. You can use movement in many programs and for many different things, including moving a cursor in a menu or moving a character around the screen. It is the latter case that we are going to explain and show here.

The Code

Homescreen

This is the basis for the code used in the two later examples. An explanation for why it works can be seen here.

:4→A
:8→B
:Repeat K=21
:getKey→K
:If Ans
:Output(A,B," // 1 space
:min(8,max(1,A+sum(Δlist(Ans={25,34→A
:min(16,max(1,B+sum(Δlist(K={24,26→B
:Output(A,Ans,"X
:End

Graphscreen

This is the same code as the first, but it has the graphscreen initialization process at the beginning, and you have to switch up the keypress codes.

:Zstandard
:104→Xmax
:72→Ymax
:Zinteger
:1→A
:1→B
:Repeat K=21
:getKey→K
:line(A,B,A,B,not(K
:min(94,max(0,A+sum(Δlist(K={24,26→A
:min(62,max(0,B+sum(Δlist(K={34,25→B
:End

Depending on what is being moved, the code might need to be revised. This particular code will move a pixel, or you can make it a line if you want. However, to move sprites, you will need to add to the coordinate variables instead. If you are moving a group of pixels, it would be ideal to hard code it.

Simultaneous Movement

Once you have learned how to create simple movement, the next natural step is to add some enhancement to make it more complex. One of the most common things desired is simultaneous movement — moving multiple things at the same time. Unfortunately, real simultaneous movement isn't really possible because of the limitations of the calculator, but you can emulate it.

When moving things, you need to be able to keep track of their position on the screen and the number of things. While the fastest way would be to use individual real variables for each thing, the best approach in terms of speed and size is a list and real variable respectively.

Before you initialize the list, it is good to consider how many things you want to allow on the screen at any one time. This is an important consideration because the more things you need to keep track of, the slower the program runs. A good range to shoot for is 5-15.

Here is what the code looks like so far:

:DelVar ADelVar L110→dim(L1

We are using the A real variable as the counter and the L1 list variable to keep track of the 10 object positions on the screen. We chose to initialize the list elements to 0 because that is our flag to determine if the object is active or not.

Now when you want to add another object, you simply need to increment the counter and then store the object's position on the screen to the list. You also need to remember to check that you haven't exceed the maximum number of allowed objects on the screen. You can combine the X and Y screen coordinates together into one list element using compression.

:A+1→A
:If A<11
:YE2+X→L1(A

You also need to check for when a thing goes off the screen. When this happens, you first look at the counter to make sure it isn't at 0, and then loop through the thing positions and move all the things to the previous list element. You then decrement the counter.

:If A>1:Then
:For(X,1,A-1
:L1(X+1→L1(X
:End
:A-1→A
:End

When moving these things, you simply loop through the positions list and then change the position of whatever thing you want. You basically are moving one thing at a time and then switching to the next thing once it is done.

Collision detection

If you want to restrict your character's movement so that it doesn't move through solid spaces such as walls, you will need some sort of collision detection. Since this example is on the home screen, the best method is to use a string. Create a string with 128 elements, leaving spaces for nothing, which will be represented as zeros for visual aid. Equal and unequal signs make good walls. Here is an example, a maze. For more info maps, go to the page making maps

:"================
  =000=000=000=0==
  =0=0=0=0=0=0=0==
  =0=0=0=0=0=0=0==
  =0=0=0=0=0=0=0==
  =0=0=0=0=0=0=0==
  =0=000=000=000==
  ================→Str1

Notice how the "maze" is set up so that the outer boundaries are all walls. The advantage of this is that it allows us to save space and speed on the calculator by removing the specific boundary check. The disadvantage is that it limits the amount of characters on screen to 6x14 instead of the full 8x16.

Now we can add the collision detection code in with our original movement code. You should notice that the main difference is the player's position for movement is checked to determine if the player is going to move onto an equals sign.

Notice how there is an extra argument after the Repeat. This allows us to have the character switch to the next maze when it reaches the end. You could also use this to switch to another map at the screen's edge.

:ClrHome
:4→A:8→B
:"================
  =000=000=000=0==
  =0=0=0=0=0=0=0==
  =0=0=0=0=0=0=0==
  =0=0=0=0=0=0=0==
  =0=0=0=0=0=0=0==
  =0=000=000=000==
  ================→Str1   //remember, 0's are spaces
:Output(1,1,Ans
:Repeat K=21 and AB=26   //AB=26 can be changed for different exit point
:getKey→K
:If Ans
:Output(A,B,"_  //One space, checks for key press and erases
:sum(Δlist(Ans={25,34
:A+Ans(" "=sub(Str1,16(A-1+Ans)+B,1→A   //If future coordinate is a space, it moves
:sum(Δlist(K={24,26
:B+Ans(" "=sub(Str1,16A-16+B+Ans,1→B
:Output(A,Ans,"X
:End
:"     //second maze

And you can repeat this until all your mazes have run through. In addition to using strings, you can also use lists, matrices, or hardcode the whole map in if statements. The code is fundamentally the same, except there is a different formula used to display the map on the screen and you also check the available spot with that formula. Again, just try to understand the code and play around with it.

On the graph screen, you cannot make a string for collision detection. Otherwise, you would be looking at a 5828 character string! Instead, on the graph screen, you can use a command called pxl-Test( to tell you what is in the next space being moved to.

The pxl-Test( command finds the status of a pixel on the graph screen returning a 1 if the pixel is on or a 0 if the pixel is off. Therefore, if you get a 1, the character shouldn't move to the next space. If the pxl-Test( is 0, then the character moves to the next space. The following code is the base of how this works, and you can alter it to add boundary checks or advanced sprite manipulation.

:sum(Δlist(K={25,34
:A+Ansnot(pxl-Test(A+Ans,B→A

References

  • Kerm Martian and his post at the UTI TI-Basic forum about keeping track of multiple shots.
  • darkstone knight's post which led to the latest few updates in the formulas.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/movement


Custom Text Input

Custom text input is used when you want to get input on the graph screen (or the home screen, if you don't like the look of Input or Prompt). As the Input and Prompt commands only work on the home screen, the only option available is to make your own text input routine.

The Basic Routine

The core of the text input routine is using the getKey command together with a string of acceptable characters organized to follow the order of the respective key codes, and then extracting one substring character and storing it to the outputted text string:

:" →Str1  // 1 space
:Repeat K=105
:Repeat Ans>40 and Ans<94 or Ans=105
:getKey→K
:End
:Ans-20-5int(.1Ans
:If 25>length(Str1) and 0<Ans and Ans<29
:Then
:Str1+sub("ABC  DEFGHIJKLMNOPQRSTUVWXYZ",Ans,1→Str1
:Text(10,1,Str1
:End
:End
:If 1<length(Str1
:sub(Str1,2,length(Str1)-1→Str1   //removes initial space

If that sounds confusing, please let me break it down for you. We first need to initialize the string variable that we will be using to hold the text the user inputs. You can use whichever one of the ten string variables (Str0-Str9) you want. The reason we initialize the string with a single character is because the calculator returns an error if you have a null string.

:" →Str1

We now begin the main program loop. The program will loop until the user presses ENTER. After that, we loop until the user presses a letter key (as all letters are assigned key codes from 41 to 93) or ENTER.

:Repeat K=105
:Repeat Ans>40 and Ans<94 or Ans=105
:getKey→K
:End

After the user has pressed one of the necessary keys, we then need to take the respective action in the program. If the user pressed one of the letters of the alphabet, we first check to see that the string is not already at the end of the screen (i.e. its length is 25). If it is less than 25, we add that text to our string variable and display the whole string:

:Ans-20-5int(.1Ans
:If 25>length(Str1) and 0<Ans and Ans<29
:Then
:Str1+sub("ABC  DEFGHIJKLMNOPQRSTUVWXYZ",Ans,1→Str1
:Text(10,1,Str1
:End

We finally close the main program loop. This text input routine just has basic functionality, as it was designed to show you how to do custom text input. It's up to you whether you want to extend it to include a larger range of acceptable characters, word wrapping, or whatever feature you want to include.

Tweaking the Routine

These are advanced features for a custom text input routine.

Backspace functionality

The above routine is very limited: once we type something in, we can't go back and change it. This add-on allows the user to press the DEL (delete) key to delete the last letter typed. To add this functionality, change the first loop code from ":Repeat Ans>40 and Ans<94 or Ans=105" to ":Repeat Ans>40 and Ans<94 or max(Ans={105,23", and add the following code right before the final End that terminates the outer loop.

If the user pressed the DEL key, we first check that the string variable has at least one character already in it (so an error isn't returned), and then remove the last character at the end of the string and redisplay the string (erasing the three spaces to the right of the last character left behind from the deleted character):

:If K=23 and 1<length(Str1 //if DEL pressed and some letters have been entered
:Then
:sub(Str1,1,length(Str1)-1→Str1
:Text(10,1,Str1,"   //three spaces after the "
:End

Flashing Cursor

A flashing cursor makes it clear that you mean business, or that you mean for the user to type in text. The code for a flashing cursor should replace the ':getKey→K' in the basic routine. You must also replace 'Ans' in ':Repeat Ans>40 and Ans<94 or max(Ans={105,23' with 'K'. 'K' must also be added onto a new line after the second 'End' after the code below. This is because the new variable 'I' messes with 'Ans'.

We start the routine normally: repeat until a key is pressed. The two Text( statements will draw a [ then erase its two tails, effectively drawing a horizontal bar. The For( loop creates an artificial delay between drawing and erasing the cursor. However, we want to end the loop if a key is pressed (so we don't have to wait until the cursor finishes flashing to type in a key). That's what the I+5Ans→I statement does: if K isn't 0, it will make I greater than 30, which will end the loop. We want to erase the cursor if a key was pressed or if I=16 (halfway through the delay loop). Finally, we end both loops.

:Text(10,4length(Str1)-2,"[
:Text(10,4length(Str1)-1," //1 space after the quote
:For(I,1,30
:getKey→K
:I+5Ans→I //if K isn't 0, I will go out of bounds, ending the loop.
:If I=16 or K
:Text(10,4length(Str1)-2," //1 space after the quote
:End

Adding Number Functionality

Although this routine differs from the one above, it accomplishes the same thing. Again, thanks to DarkerLine for the keypress to letter formula. Harrierfalcon came up with the formula to convert keypresses to numbers.

:ClrDraw
:DelVar A15→B
:Text(1,82,"             
:Text(0,82," LET
:" →Str1
:Repeat max(M={45,105,21
:‾5→C
:Repeat M=23 or max(Ans={21,45,105}) or (not(A)M>40 and not(A)M<95 and M≠44) or max(AAns={92,93,94,102,82,83,84,72,73,74
:C+1-10(C>4→C
:Text(29,B,sub(" [",1+(Ans>0),1
:Text(29,B+1," 
:If M=31
:Then
:not(A→A
:Text(0,83,sub("LETNUM",3A+1,3
:End
:getKey→M
:End
:If min(M≠{21,105,45,23
:Then
:If A
:Then
:sub("0123456789",27-3int(.1M)+10fPart(.1M)+2(M=102),1
:Text(29,B,Ans
:Str1+Ans→Str1
:B+4→B
:Else
:sub("ABC  DEFGHIJKLMNOPQRSTUVWXYZθ",M-5int(.1M)-20,1
:Text(29,B,Ans
:Str1+Ans→Str1
:B+4→B
:End
:Else
:If M=23 and 1<length(Str1
:Then
:B-4→B
:Text(29,Ans,"      
:sub(Str1,1,length(Str1)-1→Str1
:End
:End
:End

A=1 if NumLock is enabled, and A=0 if AlphaLock is enabled. Allow me to break it down.
:ClrDraw
:DelVar A15→B
:Text(1,82,"             
:Text(0,82," LET
:" →Str1

I'll let you guess on this one.
:Repeat max(M={45,105,21
:‾5→C

This resets the cursor counter, and initializes the loop that won't quit until [ENTER],[2ND], or [CLEAR] is hit.
:Repeat max(Ans={23,21,45,105}) or (not(A)M>40 and not(A)M<95 and M≠44) or max(AAns={92,93,94,102,82,83,84,72,73,74

This initializes the loop which won't quit until proper keys other than [ENTER], [2ND], [CLEAR], or [DEL] is hit.
The second boolean value is structured so that if A=0, it means AlphaLock is enabled, and if a letter key is pressed, then it will exit the loop. If A=1, then it won't work, because not(A)M will equate to 0 every time. If [VARS] is pressed, nothing happens, because there is no letter there.
The second Boolean value was created in a fashion that tells if A=1, then M is left alone. If it is not, then it doesn't count.
:C+1-10(C>4→C
:Text(29,B,sub(" [",1+(Ans>0),1
:Text(29,B+1," 
:If M=31
:Then
:not(A→A
:Text(0,83,sub("LETNUM",3A+1,3
:End
:getKey→M
:End

The first line increments C, and returns it to -5 if C=5.
The second line outputs [ or a space, if C<= 0 or C>0, respectively.
The third line clears the bracket's tails, or does nothing.
Lines 4-8 toggles AlphaLock and NumLock, and updates the display.
:If min(M≠{21,105,45,23
:Then
:If A
:Then
:sub("0123456789",27-3int(.1M)+10fPart(.1M)+2(M=102),1
:Text(29,B,Ans
:Str1+Ans→Str1
:B+4→B
:Else

This If-Then is executed only if [2ND],[DEL],[ENTER], and [CLEAR] were NOT pressed. This prevents garbled numbers with would cause ERR:DOMAIN. This is executed only if NumLock was on.
:Else
:sub("ABC  DEFGHIJKLMNOPQRSTUVWXYZθ",M-5int(.1M)-20,1
:Text(29,B,Ans
:Str1+Ans→Str1
:B+4→B
:End

This is executed if NumLock was NOT on, i.e. if AlphaLock was on.
The rest shouldn't have to be explained. Optimizations are out there…can you find them?

Advanced Editing Functionality

This routine adds several features that are not in the other versions. It allows for uppercase and lowercase text with switching in between them. It allows the user to move the cursor throughout the text and insert text and delete text where ever they would like. The user can also clear the current text and start over. Unfortunately, the code is a little hard to decipher, but we'll work through it. The main deficit of this program is that it is incompatible with the TI-83. This can be remedied, as explained below.

:"ABC  abc  DEFGHdefghIJKLMijklmNOPQRnopqrSTUVWstuvwXYZ(Theta)!xyz(Theta).  :?   :? →Str0
:"  →Str1   // 2 spaces in quotes
:DelVar M1→P
:Repeat K=105 and 2<length(Str1
:Text(0,0,sub(Str1,1,length(Str1)-P)+"|"+sub(Str1,length(Str1)-P+1,P)+"        // 5 spaces after quote
:Repeat Ans
:getKey→K:End
:P-(K=26 and Z>1)+(K=24 and Z<length(Str1)-1→P
:M xor K=31→M
:If K>40 and K<105 and K≠44 and K≠45
:sub(Str1,1,length(Str1)-P)+sub(Str0,K-40+5M,1)+sub(Str1,length(Str1)-P+1,P→Str1
:If K=23 and P<length(Str1)-1
:sub(Str1,1,length(Str1)-P-1)+sub(Str1,length(Str1)-P+1,P→Str1
:If K=45:Then
:"  →Str1   // 2 spaces in quotes
:1→P
:End
:End
:sub(Str1,2,length(Str1)-2→Str1

The first three lines take care of variable initialization. M stores whether capitals are enabled or not. M = 0 if its uppercase, M = 1 lowercase. Str0 contains all the uppercase and lowercase letters, including information for the last row of keys on the calculator. Str1 is the string that the text will be stored in. The information will be between the two space characters so that we can insert information at the beginning and end without having problems. P is the number of places before the end of the string to place the cursor. This is the most crucial variable, this will allow for the painless insertion of text and deleting of text anywhere in the string.
TI-83 Compatibility: Change Str0 to be the string listed above for the basic routine ("ABC DEFGHIJ…."). This, along with the other change listed below, will make this TI-83 compatible.
:Repeat K=105 and 2<length(Str1

This repeats until [ENTER] is pressed and makes sure that text has been entered into the string before exiting.
:Text(0,0,sub(Str1,1,length(Str1)-P)+"|"+sub(Str1,length(Str1)-P+1,P)+"        // 5 spaces after quote

This displays the text at 0,0 on the graph screen. This is a difficult line so let's break down what is being outputted onto the screen.
sub(Str1,1,length(Str1)-P)+"|"+

This returns all the characters that are before the cursor and then outputs the cursor
sub(Str1,length(Str1)-P+1,P)+"        // 5 spaces after quote

This returns all the characters that are after the cursor and then outputs some spaces. The spaces are there because when delete is pressed, the string will get smaller, and some characters will be left over. This is to cover those characters up.
The next two lines just get the key press and store it into the variable K.
:P-(K=26 and Z>1)+(K=24 and Z<length(Str1)-1→P
:M xor K=31→M

The first of these two lines control the movement of the cursor (stored in P). If the right arrow is pressed then P will decrement, less spaces from the end of the string. If the left arrow is pressed then P will increment, more spaces from the end of the string. The other conditions make sure that the cursor doesn't go too far in either direction.
The second of these lines controls the current capitalization state. By using the xor command, M will switch back and forth between 1 and 0 (lowercase and uppercase, respectively) every time the [ALPHA] key is pressed.
:If K>40 and K<105 and K≠44 and K≠45
:sub(Str1,1,length(Str1)-P)+sub(Str0,K-40+5M,1)+sub(Str1,length(Str1)-P+1,P→Str1

These lines test to see if the key press is a letter key and then inserts the letter into the string. The second line concatenates three strings together. The first is all the characters before the cursor. The second is the letter that was pressed (found in Str0). The third is all the characters after the cursor. This is all stored back into Str1.
TI-83 Compatibility: In order to make this compatible with the TI-83, change the middle string that is concatenated to sub(Str0,K-20-5int(.1K),1). This, along with the other change, listed above will make this TI-83 compatible.
:If K=23 and P<length(Str1)-1
:sub(Str1,1,length(Str1)-P-1)+sub(Str1,length(Str1)-P+1,P→Str1

These lines test to see if [DEL] was pressed and then deletes a character from the string. Since the character deleted is from behind the location of the cursor, the conditional tests to see if the cursor is at the beginning of the text (where there is no character before the cursor). The second line concatenates two strings together. The first is all the characters before the cursor minus the last one (the character being deleted). The second is all the characters after the cursor. This is all stored back into Str1.
:If K=45:Then
:"  →Str1   // 2 spaces in quotes
:1→P
:End

These lines test to see whether [CLEAR] was pressed and then clears the text accordingly. Both Str1 and the location of the cursor are reset to their original values.
After this line, the main loop ends.
:sub(Str1,2,length(Str1)-2→Str1

This line removes the extra space on each end of the string and returns Str1.

If you want to let the user view the current capitalization state, add the following line before the getKey loop.

:Text(55,90,sub("Aa",M+1,1

The coordinates can obviously be changed to place this anywhere around the graph screen.

References

  • DarkerLine came up with the formula for translating the letter keys into the short string.
  • Harrierfalcon created the formula to convert number keypresses into a short string.
  • Zaphod Beeblebrox created the advanced editing functionality routine.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/custominput


Graphics

There is only so much that can be shown with text alone: sooner or later, any kind of program, whether it is a game or a complicated math tool, will have to use graphics. The purpose of this page is to describe the various methods of rendering graphics, along with their advantages and disadvantages. In many cases, you'll find that no one method suits your needs perfectly, and they will need to be combined to produce something that looks good without sacrificing too much speed or memory space.

Picture Variables

The simplest and fastest way to display just about any image is to save it in a picture variable beforehand, and then use the RecallPic command to instantly display it to the screen. There is no choice in positioning the picture, or displaying anything smaller than the entire screen, so this method is mostly limited to title screens.

The main advantages of this method are:

  • The speed — no other TI-Basic instruction can fill the screen as quickly.
  • The image can be made as complex as desired, without loss of performance.

However, there are numerous drawbacks:

  • Each picture variable uses 767 bytes of precious memory.
  • Furthermore, the picture is stored outside the program, where it can be overwritten.
  • There are only 10 picture variables to be shared between all TI-Basic programs.
  • The picture is static and can't be moved around the screen easily.

There are several ways to get around this problem. A decent solution is to use groups to keep the program and its pictures together and backed up — this ensures that even if a picture is overwritten, that this will not be permanent. Another possibility is to hope that there won't be any other conflicting programs to cause problems.

An example of picture variables at their best is the title screen in Contra: the image is too complicated to reproduce easily in any other way, and the result has become iconic of the game.

Hard-coded Sprites

Hard-coded sprites are, in a sense, the other extreme to go to. The idea is to write out the specific commands (usually, ones like Pt-On( or Pxl-On( to display an image. A friendly window might be useful. Here is an example, drawing a smiley face near the coordinate (X,Y):

:Pt-On(X,Y,2)
:Pt-On(X+2,Y,2)
:Pt-On(X,Y-2,2)
:Pt-On(X+2,Y-2,2)
:Pt-Off(X+1,Y-2)

Unless the image only needs to be drawn at one point, adding variables such as X and Y above is useful, allowing the same code to draw the same thing at multiple locations. It should also be noted that the Pt-On( and Pt-Off( commands have an optional third argument that allows you to draw a 3x3 box or cross (using 2 or 3, respectively), which is smaller and faster than the individual composite commands.

The advantages of this approach are:

  • It is very flexible: no matter the image, it can be drawn with some amount of commands.
  • It is still fairly fast, although slower than RecallPic.
  • It's easy to make a sprite that moves around on the screen.

The drawbacks, on the other hand, are:

  • Of all the methods on this page, this one uses the most memory.
  • The more complex the image, the more commands it will require to draw.
  • Every different image requires its own instructions, complicating program logic.
  • It's easy to make a mistake or typo, and hard to fix one.

A good use for hard-coded sprites is a fancy cursor in a menu: these are usually small and relatively simple, don't require many different images, and play to the strengths of hard-coded sprites. You can also combine hard-coded sprites with compression to reduce the number of graphic commands needed, although it often causes a hit to the program speed.

Plot Sprites

A somewhat different idea for rendering graphics, plot sprites use the Plot#( commands to draw multiple points or multiple lines very quickly (taking a shortcut, so to speak, to the approach above). In this case, all of the information to draw the sprite (that is, the coordinates of the points or lines) is stored in a pair of lists. Since plots use point coordinates, a friendly window may be useful.

To display a sprite, first store the coordinates to two lists (this article will assume they are L1 and L2). Next, set up the plot variable with Plot#(Scatter,L1,L2) (to draw points at the coordinates) or Plot#(xyLine,L1,L2) (to connect the coordinates with lines). Then, the DispGraph command will update the graph screen with all the plots that are currently in use. There are three plots available, which can be switched on and off with the PlotsOn and PlotsOff commands.

Here is an example of the same image displayed using plot sprites:

:{4,0,0,4,4,4,0,2,2}→L1
:{0,0,4,4,0,2,2,2,4}→L2
:Plot1(xyLine,L1,L2
:DispGraph

Plot sprites are uniquely suited to being moved around the screen: once the setup phase is done, just modify the lists slightly and then use DispGraph again to draw the sprite at a different location, erasing it from where it was. Just using simple arithmetic on the lists lets you move, reflect, rotate, and stretch a sprite. The table below shows the formulas required (some intuitive, some not):

Transformation Formula
Horizontal translation A+L1→L1
Vertical translation B+L2→L2
Reflection about the x-axis -L1→L1
Reflection about the y-axis -L2→L2
Rotation 90°
clockwise
L1→L3
-L2→L1
L3→L2
Rotation 90°
counterclockwise
-L1→L3
L2→L1
L3→L2
Rotation by an angle of θ L1cos(θ)-L2sin(θ)→L3
L1sin(θ)+L2cos(θ)→ L2
L3→L1
Horizontal stretch AL1→L1
Vertical stretch BL2→L2

The advantages of using plot sprites are:

  • The image data is stored in variables (lists), so the same code can display any sprite.
  • Plot sprites are usually smaller than hard-coded sprites, at a comparable speed.
  • As named lists, images can be saved outside a program without fear of being overwritten.
  • The sprites are uniquely easy to move (arbitrary rotation, for instance, is only possible with plot sprites)

The drawbacks are:

  • Since there are only three plots, only three independent sprites can be displayed at a time.
  • Plot sprites don't work well with other graphics: DispGraph erases most things drawn on the graph screen.
  • DispGraph erases before drawing, producing noticeable flicker.
  • On the color calculators, plot sprites can only display one color.

There are two main avenues for plot sprites. The first is for displaying an image that won't have to be moved around (such as a title screen): this avoids the two problems that DispGraph causes. The other is for displaying a few images in complex motion, where the transformations can really come in handy.

Text Sprites

Text sprites are the most bizarre method (known so far) of displaying graphics. They are efficient in a very limited application: displaying small (usually 5x5) images without the drawbacks of hard-coded sprites. The idea is to display several characters very close to each other using the Text( command, so that the first pixel column of each character is combined into an image. For example:

:"([X[("→Str1
:For(X,1,5)
:Text(0,X,sub(Str1,X,1))
:End
:Text(0,6,"  ")

To understand what is going on, add a Pause command in the For( loop, and watch the image being drawn piece by piece.

When dealing with text sprites, the image data is stored in strings (in the example above, storing any other 5-character string to Str1 will produce a different 5x5 sprite). In fact, using properly chosen characters (see this chart), nearly any sprite with 5 rows (since small text characters are 5 pixels tall) can be displayed, with only a few rarely-encountered exceptions.

The advantages of using text sprites are:

  • At 5 pixels per byte (usually), they are the most efficient method of storing small images.
  • The sprites are not made up of points and lines, so they can be fairly detailed.

The drawbacks are:

  • Text sprites are usually slower than hard-coded sprites to display.
  • They are limited to a 5xN size, which makes them less flexible than other methods.
  • Displaying a text sprite erases a small space to the right of the sprite (this can be avoided with caching — see below).
  • Code to produce text sprites is harder to learn and understand.
  • It is extremely difficult to use text sprites on color calculators, as these use smaller pixels.

Tilemaps are a good application for text sprites: the code for hard-coded sprites would be too large and unwieldy, and plot sprites are too limited in number. This is demonstrated in Donut Quest, a puzzle game whose graphics play to the strengths of text sprites while avoiding situations that would highlight their drawbacks.

Recently, someone came up with the idea of vertical sprites. It uses the same idea but it displays sprites from bottom to top. You can find more information in the Text Sprites page.

Layered text sprites

Similarly to text sprites, layered text sprites (also referred to as dual-layer ASCII sprites) use the Text( command in order to display custom sprites very efficiently and are usually used in order to display an entire level at once rather than to draw a single isolated sprite due to their limitations, however they are faster than most methods for displaying large images and use very little memory (2 bytes for a single sprite). The idea is to draw a first layer of large font characters, saving them using StorePic, drawing a second layer on top of them and finally using the RecallPic command to join the 2 layers together, creating an horizontal line of sprites. For example:

:”NNNHHH”→Str1
:”OOOOOI”→Str2
:Text(-1,1,1,Str1)
:StorePic1
:Text(-1,1,1,Str2)
:RecallPic1

A variation of this method can be found in the game Serenity, where the second layer is shifted 1 pixel to the right, allowing the creation of 6x7 sprites and the removal of the gaps created between sprites when using the regular method.

Advantages

  • Each sprite only uses 2 bytes of memory
  • Due to the fast rendering speed of layered text sprites, they allow the entire screen to be filled very quickly, making them useful for drawing an entire level at once
  • The sprites allow for a lot of detail compared to other methods

Drawbacks

  • They are limited to a 5x7 or a 6x7 size, making them less flexible than other methods
  • Only a few different characters can be used, limiting the amount of shapes possible
  • Code to produce layered text sprites is harder to learn and understand
  • They are inefficient for displaying individual sprites

Due to the drawbacks of this method, layered text sprites are mostly used by platformers whose graphics resemble the home screen, such as Zoith, Metroid Pi and Serenity, for their ability to fill the graph screen very quickly when moving to a new screen.

Assembly Libraries

The fifth way to render graphics is to use an assembly library such as xLIB which includes sprite routines. These routines typically do what we all wish RecallPic could do: nearly instantly recall a small piece of a picture variable to an arbitrary part of the screen, often with extra features thrown in.

Choosing a library to use for your program involves trade-offs: an obscure program might have all the features you want, but a popular library will be used by other games as well. Users probably wouldn't mind installing one library to play a bunch of cool games, but if every game uses its own assembly library, managing them becomes tricky (particularly because they may interfere with each other).

The advantages of using assembly libraries for graphics are:

  • They are fast: usually faster than RecallPic, and definitely faster than any other method.
  • They are versatile: once you make the decision to use a library, it can be applied to any situation.

The drawbacks are:

  • An assembly library takes up lots of memory (not as much of a factor on newer calculators).
  • Typically, you will have to use a picture variable, with all the drawbacks that entails.

It's best to use assembly libraries only for graphics-intensive programs. If you do decide to use an assembly library, make as much use of it as possible: there's usually no point in going halfway and mixing an assembly library with any of these other tricks.

Advanced Techniques

Caching: with almost all of these methods, it takes some time to display an entire screen's worth of graphics. If there's a chance that this screen will have to be displayed more than once, it makes sense to avoid doing the extra work of drawing it all over again. To prevent this, take any unused picture variable, and use StorePic to save the current state of the screen. Then if it ever needs to be redrawn, RecallPic the screen instead of rendering it the normal way. This technique makes sense for a title screen (if it wasn't a picture variable already) or for the initial state of a level of a game (in case the player restarts).

A similar technique can be used when drawing one image will erase another part of the screen, and both are necessary. In this case, StorePic the screen, draw the image, and then RecallPic. Because RecallPic uses "OR" logic (a fancy way of saying it doesn't ever erase dark pixels), this will keep the background while still drawing the new image. This is critical when combining plot sprites with any other method, and often comes in handy with text sprites as well.

Greyscale: if a pixel flashes on and off very quickly, it will appear grey to the eye (because erased pixels need time to fade to white). Switching back and forth between two or more pictures gives the effect of using three colors (black, white, and grey) on a calculator that can normally only handle two. Because this needs to be done quickly, usually only programs using assembly libraries attempt this. An example using xLIB:

:Repeat getKey
:For(N,1,2)
:real(3,N,0,1)
:End
:End

In this case, pixels that are on in both Pic1 and Pic2 will be displayed as black; pixels that are off in both of them will be displayed as white; pixels that are on in one and off in the other will be displayed as grey.

With precise timing, this technique can be improved to produce multiple shades of grey. Suppose that in this example, Pic2 were displayed twice as long as Pic1. In that case, black and white pixels would be the same; however, a pixel that was on in Pic1 and off in Pic2 would be on 1/3 of the time, while a pixel that was on in Pic2 and off in Pic1 would be on 2/3 of the time. This would give four colors:

State in Pic1 State in Pic2 Result
off off white
ON off light grey
off ON dark grey
ON ON black

Even more shades are possible, but the more complicated the code, the worse the flicker. If you try for too much, eventually the "greyscale" will turn into two pictures quite obviously alternating onscreen. Given the limitations of TI-Basic, it might be best to stick to 3-color greyscale.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/graphics


Program Protection

Disclaimer: Program protection not only is rather limited in its effectiveness, but also acts as a hindrance towards maintaining the open and collaborative nature of the TI-Basic community: allowing others to study and learn from your code, and to use the techniques and concepts in their programs, increases the quality of TI-Basic programs being released.

You've just finished working on your latest, greatest program. You put in a lot of time and effort creating the program, and now you want to enjoy the fruits of your labor — showing it off to your friends at school. When your friends try the game, you get positive feedback and they tell you how much fun it is, and even ask if you could put the game on their calculators.

Now, you don't mind putting the game on your friends' calculators, but you want to make sure that no one can mess with it. Once the game is out amongst the school crowd, you know that other people will want the game so you need to come up with a way to protect your program. Fortunately, there are several ways to protect a program.

Before getting to program protection, the first thing you need to do is edit lock your program. You can edit lock a program using either one of the several downloadable assembly programs or the Graph Link software made by TI. It goes without saying that you should never give someone an editable version of your program.

Once your program is edit locked, now you can add a security function. Although there are several ways to protect a program, they each have varying degrees of complexity and success. The general rule is that the more complicated the protection is, the more difficult it will be for someone to circumvent it.

Put the Code Together

Arguably the simplest, yet most crude program protection method is just putting all of the code in the program on one line. You might recognize this as utilizing compact style, except this time it serves as a program safeguard instead of a stylistic choice.

In order to put code together, you need to separate each command with a colon (:). The colon closes everything except a literal string, in which case the colon will actually be included as part of the string. In order to prevent this from happening, you need to close the string with a quote before adding the colon.

:If A=2:Then
:Disp "Hello
:not(B→B
:End
can be
:If A=2:Then:Disp "Hello":not(B→B:End  // Note the closed string

There is one command that doesn't need a colon following after it — DelVar — but leaving it off can cause some problems. DelVar's are typically chained together with one variable after another (i.e., DelVar ADelVar B), but the DelVar command also allows you to take the command from the next line (it doesn't matter what command it is) and put it immediately after the DelVar (i.e., DelVar ADisp "TI-Basic").

This works for the majority of commands, but there are two cases in which the command will actually be ignored: the End from an If conditional and a Lbl command. Both of these cases can cause your code to not work correctly anymore, and so you should either add the appropriate colons between the DelVar's or re-organize your code to eliminate the situation entirely.

:If not(X:Then:-Y→Y:DelVar ZEnd
can be
:If not(X:Then:DelVar Z-Y→Y:End  // Note DelVar's position

When you put the code together it will wrap around to the next line (and keep wrapping around for however many lines are needed), which is useful because the average calculator user will not be able to read and understand the code then. More importantly, if they press a key to try to mess with the code it can have dire consequences. Specifically, if the user presses CLEAR, the whole line of code (i.e., the entire program) will be deleted.

Entering a Password

If putting all of the code together on one line seems rather complicated (and maybe not worth all that effort), a simpler program protection method is having the user type in a password at the beginning of a program. You then check the password against the stored password and allow the person to play the game if the passwords match or exit back to the home screen. You can have the password be whatever you want.

:"5552646472→Str1    // Store the password to a string
:For(X,1,.5length(Str1    // Loop every two characters for a key
:Repeat Ans
:getKey
:End
:If Ans≠expr(sub(Str1,2X-1,2    // Check if the user typed the wrong key
:Stop    // Stop the program and return to the home screen
:End

When editing the password string, you must keep the length divisible by two because of the For( loop and the If conditional check. Besides that, this code does not allow keys 102-105 to be included in the password. That shouldn't be too big of a problem, though.

Entering Seeds

You can use pseudo random number sequences as a sort of password protection. After seeding the rand command, the results generated will be unique to the seed that was chosen. If the seed takes on the behavior of a password, then a comparison of the rand function to one of its precomputed results will act as an authentication for that password.

For instance, 5→rand followed by a single use of rand will return .727803… on all calculators, so a test can be devised as follows:

:Input X    // Request a number
:X→rand    // Seed the random number generator
:If rand≠.7278038625    // Check if the first random number is not equal to this value
:Stop    // Stop the program
or
:If rand≠.7278038625
:Stop

Only when the user inputs the correct seed (or in the latter case, stores the correct seed to rand before running the program) will he be able to venture past this part of the code. The upside to this technique is that even if he does see the code, he won't be able to figure out what the password is just by looking at that number.

Going further with this, you can test for a result that is obtained only after a specific number of numtrials (i.e., uses of the rand command). After storing 7 as a seed, the third result will be .577519…, so having a test similar to the one shown above will mean that the code that follows it will only work on its third execution after the seed is stored manually — adding another layer of obscurity.

Hash Functions

While using the seq( command, the calculator can still interpret keypresses and store them to getKey. One possible way you can use this feature is to make a password function that asks the user to enter in the correct password before time expires:

:DelVar L1seq(getKey,X,1,200→L2
:For(A,1,dim(Ans
:L2(A
:If Ans:Ans→L1(1+dim(L1
:End
:If 5=dim(L1
:If max(L1≠{55,52,64,64,72
:Stop
:"Success!

The main problem with using this routine is that you have to create a huge list to have enough time to input a reasonable password. This can be fixed by replacing seq(getKey,X,1,200 with something that goes a little slower:

:seq(getKey+0rand,X,1,100)
:seq(getKey+0dim(rand(2)),X,1,100)
...

This does lose a bit of sensitivity, but this isn't a huge problem because the routine has a lot of sensitivity to begin with. Even adding +0dim(rand(2)) left the code still sensitive enough that it recorded every keypress of me simply brushing a finger across the keyboard of my TI-83+.

Put this together with the idea that we don't want to store the password itself (because that would be fairly easy to figure out), but rather a hash of the password — a numerical equivalent value for the password. This is easier than extracting the nonzero elements of a list. For example, sum(√(Ans is a decent option that doesn't care about the order of the keypresses. If you want an option that does, take cumSum(Ans)not(not(Ans first — this multiplies the last keypress by 1, the next-to-last by 2, the one before that by 3, and so on.

Here is an example:

:ClrHome
:Disp "Input Password
:seq(getKey+0dim(rand(2)),I,1,50
:If 106.322402=sum(√(cumSum(Ans)not(not(Ans
:"Success!

This example will display the message Success! if you enter the password AWESOME. Obviously, one of the main programs with using a hash function is coming up with the different hashes for the passwords, so here is a program that will assist you in making the hashes:

:{0→L1:0
:Repeat Ans=105
:If Ans
:Ans→L1(1+dim(L1
:getKey
:End
:sum(√(cumSum(L1
:DelVar L1Ans

Input your password and then press ENTER to get the appropriate number to test against.

Example password: HAL
Hashed result: 29.8632681

By replacing 106.322402 in the hash password program with 29.8632681, the password will be reconfigured to HAL.

Self-Modifying Code (SMC)

Another way you can protect your program is by using self-modifying code. SMC makes your code more difficult to understand, and by placing code inside a graphing variable, you are essentially hiding it. This prevents somebody who's not very knowledgeable from figuring out what it is.

A good example of this is where you have an If conditional, and you replace part of the condition with a graphing variable:

:If Xnot(Yint(rand
can be
:"not(Yint(rand→u
:If Xu

If this conditional is inside a loop, then you can modify the u variable later so that its code is something different when the If conditional is checked next time. For the average calculator user, this will make your code seem obfuscated, and they will be hesitant to mess with it.

Causing an Error

Depending on the protection used, you usually want to implement an error when it has been breached. The simplest error would be a message to the user. <error status> can be anything you want: see the methods below for when to cause an error.

:If <error status>
:Pause "ERROR! UNAUTHORIZED USE DETECTED!
:Stop

Unfortunately, this method allows the user to know when the error occurred and remove the error code by pressing ON when the error is displayed. A more secure method uses an error caused by the calculator that cannot be traced to specific code. The drawback of this method is that a custom error message explaining the problem cannot be displayed.

:If <error status>
:Goto XX

This code will cause a program to display ERR:LABEL because there is no label XX. It is one of the few errors that does not have the option to go to the code causing the problem, which makes it more secure. An experienced user will most likely be able to find the problem Goto, however.

The most complicated method of causing an error is to embed pieces of code that cause problems when <error status> is true. In the examples below, problems are caused when X≠20 (replace this with whatever condition you want). Unless the user is an expert, it will be difficult for the user to fix the errors.

:If 21=getKey(X=20    // Clear getKey
:L1(X=20→LSAVE    // Prevent saving
:A+X→A    // Use as a replacement to A+20→A
:max({17,21,35,42,55}=seq(5Aint(B(X=20)/fPart(C
    // Screw up a complicated command
    // Extremely difficult for someone else to figure out

Another option is to quit the program immediately. This is most effective in a large program, where users will have to pore through hundreds if not thousands of lines of code to find the problem code. In addition, make the program jump to the default quit routine instead of a new one to confuse users even more.

:If L1(31)=5    // Quit condition test
:Goto XX    // Default quit label
...    // Whatever code is in between the Goto and matching Lbl
:Lbl XX
...    // Stuff to do before quitting
:Stop

Storing the Protection Status

The other program protection methods all require one variable in which to store the protection status (the number of times the program has run for a "trial period", whether it is protected or not, etc.). You can use any variable for this, but each has its own advantages and disadvantages: a custom list is best (but somewhat difficult to implement) and a finance variable is second best.

  • Regular variables — Have the advantage of being readily accessible, but are not very suitable because they are frequently overwritten by other programs.
  • Finance variables — Built-in to the calculator and are somewhat hidden, so they are unlikely to be erased. You can access these variables by going into the Finance menu. The only uses of the finance variables are the Finance Application and other programs. If another program is using the finance variable you want to use, either use a different one or change the other program. However, all the finance variables are reset to zero when the RAM is cleared.
  • Custom Lists — Can be archived, and it is unlikely that some other program would use the same list name. However, the list is visible in the Memory Management menu, and a perceptive user may realize that it is being used for program protection and change it. To counter this, you can hide the value among other values in another list used by your program (for example, save lists).

Trial Periods

If you wanted your program to only run a certain number of times (a trial period), you will have to have a counter that counts the number of times the program has run and produce an error when the limit is reached. (See above for a discussion on which counter to use.) For this example, we will use the finance variable n for simplicity. Add something like this to your program:

:n+1→n    // Increment the counter
:If n>5    // If this is past the fifth time, free trial is over
:Goto XX    // Replace this with any of error methods explained above

That's it. The above code will cause an error message to be displayed after the user has reached the end of the trial period (used the program five times). You can change this however you want to fit your needs. Since the increment comes after the error, it will continue erring each time it is run.

Authorization Required

You can also set up your program so that only authorized/licensed users can run it. This method can be combined with the above method: Users can use the programs until their free trial is up and they have to become "authorized." To "authorize" an individual calculator, set n to a predetermined value.

There are two ways of doing this: either type in the value manually (and use Clear Entries afterwards to prevent the user from discovering it), or transfer n as part of a group containing your program.

:If n≠20    // If n=20, the calculator is "authorized"
:Goto XX    // If not, cause problems
    // You can replace this with any of the errors mentioned above

You can also use this method to lock some of your program's features in the "unauthorized" versions. For instance, in this example every user can use feature one (which is part of label 1) while only authorized users can use feature two (which is part of label 2):

:Menu("MAIN MENU", "FEATURE 1", 1, "FEATURE 2", 2
:Lbl 1 
<feature one, available to everyone>
:Lbl 2
:If n≠20:Then
:Disp "ONLY AUTHORIZED","USERS CAN USE","THIS FEATURE
:Else
<feature two, restricted>
:End

Keeping subprograms un-executable

Say you have a large program with many subprograms, the only correct way to run the program is to run the main one. So to keep subprograms from being run outside of the main one you create a pass-on key and have the subprograms check Ans to see if it matches.

PROGRAM:MAIN
:randInt(1,100→Z    //make a pass-on key, keeping it new each time so the user cant guess it
(...rest of code)
:Z                //Store the key as Ans
:prgrmSUB1            //Call the subprogram
PROGRAM:SUB1
:If Ans≠Z            //Check the key and end the program if it doesn't match
:Stop
(...rest of code)

Simple enough

Thoughts to Consider

While discussing program protection, it is important to mention that somebody who's a knowledgeable calculator user will be able to circumvent any program protection using either one of the downloadable assembly programs that can unlock TI-Basic programs or the Graph Link software. Because of this, program protection really is only possible when you are dealing with ignorant calculator users.

Besides knowing about knowledgeable calculator users, you should also think about how others would be able to learn from your code. The general consensus among the calculator programming community is that programs should be unrestricted so others are able to study your work, as long as they do not release it as their own.

Putting all the code on one line would be frowned upon in this case because other programmers don't want to have to deal with separating out the code one line at a time to be able to understand and read it; that's just a major headache. Just remember that experimentation is key to learning TI-Basic, so you don't want to deprive that opportunity from someone else.

References

  • David Martin had the ideas for "free trial" and "authorization" program protection in his TI-Basic guide, which unfortunately is not available on the Internet anymore. The examples given here are based on these ideas, but modified to fit this guide better.
  • Weregoose came up with the plain password code example, while DarkerLine and Weregoose came up with the hash function password code examples; the examples were originally posted on the United-TI TI-Basic forum topic.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/protection


Self-Modifying Code (SMC)
Equation Variables
Function Y0-Y9
Parametric X/Y1T-X/Y6T
Polar r1-r6
Sequence u, v, w

Self-modifying code (SMC) is code that changes itself while it is executing. While TI-Basic does not provide support for SMC like it is found in other programming languages, TI-Basic does allow you to implement a primitive form of SMC using the equation variables that are used when graphing an equation on the graph screen.

The function, parametric, and polar graphing variables are accessible in the VARS menu (options 1, 2, and 3 respectively), while the sequence graphing variables are accessible on the keypad by pressing 2nd 7, 8, and 9 respectively.

Each of these variables is the same size, so there is no real difference between which variable you use. However, since sequence graphing is the least used graphing mode, the sequence variables are probably the best variables to use when using SMC.

How does it Work?

While the equation variables are primarily used for graphing, they are actually stored internally as strings by the calculator. The string operations and commands do not work on them, however, but you can store a string to them and evaluate them in an expression.

Just like how you can evaluate an expression stored in a string using the expr( command, the equation variables can be used the same way implicitly. The expression can contain whatever combination of numbers, variables, and functions that you want, just as long as they evaluate to a number or list of numbers.

For a simple example, let's initialize X with a value of 2 and store the expression "50X" to u:

:2→X
:"50X→u

When you access u, it will have a value of 100. But what would happen to the value of u if you changed the value of X to 5? Well, because the value of u depends on the value of X, u would change accordingly, and it would now have a value of 250. This is the basic premise of SMC: You can modify a variable elsewhere, and it will automatically update the respective equation variable. Hence, a program can change how it runs.

As it turns out, finding an occasion to use this technique is usually rare, so here is a made-up example. This program will count up and down with the arrow keys until you press ENTER. If you press 2ND, however, it will switch the order of the keys:

:5→A
:"(Ans=25)-(Ans=34→u        // initial expression for u
:Repeat Ans=105
:A+u→A
:Disp Ans
:Repeat Ans:getKey:End      // wait for a keypress
:If Ans=21
:"(Ans=34)-(Ans=25→u        // switch the arrow keys
:End

Advanced Uses

While just using SMC for simple expressions doesn't really add any additional value to your programs, you can use it for more complicated purposes. One common situation is optimization.

If you have a lengthy command or formula that you use multiple times throughout your program, you can simply store the statement to an equation variable, and then use the equation variable whenever you want to call the statement. This eliminates duplicate code, which makes your program smaller.

For example, if you want to generate a random integer from 1 to 9, here is what you would use:

:"randInt(1,9→u

Then each time you wanted to create a random integer, just use u.

Limitations of SMC

There are a few limitations you need to be aware of when using SMC:

  • It complicates your code, making it difficult to understand and maintain. This is why you should primarily stick to implementing SMC when you are done with your program.
  • The equation variables will affect the graph settings, and likewise the graph screen will be affected if the respective graph mode is enabled.
  • You can't store the equation variable to itself, or other variables, if they don't have a matching type (i.e., trying to store a string to a real will result in an ERR:DATA TYPE error).
  • Don't abuse SMC; the extra step of reading and executing through variables may slow down your code slightly and even cost a number of bytes if used improperly, so wield it wisely (i.e., only for the benefits it provides over other methods).

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/selfmodify


Grouping A Program

Your friend just asked you to transfer a program on your calculator over to his calculator so that he can play it in class whenever he wants to. You say sure, and he gets his link cable out and you start the transfer process. What you thought was going to be a simple transfer turns out to involve some serious headaches.

The program he wants not only has several subprograms that go with it, but multiple list and matrix variables as well as a few pictures. Unfortunately, you aren't aware of this until later after he tries to run the main program without the necessary subprograms, variables, and pictures.

When he asks you why the program won't work like it did on your calculator, you don't have an answer. You decide to start transferring over other programs and variables and whatever else to try to make the program work, but the program still doesn't cooperate. Finally you just give up and tell him that there must be something wrong with his calculator.

While this seems like a rather difficult problem to fix, there is in fact a simple solution: group files. Groups store files together in a package, where the file can be almost anything, whether it is a program, variable, picture, etc. Because groups reside in the archive, you never have to worry about a RAM clear deleting your group.

Advantages

Several files that go together can be put in one group, making it easy to transfer the files together — whether between two calculators, or a calculator and a computer.

On a TI-83+ or higher, group variables are stored in the archive, which means that a rogue RAM clear won't delete your files.

Groups are also great for backing up a version of a program being worked on before making major changes to it - even if the program is very large, or split between several files.

Finally, putting several parts of a released program in a group avoids the issue of users that forget to transfer a necessary file (although you should explain how groups work in a readme file).

Limitations

A group must contain more than one variable. It's possible to get around this by providing a dummy variable in the group (use a variable such as X that probably doesn't hold anything important).

TI-Basic programs cannot modify groups. You will have to recreate the group if you want to change its contents. Usually, this isn't too much trouble.

It's also been reported that in large enough groups, the calculator may change a bit in the data when ungrouping — in practice, this might result in an error when running the newly-ungrouped program. To be on the safe side, you should check that a group "works" before deleting the original files. It's also possible that splitting the large group in two (if this is feasible) will fix the issue.

References

  • The idea for this grouping article came from Jon Pezzino and Kerm Martian's "The Elite Guide to TI-BASIC". It is a good read with lots of useful knowledge and tips/tricks. You can find the link to it on the Resources page.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/grouping


Subprograms
toolbar-separator.png This article is part of the coding stage of the development cycle.

Imagine you're creating an RPG, and the current problem you're facing is how to display all of the data for each character on the screen. Without putting too much thought into it, the easiest approach to you seems to be to simply write out the data each time. Unfortunately, when you start implementing this approach, it soon becomes apparent that it will not work in your program.

While you've only programmed in a few of the characters and their respective data, you can already see that there is simply too much data to enter in; and then when you think about the possibility of having to go through and change all of the data again if you update the program, you're now left feeling overwhelmed and wondering if there's another way. Thankfully, there is, and its name is subprograms.

A subprogram is a program called by another program to perform a particular task or function for the program. When a task needs to be performed multiple times (such as displaying character data), you can make it into a separate subprogram. The complete program is thus made up of multiple smaller, independent subprograms that work together with the main program.

There are two different general types of subprograms available:

  • External — They exist as stand-alone programs that are listed in the program menu, and can be executed just like a regular program.
  • Internal — They are contained inside the program itself, so that they can be called by the program whenever needed.

There are certain advantages and disadvantages to using each type of subprogram, and consequently, situations where using one type of subprogram makes more sense than using the other. This doesn't mean you can't use whichever you like, though.

External Subprograms

External subprograms are the simplest type of subprogram, and involve executing one program from inside another program using the prgm command. You just insert the prgm command into the program where you want the subprogram to run, and then type the subprogram's name. You can also go to the program menu, and press ENTER on whichever program you want to use to paste the program's name into the program.

:prgmPROGNAME

When creating a subprogram, you take whatever code you want from the parent program and put it in its own program (see your first program for more information), and then put a Return command whenever you want to return to the parent program. (A Return command is optional at the end of a program, and you typically leave it off as part of program optimization.)

You should try to name your subprograms Zparentn or θparentn, where parent is the name of the parent program and n is the number (if you have more than one). Because subprograms are relatively unimportant by themselves, you want them to appear at the bottom of the program menu so they don't clutter it up and interfere with the user's ability to find whatever program they're looking for.

Here's a simple example where we are storing maps for our maze game in a subprogram, and then retrieving the desired map from the subprogram as a string, so we can print it out on the home screen. (This example is somewhat contrived, but it should be enough to illustrate external subprograms).

PROGRAM:MAZE
:ClrHome
:prgmZMAZE
:Output(1,1,Ans
:Pause

PROGRAM:ZMAZE
:int(3rand→A
:"X    XX    XXXXXX    XX    XXXXXX    XX    XXXXX
:If A=1:"X X X X X X X X X X X X X X X X X X X X X X X X 
:If not(A:"X              XX              XX              X
subprogram_zmaze.gif

When the subprogram's name is encountered (in this case, prgmZMAZE), execution of the program will be put on hold, and program execution will transfer to the subprogram. Once the subprogram is finished running, or the Return command is executed, program execution will go back to the program, continuing right after the subprogram name. (If the Stop command is used instead of Return, however, the complete program hierarchy will stop.) See the image to the right for a graphical view of program flow using subprograms.

Although subprograms can call themselves (i.e., recursion) or other subprograms, each subprogram should return to the parent program and let it handle all the program calling. A structured program hierarchy is easier to understand and update (in fact, it's actually a code convention), and helps cut down the potential for memory leaks.

Each program call is sixteen bytes, and gets put on a stack in RAM by the calculator. This is fine as long as its size isn't larger than the free RAM available, but each additional program call takes more memory until the program Returns. Having many nested program calls can run out of memory and crash the calculator (giving you a ERR:MEMORY error).

External subprograms often are made to increase the speed of a program and decrease the size of the program overall by executing often used code at one place, where it can be called quickly. (as opposed to Labels)

To make subprograms even faster, a Return may be used in the subprogram, but only is useful in subprograms with several methods, and only after a method has been completed. The problem with using a Return in such a method is that it isn't very easy to prevent memory leaks by using a Return before an End command should have been called.

Because the same thing happens with Goto's before End commands as Returns before End commands, we can use this to our advantage, to quickly return from a subprogram. By using a Goto to a label with one or possibly more End commands, you can quickly return from a program, or quickly reset a While, Repeat, or For( loop without having to execute the rest of the code in the subprogram or loop.

Goto ST
Lbl E1
End
Lbl E0
Return
Lbl ST
[code]
If [condition]
Goto E0
[code]
If [condition]
Then
[code]
Goto E1
End
For(A,1,10
[code]
If [condition]
Goto E1
[code]
End

This can significantly increase the speed of subprograms or loops, by using Labels without worry of ERR:MEMORY.

Passing Arguments

The main problem associated with trying to use external subprograms is that there is no built-in support for passing arguments to subprograms. This feature is important because it allows the subprogram to act differently based on what values are given to it for processing.

Fortunately, you can mimic this functionality by using variables. Because all variables are global (variables used by one program can be used by another), changing a variable in one program affects that variable everywhere else. While you can use almost any variable that you want, there are three main types of variables that you should choose from:

  • Pre-Defined Variables — Includes reals, strings, matrices, built-in lists, etc. These variables are frequently used by most programs, so you don't have to worry very much about whether the user cares if your mess with them.
  • User-Defined Lists — Uses the individual list elements to store different values. These variables have a certain sense of security that comes with using them because they are the only variable that you can actually create, so a program can have its own custom list to use.
  • Ans — It can take on whatever value and variable you want, so the program doesn't have a specific variable hard-coded in. Its value changes whenever you store something or simply place an expression or string on a line by itself.

When using a pre-defined variable or user-defined list, you simply have to set the variable to the value that you want and then call the subprogram. The subprogram should be able to use that variable without problems, but if you don't properly setup the variable, the subprogram won't work correctly.

:{2,3,5,7,9→PRIME
:prgmZPRIME

Using the Ans variable is essentially the same, except you need to add some additional code to the subprogram. Because the value of Ans changes whenever there is a new variable storage, you should have the first line inside the subprogram save Ans to another, more stable variable.

:{2,3,5,7,9
:prgmZPRIME

PROGRAM:ZPRIME
:Ans→PRIME

This change saves some memory in the main program (in our example, we were able to get rid of the →PRIME statement), but the subprogram size is larger, since we really just shifted the variable storage code to the subprogram. However, if the subprogram is called multiple times this extra memory is only used once instead of once per call.

This does create a problem, though, because now when you store Ans to another variable, it will crash the program if Ans isn't the same type of variable. There is only one case where you can avoid crashing when the subprogram receives the wrong variable type. If the subprogram is expecting a real variable (such as A or X) and it is passed a list, it can prevent a crash by using the fact that a parenthesis ("(") has multiple functions.

PROGRAM:ZSUB
:Ans(1→A

The reason that this works is because a user-defined list doesn't need the ∟ prefixed character at the beginning when referring to the list. While you may be only asking the user to input a simple real variable, a list would also be allowed. There is nothing you can really do to fix this problem with other types, so just be careful.

Advanced Uses

The main consideration when using external subprograms is how many subprograms your program should have. While you're still putting your program together, it's good to keep it in many small, separate subprograms; but when you're done, all those subprograms become a liability and make your program unwieldy to use. This is because you have to remember all those subprograms in order to use your program.

There are two different ways to resolve this problem. The first way is to put the subprograms back in your program. This should only be done if a subprogram was only called once or twice, and putting it back in won't slow down the program. All you have to do is paste the code from the subprogram in place of the subprogram call. When you're done, you can delete the now unnecessary subprograms.

(The more detailed explanation is to go through your main program, and whenever you see a prgm call for a subprogram, clear that line and press 2nd STO. The Recall option will come up. Press the PRGM key and select the appropriate subprogram from the EXEC menu. The calculator will paste that subprogram's code into the main program.)

This is the same subprogram example from before, but now we've gotten rid of the ZMAZE subprogram and simply placed the subprogram code in the MAZE program itself:

PROGRAM:MAZE
:ClrHome
:int(3rand→A
:"X    XX    XXXXXX    XX    XXXXXX    XX    XXXXX
:If A=1:"X X X X X X X X X X X X X X X X X X X X X X X X 
:If not(A:"X              XX              XX              X
:Output(1,1,Ans
:Pause

The second way to resolve the problem is by simply combining your subprograms together, so that there are fewer subprograms needed. Of course, how many subprograms you decide to use is up to you, but you should try to limit it to three or four subprograms at most, and just one subprogram ideally. This might take some effort on your part, but it will most certainly make your users happy.

When you start combining your subprograms together, you should place the subprograms one after the other, giving each subprogram a unique branching label (note that labels are local, so you can't use Goto in one program to jump to a label in another program). Instead of having to search through each individual subprogram, branching allows you to simply jump to the desired subprogram. You then just use the subprogram's variable argument to determine which subprogram to access.

:If A=e:Goto A  // jump to first subprogram
:If A=π:Goto B  // jump to second subprogram
:Stop  // the subprogram was accidentally called
:Lbl A
: // subprogram code
:Return
:Lbl B
: // subprogram code
: // No Return needed here

Looking at the example, the first thing you should notice is the variable values that are used to determine which subprogram to jump to. While you could use something simple like one or two, those values have a high probability of being accidentally entered in by the user or being set by another unrelated program. What works better is to use random decimals (like .193 or 1.857) or math symbols (like e or π).

If none of the variable values for the subprograms match, then none of the subprograms will be executed; instead, program execution will go to the Stop command on the next line, which will immediately stop the entire program. The reason for adding this program protection is to prevent the user from running the subprogram separate from our main program.

This is a real concern since external subprograms are listed in the program menu, and the user most likely at some point will try to run the subprogram just out of pure curiosity. Unless the user is a competent TI-Basic programmer who knows what they are doing, however, you normally don't want to let the user mess with your subprograms. If they change something, or delete some lines of code, then your program might stop working correctly.

The second thing you should notice about the example is the Return command at the end of each subprogram. If you have lots of subprograms, and you're accessing a subprogram near the bottom, it takes a considerable amount of time for program execution to go back to the main program. This happens because program execution doesn't return to the main program until after it reaches the end of the program, or it executes a Return command. So, just remember to include the Return commands as needed.

Using Assembly

Although using assembly programs can limit the compatibility of your program, they can be helpful in reducing the memory your program occupies, and allow for easier calling of subprograms. To use an assembly program for calling subprograms, have your subprograms named using some very simple pattern (e.g. "ZZ10", "ZZ11", "ZZ12", "ZZ13", etc). Then create a program such as the following called ZEXEC (or something similar):

:"ZZ"+Ans→StrX
://Assembly program to run program name in StrX

Then you can call this program through the line:

:"13
:prgmZEXEC

This will create a string with the contents "ZZ13" which will then run the program ZZ13. Depending on the assembly program you are using, you could have "ZZ13" archived (along with the rest of the subroutines) and when ZEXEC is called, it copies it to an unarchived program, runs the copy, and then deletes the copy, thus only one subroutine at a time is unarchived. This is useful for programs with lots of subroutines. One way of doing this is using xLIB, for which the ZEXEC code would look like this:

"ZZ"+Ans
real(10,0,0
prgmXTEMP000
real(10,1,0

In order to make this concept more efficient, a number to string routine would come in handy. If one were using such a routine one could have various actions in a program return number values. These numbers would be converted into strings and the program would run the corresponding subprogram. This would become useful with a custom menu, one could have the program return the location of the cursor, convert that into a string and run the subprogram that corresponds to that cursor location. Some assembly programs that can be used may be found on the assembly libraries page.

Advantages

There are several advantages of using external subprograms. First, and foremost, they reduce program size by eliminating redundant code. Instead of having to type the code multiple times for a task that occurs more than once in a program, you just type it once and put it in a subprogram. You then call the subprogram whenever you want to perform the task in your program.

Second, external subprograms increase program speed by making programs as compact as possible. You separate conditional tasks from the program (they either happen every time or they are skipped over), and put them in a subprogram; you then call the subprogram instead. This improves program speed because the calculator doesn't have to go through all of the conditional code anymore.

Third, external subprograms make editing, debugging, and optimizing easier. Instead of going through the entire program, looking for the code you want to change, you can focus on one subprogram at a time. This makes the code more manageable, allowing you to more thoroughly look at each subprogram and to better keep track of which subprograms you have looked at. It also prevents you from accidentally changing other parts of the program.

Lastly, subprograms are reusable, allowing multiple programs to share and use the same code. Breaking a program into smaller, individual subprograms, which each do a basic function or task, allows other programs to use those subprograms. Consequently, this reduces program size.

Internal Subprograms

Internal subprograms are the most complicated type of subprogram, and involve putting the subprograms in the main program itself. This is not the same thing as pasting the code from the subprogram in place of the subprogram call, like you do with external subprograms; rather, it is designing your main program so that it can take advantage of subprograms, but all the code is self-contained.

There are several different ways that you can make internal subprograms, but the three most common ways are:

  1. Append to the beginning of the program
  2. Structured loops or branching
  3. Branching out of broken loops

Append to Program Beginning

If you remember how we used external programs, then this should be very familiar. Instead of placing the subprograms in their own separate program, we are now just placing the subprograms at the beginning of our main program.

The standard way to make a subprogram is to use an If-Then conditional:

:If A=1.234:Then
: // subprogram code
:DelVar A
:Return
:End

Then to call the subprogram, you just set the variable to the desired value:

:1.234→A
:prgmPROGNAME

Of course, there are some important considerations that you need to be aware of. You can use whatever random value for the variable that you want, just as long as it isn't something that the user would typically use. This is to ensure that the subprogram isn't accidentally run when it shouldn't be, which is why you need to reset the variable's value inside the subprogram before exiting.

While you could use any variable that you want (including Ans), the best variables to use are the simple real variables (A-Z and θ). This is because they are small in size and they are constantly being used by other programs, so you don't have to really worry very much about your subprograms being accidentally run. (Ans is not a very good variable to use for the reasons listed above.)

You should always remember to include the Return command at the end of the subprogram. Once the subprogram is finished, the Return command will cause the subprogram to stop and return to the previous place in the program from where it was called. The other reason for the Return command is to prevent any memory errors that can occur if a program recursively calls itself too much.

Advanced Uses

You can have multiple subprograms at the beginning listed one after the other by simply using different values for the the variable:

:If A=1.234:Then
: // subprogram 1
:End
:If A=2.246:Then
: // subprogram 2
:End

While this works quite well when you only have three or four subprograms, with more subprograms it can actually slow down the main program. This happens because the calculator has to go through all the subprograms to get to the main program code.

You could fix this problem in a couple different ways, but the easiest way is to simply place all the subprograms in an If-Then conditional and then make that part of the subprograms. If this conditional is false, all of the subprograms will be skipped over.

A real number has an integer (accessed with the iPart( command) and fraction (accessed with the fPart( command) part, and you can use both of those for the subprograms: the integer will be the subprogram access check on the outside If-Then conditional and the fraction will be the respective subprogram we want to run.

:If 123456=iPart(A:Then  // get integer part of number
:10fPart(A  // get fraction part of number
:If Ans=1:Then
: // subprogram 1
:End
:If Ans=2:Then
: // subprogram 2
:End
: // rest of subprograms
:End

For calling the subprograms, you then just set the variable to the desired value like before:

:123456.1→A  // run subprogram 1
:prgmPROGNAME

Structured Loops or Branching

If you don't like placing subprograms at the beginning of a program, the next approach that you can try is placing subprograms in the actual program code. While it would appear easy to simply place the subprograms wherever you feel like in your program, you can't readily do this since it would almost certainly cause your program to stop working correctly. Instead, you need to modify your program and subprograms so they can be put together.

What this modification entails is reorganizing your program so that the code works in a modular fashion as individual subprograms. This may not seem like it would be worth the effort, depending on the amount of code in your program, but modularization makes the program easier to understand and update (see planning programs for more information).

While there are several different ways you can structure the code in a modular fashion, the simplest way is to give each subprogram its own individual loop with a respective variable value as the loop condition. You can then access and exit the desired loop by simply changing the value of the variable. Of course, you have to determine which loop and variable you are going to use.

There are three different loops you can choose from (While, Repeat, and For(), but the best loop to use in this circumstance is While. This is because the condition is tested at the top of the loop, so if it's false already before the loop, then the loop will actually be skipped over (which is what allows us to use the loops as subprograms).

Once you have decided upon a particular loop, now you need to choose which variable you want to use. Like with the first way to make internal subprograms, the best variable to use is one of the real variables (A-Z and θ). This is because we just need a single value, and real variables only take up 15 bytes of memory (other variables are just as small, but they take up more memory when you're accessing them).

Now that the loop and variable have been chosen, we need to setup the system of loops to act as the subprograms. What works best is to have a main program loop and then place the subprogram loops inside of it. Putting the variable and loops together, here is what the program skeleton looks like:

:Repeat not(A  // main program loop
:1→A
:While A=1
: // subprogram 1
:2→A  // enter loop for second subprogram
:End
:While A=2
: // subprogram 2
:DelVar A  // exit main program loop
:End
: // rest of subprograms
:End

You just set the value of the variable in the loop to use the desired subprogram. Then when you are done with the subprogram, you just change the value of the variable to something different to exit the loop. You do the same thing to exit the main program loop. You can use whatever system of values for the variable that you want, but just remember to keep it simple enough so that you can come back to it later and it still makes sense to you.

The one drawback of using this approach is that the calculator has to go through all the subprograms to exit the main program loop, which can really be slow depending on the size of the subprograms. At the same time, this approach is very easy to understand and follow because the loops are organized in a straight forward manner, so it's kind of an even trade off.

Related to using structured loops, the alternative you can use is branching. While using branching by itself to structure a program is generally frowned upon (see planning programs for more information), you can actually use it quite effectively for making internal subprograms that only need to be called a few times. Here is a simple example:

:0→A:Goto A
:Lbl B
: // main program code
:1→A:Goto A
:Lbl C
: // main program code
:Stop
:Lbl A
: // subprogram code
:If A:Goto C
:Goto B

The A variable is used for determining when to stop the program: a zero value will simply cause the subprogram to jump back to the main program, but a value of one will cause the subprogram to jump to the exit of the program (the C label). Because the calculator doesn't store the label positions, there is no way to get memory leaks using this approach, which is especially important when exiting the program. However, it does get hard to follow and maintain the code the more branching there is.

Branching out of Loops

The last way to make internal subprograms is arguably the most difficult to understand, but once you have it setup in your program, it provides an easy framework for adding additional subprograms. The best time to use these kind of subprograms is when you have a main program loop that you're running and you want to be able to jump out of it and then back into it whenever you want.

The basis of these subprograms is using branching (Goto and Lbl) with loops and conditionals (anything that uses an End command). Branching by itself allows the calculator to jump from one point in a program to another, skipping over whatever code you don't want executed. When you use branching to exit loops and conditionals, however, it has the unwanted effect of causing memory leaks.

Memory leaks happen because the calculator doesn't get to reach the End command for the associated loop or conditional, and the calculator just keeps on storing the End commands in its stack until there is eventually no free memory left. (Memory leaks can also occur with excessive program recursion.) Here is a simple example that has a memory leak:

:Lbl A
:While 1
:Goto A
:End

If you notice, when the Goto A command is executed, it jumps to the matching label A that is on the line before the loop. The While 1 loop is never allowed to finish because the End command never gets reached, and the branching occurs over and over again until the calculator finally slows down to a stop (because there is less and less free memory available) and returns a memory error.

This type of programming is common with beginners, and its use is generally frowned upon; instead you should try to use proper program structure (see planning programs for more information). However, if you know what you are doing, you can actually use these broken loops and conditionals for internal subprograms, and you won't have to worry about memory leaks or the dreaded memory error.

There are two different approaches that you can use. The first approach is to use another Goto and matching label to jump back into the loop. Because the calculator doesn't store the labels, you can freely use whatever branching in the loop that you want, and the calculator will act like it had never even left the loop:

:Repeat getKey
:Goto A
:Lbl B
:End
:Stop
:Lbl A
: // subprogram code
:Goto B

The key here is that the Goto A command jumps to the matching label A outside the loop, and then the Goto B jumps to the matching label B back inside the loop. The calculator still has the loop's associated End command on its stack, so the loop will just keep looping without problems until you eventually press a key to stop it and it executes the Stop command.

While this first approach works rather nicely in small programs, it is not very practical for use in large programs because all the branching starts to slow the program down. Unlike loops and conditionals, the calculator doesn't keep track of the label positions, so it must start from the beginning of the program to find the matching label to jump to. The further down the label is in the program code, the more time the calculator must spend looking for it.

The second approach solves this problem by using a duplicate End command for the loop or conditional. Since the calculator keeps track of the number of unfinished loops and conditionals by storing the associated End commands in its stack, we can make the calculator believe that our different End command is actually the End command that belongs to the loop. Here is a simple example to illustrate:

:Repeat getKey
:Goto A
:End
:Stop
:Lbl A
: // subprogram code
:End

Like with the first approach, when Goto A is executed the program will jump to the matching label A, and then the subprogram code will be executed. This time, however, the calculator will read the End command after the subprogram code, which it believes is the end of the loop, and then immediately jump back to the beginning of the loop. This process will be repeated over and over again until the user presses a key, at which time the Stop command will be executed and the program will stop.

The subprogram code for both approaches can be whatever you want, including other loops and conditionals. You just need to remember to close the loops and conditionals before returning to the original loop, otherwise the calculator will have the wrong End command on its stack. You also want to have a matching number of End commands for your loops and conditionals, or you will get a memory leak.

Advanced Uses

There are a couple different ways you can enhance the duplicate End subprogram approach so that you get the most use out of it. The first way is relatively simple, and just involves using a For( loop as the looping structure, instead of a While loop or Repeat loop (which is what we had in our previous examples).

A For( loop is basically a specialized form of a While loop, with the main differences being that it is executed a specific number of times and it has the variable setup and ending condition built-in. You just choose a variable, the range of values, and the increment (it is optional, with one as the default); and then the loop will start the variable at the initial value and increment it each time until it reaches the ending value.

Now when you start using the For( loop for internal subprograms, you need to make sure the For( loop executes at least twice. This is so that the End command of the For( loop gets used along with the End command of the subprogram, otherwise it will simply fall through after the first time through the loop. You can select different subprograms based on the variable's value. Here is our example from above, now using a For( loop instead:

:For(A,0,1
:If not(A:Goto A
:End
: // main program code
:Stop
:Lbl A
: // subprogram code
:End

When the For( loop is executed, the A variable is set to zero. The not(A condition is true, so the calculator executes the Goto A command and then jumps to the matching label A. The calculator then jumps back to the beginning of the For( loop and increments the A variable to one. This time, however, there is no subprogram jump taking place, and the calculator simply finishes the For( loop like normal.

The second way to enhance the duplicate End subprogram approach is by using a simple trick. Because a While loop loops only when the condition is true, when the calculator comes across a While loop with a false condition, it will simply skip over the entire loop (and everything inside the loop). The easiest way to make a false condition is to use zero, since zero will never be true (based on Boolean logic). Here is a simple example to demonstrate:

:While 0
:Lbl A
: // subprogram code
:End
: // main program code
:If getKey:Then
: // program code
:Goto A
:End

When the calculator encounters the While 0 loop, it won't execute it because 0 is false. After the calculator enters the subprogram conditional, it executes some program code and then hits the Goto A command and jumps to the matching label A inside the While 0 loop. The calculator takes the End command of the loop as the End command of the conditional, and thus no memory leak occurs.

The reason that this trick is so valuable is because it allows you to place your subprograms at the beginning of the program, and you don't ever have to worry about them being accidentally executed (they will always be skipped over). In addition, now that the labels are at the beginning of the program, there is no more speed problem to deal with, since the calculator doesn't have to search through the entire program to find the labels.

Advantages

The main advantage of using internal subprograms is that there is only one program needed to make your program run. When you give someone your program, you don't have to worry about forgetting to include any subprograms; or somebody deleting your subprograms afterwards, causing your program to stop working correctly. These things are mostly out of your hands, but users will think your program is at fault.

Related to the first advantage, the other advantage is that the user's program menu doesn't get cluttered up with insignificant subprograms. This problem is relative to how many subprograms a program has, but it can become tiresome to have to sort through the program menu in order to find the program that you want. If anything, this is just a nice courtesy to the users of your programs.

References

<< Commenting Code Overview Program Cleanup >>

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/subprograms


Multiplayer
toolbar-separator.png This article is currently in development. You can help TI-Basic Developer by expanding it. I may never get around to finishing this. Feel free to improve it. ~ GoVegan

Multiplayer is where two or more people play a game together at the same time. Although you can create AI opponents for a player to play against, AI does not offer as much fun compared to playing against other human opponents — you can have the players work together, compete against each other, and even one player manage the other players.

Multiplayer games are generally divided into two categories: the players share a single calculator, and the players each play on their own calculator connected together with a link cable (either I/O or USB).

Single-Calculator Multiplayer

Multiplayer games on one calculator generally fall into two categories: real-time and turn-based. Real-time is where the game action is constantly changing, not stopping for the player input. Some classic examples of real-time games are Galaxian and Pong. Turn-based is where each player is allowed to make a move, and the game action only changes after each player has moved. Some classic examples of turn-based games are Battleship and Scorched Earth.

Making real-time games involves using the getKey command, except you can't wait for a key to be pressed. The general form is something along the lines of:

While <game not done>
getKey->K
If K=<player 1 key>:Then
// player 1 action
End
If K=<player 2 key>:Then
// player 2 action
End
<Update rest of game>
End

As you can see, the player action only occurs when a player has pressed a particular key; otherwise the game just continues on like regular, with the main game loop being repeated over and over again.

There are some problems with making real-time games, however.

The first, and foremost, problem is that TI-Basic is rather slow with user input. If you do anything remotely time-intensive, such as displaying lots of graphics or complex variable manipulation, then there will be some lag-time between when a player presses a key and when the calculator gets around to processing it. Although there's not really much you can do about this, you can make sure your game is as optimized as possible (especially breaking the more time-intensive parts into their own subprograms).

The second problem is that the calculator only keeps track of the last key pressed since the last time getKey was executed, so that means only one player can have their input read and processed each time through the game loop. In addition, if you enter a large block of code for the player, it will take a while before the other players have a chance to do anything.

Related to the second problem, the third problem with making real-time games is that unlike the other keys, the arrow and DEL keys can actually be held down, which will cause them to keep being repeated until they are unpressed. The effectively disables the other keys from being able to be pressed. There is no viable way to get around this problem, except asking the players to not press those keys.

The fourth problem is that the keypad is quite small, and having two or more people try to share the calculator can be rather difficult. The best way to work around this problem is choosing keys for each player that are a good distance away from each other. When choosing keys you should also keep in mind the calculator screen — if somebody has to press keys that make it difficult to see the screen, then you should choose different keys.

Because making real-time games is not very practical, a better alternative is turn-based games: you hand the calculator from player to player, allowing each each player to move one at a time. These games are much easier to program: you simply use a variable to keep track of whose turn it is, increment the variable after each player's turn, and when everybody has completed their turn, you reset the variable. The only real downfall of turn-based games is that they can be slow because you have to wait until the other players are done before you can move.

Multi-Calculator Multiplayer

So I guess you're wondering how to program a multi-calculator multiplayer experience into one of your games. One of the first things you will need to do is familiarize yourself with the GetCalc( command. Basically, it retrieves a specified variable from another calculator and stores it to that variable on yours.

Creating multiplayer programs over two calculators is a much less simple process as it is to make single-calculator multiplayer programs. However, doing so could be the main selling point of your program and would certainly be worth the effort. You will notice that in each of our examples we tend to transfer lists, which we recommend you do too. Whilst it is possible to transfer a variety of real variables, it is much faster to transfer a list of numbers than a number of real variables.

There are two general ways to programming multi-calculator programs; one screen processing and two screen processing. The one screen processing method is simply making a program use the statistics from another calculator, and the whole multiplayer experience is processed on that calculator. The two screen processing method is much more complex, where we can share the multiplayer processing across two calculators by using a "turn-by-turn" interface.

Core

When it comes to multi-calculator multiplayer games, it is absolutely necessary to give each calculator its own identity. As both calculators are running the exact same program, we need a way to be able to determine one calculator as "Calculator A" and the other calculator as "Calculator B". This makes it possible for both calculators to know what data to send and receive. For example, if both calculators were "Calculator A", then both calculators would be doing exactly the same thing, or keep trying to receive the same variable from each other in an endless loop

This is code determines which assigns each calculator with a unique identity:

:GetCalc(A
:e(A=π)+π(A≠π→A

How it works is that the calculator gets the variable A from the other calculator, and checks whether it equals π (pi). If A equals π, then e is stored to A; however, if A does not equal π, then π is stored to A. Here is a table to demonstrate the results:

Calculator A Calculator B
A = π A = e
A = 3.141592654 A = 2.718281828

The calculator can therefore identify itself like this:

:If A=π:Disp "I'M CALC A
:If A=e:Disp "I'M CALC B

If we use a not( routine to make Calculator A = 1 and Calculator B = 0 instead, then we are unable to determine whether a link has been initiated. Simply explained, because variable A is more likely to equal zero than any other number, Calculator A may accidentally assume Calculator B has initiated the multi-calculator sequence. Variable A is not likely to ever equal π (or e), which is why it's useful as a "connection initiated" checker for the calculator.

The beauty of the core code is that it doesn't matter which player executes the core code first, both calculators will be able to give themselves a unique identity, be able to distinguish which calculator they are and be able to see whether the other calculator is initiated yet.

One Screen

If you are looking to save space and valuable time, this is the multiplayer for you. This method has the sending calculator in a power-saving state the whole time while the receiving calculator does all of the hard work such as processing and animation.

First off, we put in the core multiplayer code to determine which calculator is which. Then, Calculator B will retrieve the opponent's statistics for battling. Because the program uses the same variables on every calculator, we need to find a way to store Calculator A's statistics onto Calculator B without overwriting Calculator B's statistics. Surprisingly, this is not as hard as it seems:

:GetCalc(A
:e(A=π)+π(A≠π→A
:If A=π:Then
:∟STATS→L₁
:Disp "SENDING DATA...","PRESS ENTER WHEN
:Pause "FINISHED
:End

Now that each calculator has created its unique identity, and Calculator A has stored its statistics to L₁, we can finally make Calculator B receive Calculator A's statistics and process all of the data:

:If A=e:Then
:GetCalc(L₁
<interactive code>
:End

After this, write the rest as though this was a single-calculator multiplayer game, where you're statistics are in ∟STATS and your opponent's statistics are in L₁. Here is a side-by-side comparison on how the program runs:

Calculator A Calculator B
1SCREEN-A.gif 1SCREEN-B.gif

Two Screens

Here we show you a turn by turn based method of a battle game.

Like with all multi-calculator multiplayer programs, we first provide the program with the core. This time, however, we will first reset variables A and F. Then we will add code for which stores each calculator's statistical data to its individually named list. Calculator B is then instructed to go elsewhere in the program (note that Goto is within an If-Then loop):

:DelVarADelVar FGetCalc(A
:e(A=π)+π(A≠π→A
:If A=π:Then
:∟STATS→L₁
:Else
:∟STATS→L₂
:Goto W
:End

Because this is turn by turn battle game, we need to repeat the battle code until the battle is finished. We will make variable F determine this. Also, we want Calculator A to be able to attack first, so we shall put the code for attacking as the first thing in the Repeat loop. This is where it starts to get a bit sticky. First we delete variable B, which is going to determine what command the user has chosen (whether it be a kind of attack, or to run away).

:Repeat F
:DelVar BMenu("CHOOSE ATTACK","ATTACK A",A,"ATTACK B",B,"RUN AWAY",R
:Lbl A:1→B:Goto S
:Lbl B:2→B:Goto S
:Lbl R:‾1→B
:Lbl S:1→θ

So when the user selects an option from the menu, a number is stored to B and 1 is stored to θ. Theta tells the receiving calculator that it the sending calculator is not ready yet. Then we create a second menu. This is to give the receiving calculator a chance to receive certain variables. That process is almost instant, and so the user then presses ENTER. θ is erased and 1 is stored to S, just before the "animation" program starts. S simply tells the animation program that it has just sent the attack.

:Menu("SENDING ATTACK","READY?",SA
:Lbl SA:1→S
:DelVar θprgmθANIMAT

The animation program is shared by both the attacker and the attacked. The program makes particular animation depending on whether variable S is equal to one. If S=1, then this program will only display the opponent getting hurt. If S=0, then this program will display YOU getting hurt, calculate how much HP you have left, and if you died, sets variable F to zero. By using the subprogram "prgmθANIMAT", it means we don't need to worry about memory leaks or program changes.

Now we have the receiving code. You will notice that Lbl W is the first line here. This is so that Calculator B can jump straight here on the first move. Because this label is within a repeat loop, and the Goto came from an If-Then section, there are no memory leaks. The first thing we do is make the program wait until the sending calculator has issued a move. If the game is over (F=1), then this process stops, and the program exits the "Repeat F" loop. If the game is not over, and the opponent issued a move, then the calculator receives the opponent's updated statistics.

:Lbl W:Disp "WAITING...
:DelVar BRepeat B or F
:GetCalc(B
:GetCalc(F
:End
:If not(F:Then
:If A=e:GetCalc(L₁
:If A=π:GetCalc(L₂

At the moment upon entering the loop, we know that the opponent's θ equals 1. In this loop, we clear our θ variable and then retrieve the opponent's θ. Because of the nature of GetCalc(, we can not receive variables whilst the other calculator is processing. Remember that as soon as the other calculator exits the "SENDING ATTACK…" menu, the animation subprogram starts.

Using this knowledge, if we delete θ and then retrieve θ whilst the opponent is in the "SENDING ATTACK…" menu, θ will equal 1 (and hence the loop is repeated). But when the opponent starts the animation process, we will be unable to retrieve θ, and so θ will equal what it all ready was, zero (hence we exit the loop).

:Repeat not(θ
:DelVar θGetCalc(θ
:End
:DelVar SprgmθANIMAT
:End
:End

This code is rather remarkable because it makes it possible to start the animation on both calculators, at the same time, automatically. You don't need to go messing about with "both users press ENTER at the same time" routines, only one user needs to press ENTER and both calculators begin — a foolproof technique.

If, after the animation process, the battle is not yet over, then the program continues into attack mode again (at the start of the "Repeat F" loop).

Now we need a routine which restores the statistics to the ∟STATS list and says who won after the battle is over! This is the easiest part of the routine. If the player's health points do not equal zero, then that player won — otherwise the other player won.

:L₁
:If A=e:L₂
:Ans→∟STATS
:If Ans(6:Then
:Pause "YOU WON!
:Else
:Pause "YOU LOST!
:End

There are a couple of things that you need to be aware of for this routine to be work:

  1. When the "SENDING ATTACK" menu pops up, you must wait for a second for the attack to actually send before pressing ENTER;
  2. Variable A must NEVER equal π during the program, (obviously with the except of the multi-calculator code itself). If it does, and a different calculator starts this routine before the other one, then the link process will fail.

To prevent the second problem from ever happening, you should reset variable A at the start of your program, and never use this variable throughout the program.

This whole routine is certainly complex, but it does work, and works pretty well too. Here is a side-by-side comparison of how the program runs. For reference, here is a table showing the values:

Calculator A Calculator B
Max HP ∟STATS(1)=2 ∟STATS(1)=5
Level ∟STATS(2)=2 ∟STATS(2)=5
Attack ∟STATS(3)=2 ∟STATS(3)=5
Defence ∟STATS(4)=2 ∟STATS(4)=5
HP ∟STATS(6)=2 ∟STATS(6)=5
Calculator A Calculator B
1SCREEN-A.gif 1SCREEN-B.gif

Final Notes

Whilst the abilities of the GetCalc( command make it harder to create multi-calculator programs, it certainly is not impossible. You just need to think extra hard and create very clever workarounds to its boundaries.

If you have any questions or comments about these routines please ask in the discussion area for this page.

References

  • James Kanjo came up with the "Multi-Calculator Core" code in his IM program, and also came up with the "turn by turn battle" code, including the function to make one calculator respond to another calculator's ENTER keypress

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/multiplayer


Validation of User Input

Validation is the process of evaluating user input to ensure it satisfies the specified requirements. Most programs just blindly accept any input that the user enters, assuming that it was entered in correctly and that it is valid. This is a dangerous assumption, because there is a great likelihood that somebody at some point will enter in bad input. When that finally happens, the program will crash when it tries to use the input. In order to ensure this doesn't happen, you should validate user input.

When validating user input, there are three main approaches you can take:

  • Stopping the program — This validation approach involves asking the user for input, and then checking to see if it is a bad input value; if it is, you then just stop the program with a Return or Stop. The idea is that there is no point continuing on to the rest of the program, since the input would only cause the program to crash or get messed up when the input finally gets used.
  • Keep asking for input — This validation approach involves placing your validation inside of a Repeat or While loop, and using a variable as a flag to indicate whether the input is valid or not. The idea is that after asking the user for input, you check to make sure it is not a bad input value; if it is, the bad input flag will be set, and input will be asked for again.
  • Make bad input valid — This validation approach involves asking the user for input, and then trying to filter out any bad parts of the input that might be present. You can make the filters as in depth as you want, but because there is almost an infinite number of things that a user can enter in, there is no way to cover everything. Ultimately, it comes down to knowing the user, and what they are likely to enter in.

How to Validate Variables

There are three main variable types that a user will be asked to input values for in a program: reals, lists, and strings. Each of these variables has their own set of standard validation considerations to check for, along with whatever additional considerations you have in your particular program.

Reals

When validating a real variable, the main things to check for are:

  • Is it within the appropriate range?
  • Is it not a complex number (i.e., there is no imaginary i part)?
  • Is it an integer (i.e., no fraction part)?
  • Is it positive (or zero, if appropriate)?

Testing for these four conditions is relatively easy, considering that there are built-in commands that will take care of it for you: relational operators, the imag( command, and the fPart( command. Generally, you should do the complex number check before the other three checks, because an imaginary part in a number can cause problems.

There's another problem that comes up with using Input specifically. If the input is for a real number A, the user might enter a list, which will be stored to ∟A instead. A simple way of fixing this problem is to store an invalid value to A to begin with, which will be dealt with if the user enters a list and doesn't change A. Many times, this is as simple as using DelVar.

For a simple example of validating a real number, imagine asking the user to specify how many rounds of a game they want to play. A For( loop is used as the main game loop, with the number of rounds being the upper boundary. Since the lower boundary is zero, we want the user to input a number greater than zero. In addition, a For( loop does not work with complex numbers, and we do not want to allow a fraction part because the number of rounds is used to calculate the scoring.

Here is what the validation code for our game might look like with each of the three different validation approaches:

:DelVar AClrHome
:Input "ROUNDS: ",A
:If imag(A
:Return
:If A<1 or fPart(A
:Return
:0→A
:Repeat Ans
:ClrHome
:Input "ROUNDS: ",A
:If not(imag(A
:not(A<1 or fPart(A
:End
:DelVar AClrHome
:Input "ROUNDS: ",A
:max(1,iPart(real(A→A

There are a couple things you should note. In the stopping the program code, we used the Return command to stop the program, instead of the Stop command. This is so that the program will work correctly with subprograms and assembly shells. We used the opposite commands in the making bad input valid code: iPart( instead of fPart( and real( instead of imag(. We are also using the max( command to make one the minimum value for the input.

Lists

When validating a list, the main things to check for are:

  • Is the list length within the appropriate range?
  • Does each list element pass the real validation?

Testing for the list length condition and each of the list elements involves using the built-in dim( command. You first check to see that the list length is acceptable, and then use the dim( command as the upper boundary in a For( loop to go over the list elements one at a time. Each element is validated just like a real variable.

For a simple example of validating a list, imagine you have a lottery game and you want the user to specify three numbers. We want the numbers to be between 1-100, as well as not having an imaginary or fraction part. Here is what the validation code for our game might look like with each of the three different validation approaches:

:ClrHome
:Input "NUMBERS: ",L1
:If 3≠dim(L1:Return
:For(I,1,3
:L1(I
:If imag(Ans:Return
:If Ans<1 or Ans>E2 or fPart(Ans
:Return
:End
:Repeat A=3
:ClrHome
:Input "NUMBERS: ",L1
:DelVar A
:For(I,1,3(3=dim(L1
:L1(I
:If not(imag(Ans
:A+not(Ans<1 or Ans>E2 or fPart(Ans→A
:End:End
:ClrHome
:Input "NUMBERS: ",L1
:For(I,1,3-dim(L1
:randInt(1,E2→L1(1+dim(L1
:End
:3→dim(L1
:max(1,min(E2,iPart(real(L1→L1

Like with the example from before, we had to check for the complex number before checking for the number boundaries and fraction part. This is because neither of those commands work with complex numbers; they will actually throw a ERR:DATA TYPE error. Also important is the optimization that we used to move the list dimension check into the For( loop's upper boundary. This allowed us to eliminate a conditional that we would have had to add.

Strings

When validating a string, the main things to check for are:

  • Is the string length within the appropriate range?
  • Does the string only contain the appropriate characters?

Testing for the string length involves using the built-in length( command. This check by itself is not enough, however, because a string treats commands and functions as just one character (i.e., a string of "ABOutput(" is considered to be three characters long). The way you resolve this problem is by making sure the string only contains certain characters. This involves creating a string of acceptable characters, and then checking the user input against it.

For a simple example of validating a string, imagine you have a two-player hangman game and you want the user to enter in an eight letter word, so that the other player can guess it. The only characters that are allowed are the uppercase alphabet (A-Z), and there is no restriction that the word has to actually exist. (Programming in a check for that would involve keeping a dictionary of words, and that could potentially take up a lot of memory.)

Here is what the validation code for our game might look like with each of the three different validation approaches:

:"ABCDEFGHIJKLMNOPQRSTUVWXYZ
:ClrHome
:Input "WORD: ",Str1
:If 8≠length(Str1:Return
:If not(min(seq(inString(Ans,sub(Str1,I,1)),I,1,8
:Return
:"ABCDEFGHIJKLMNOPQRSTUVWXYZ→Str0
:0:Repeat Ans
:ClrHome
:Input "WORD: ",Str1
:If 8=length(Str1
:min(seq(inString(Str0,sub(Str1,I,1)),I,1,8
:End
:"ABCDEFGHIJKLMNOPQRSTUVWXYZ→Str0
:ClrHome
:Input "WORD: ",Str1
:For(I,1,8-length(Str1
:Str1+sub(Str0,randInt(1,26),1→Str1
:End
:For(I,1,8
:If not(inString(Str0,sub(Str1,I,1
:sub(sub(" "+Str1,1,I)+sub(Str0,randInt(1,26),1)+sub(Str1+" ",I+1,9-I),2,8→Str1
:End

When the user inputs a word, we loop through all of the characters in the word and get their positions in our acceptable characters string. If any of the characters weren't in the string, then their position will be zero, and when we take the minimum of all the positions, the smallest will be zero. With the making bad input valid code, we also concatenate how ever many characters we need to make the word eight characters long.

Making Validation More Friendly

There are a couple different ways you can make validation more user-friendly: displaying error messages when there is bad input, and storing input as a string and converting it to the appropriate variable type.

Displaying error messages to the user when they enter bad input helps the user correct their mistake, and provides some direction on what input you are expecting them to enter. An error message does not need to be complicated or long — just enough so that you can get the point across. For example, say a program is a number guessing game, and the user is expected to enter in a number between 1-1000. If they enter 5000, you can display the message "Between 1-1000".

Storing input as a string allows you to accept any input that the user may enter, even if it is messed up, entered in in the wrong format, or inappropriate for the variable that you are storing it to. This way instead of the program crashing when it gets bad input, it can actually handle it and do whatever it needs to to make it work. You then just check to see if the string has the appropriate value(s), and convert it to the desired variable using the expr( command.

The validation for the real variable, for example, did not include a check for whether it is a list or string. This is because you can only really check for those things when you have a string that you can manipulate. If we wanted to add that check, we can search the string for an opening curly brace and commas or any characters besides numbers. If we find those things, we know that the input is bad, and we can reject it and ask for input again.

In the case of the real variable, the other advantage of using a string is that you don't have to worry about whether the calculator is storing the variable to a list. More specifically, if a list is entered for input, the Input and Prompt commands will actually store the input to a list with the same name. This is possible because you don't need to include the character when referring to a user-defined list. (Entering a string would also work, and the string would become associated with the list.)

Besides checking the list for whether it is a real variable or string, you also can check that it is in the appropriate format. When a list is entered, it needs to start with an opening curly brace, and then have each element separated by a comma. Because most users forget to include the opening curly brace, it is very convenient to place that at the beginning of the list yourself, so that the user never even knows about needing it.

You can take that idea even further, and allow a list to be entered in many different ways: with commas and curly brackets, with commas and no brackets, as a list name (L1 through L6), or as a name starting with ∟, or as a name without the ∟. Instead of requiring one of these, the program might very well be programmed to handle all of them. This all comes down to finding alternate ways of making user input valid.

Thoughts to Consider

The amount of validation you put in a program depends on how large and/or complicated the program is. If you have an extremely complex game with all sorts of user input, then it would be appropriate to include validation for some or most of those things. The general guideline is that the amount of validation needed correlates to the size of the game — i.e., a short math routine probably wouldn't need validation.

While discussing validation, it is also important to mention that since the Input and Prompt commands only work on the home screen, you need to write your own custom input routine using the getKey command if you want to get input on the graph screen. If your entire program is already on the graph screen, however, this should not be an issue, because it makes perfect sense to maintain the user's attention on the graph screen.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/validation


Recursion

Good programmers usually design their programs to utilize subprograms (calling another program from within the program) for optimization but another alternative that is available, but less often used, is the program simply calling itself — more commonly known as recursion.

The basic premise behind recursion is breaking up a problem into smaller problems, and then working your way through each problem until they are all completed. By tackling one small problem at a time, instead of the entire problem, the code needed is typically not only smaller and easier to understand (i.e., more manageable), but also tends to be faster.

However, recursion isn't always the most appropriate approach. You can usually rewrite a recursive program to use iteration instead (whether it's a While, Repeat, or For( loop). While the iteration code may be larger, it doesn't need the additional memory for each call that the program makes like recursion does. Iteration is also better when trying to implement an algorithm with recursion isn't very practical.

Problems with Recursion

There are some problems you will come across when trying to use recursion in your programs. Each of these problems is inherent to TI-Basic because of the way TI designed it, which means you can't change them. Fortunately, you can use some creative thinking to work around them.

The first problem you will come across is that you can only call a program a set number of times before you run out of memory and the program crashes — giving you the dreaded ERR:MEMORY error. The reason that this happens is because the calculator places each program call on a stack.

The program call stack is kept in RAM, so it is fine as long as its size doesn't exceed the amount of free RAM available. Each program call takes up approximately sixteen bytes, so just divide that by the free RAM to see how many program calls you can make.

Besides simply limiting the number of program calls you make in a program (i.e., trying to keep recursion to a minimum), a work around to this problem is storing a special value to a variable (something unique that wouldn't be entered by accident), displaying a message to the user telling them to "Press ENTER" and then stopping the program with the Return command after a set number of program calls have occurred.

:312958→A
:Output(4,4,"Press ENTER
:Return

Once the user presses ENTER, you will want to include a check at the beginning of the program for the variable you used to see if its value is equal to the unique value you assigned it. If it is, you then can jump to the place in the program where you left off before. You also want to give the variable a new value so that the program won't accidentally jump to the place in the program when the program is next executed.

:If A=312958  // Check if variable equal to unique value
:Goto A
...
:Lbl A
:1→A  // Reset variable to a new value

Another problem you will cross across is that TI-Basic programs don't have return values. In 68k TI-Basic (which is much more powerful overall), a return value can be passed to the calling program, which can then use it however they want (for example, to determine which course of action to take next).

While you can't add a return value to a program, you can mimic that functionality using a variable. The best variable to use is Ans because it can take on whatever value and variable type you want, so the program doesn't have a specific variable hard-coded in. This is especially important because variables are shared by every program.

Related to creating a return value is the problem of creating (pseudo) local variables. As you deal with each program call in recursion, it is useful to be able to keep track of variables and how they change from one program call to the next. While there are no local variables, you can make a list perform in that capacity.

In addition to the list itself, an index variable that keeps track of where you are in the list is also required. Whenever you enter a program that needs a local variable, increase the index variable and add a new element to the end of the list with augment(∟NAME,{var}). When you exit the program, decrease the index variable and remove the element from the list with var→dim(∟NAME). You can access the local variable at any time with ∟NAME(var).

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/recursion


Assembly

Besides TI-BASIC, assembly is the other primary programming language available for the TI-83 series calculators. Unlike TI-BASIC, which uses commands and functions that are easy to understand, assembly is programmed in the calculator's own machine language. Thus, it is much harder to program in and read.

This lack of usability, however, is more than made up for when you consider the fact that assembly is much faster and more feature rich than TI-BASIC. Games that normally can't be done (or, if they can be done, they aren't done very well) in TI-BASIC are just considered average in assembly.

At the same time, there aren't as many assembly programmers compared to TI-BASIC programmers; and subsequently, effort has been made to enhance TI-BASIC using assembly, to make it more capable of quality games and programs. This includes:

  • Shells — A shell allows a person to run a program from inside one central place, and since most assembly programs are run through a shell, it makes sense to run your TI-BASIC programs there as well.
  • Libraries — A library enhances a TI-BASIC program in some way, providing support to an internal function of the calculator (such as lowercase text) or access to a peripheral of the calculator (such as the USB port on the TI-84+/SE). If the ones available do not suit you, you can even make your own.
  • Applications — BASIC Builder allows you to package your TI-BASIC program(s) into a Flash application, which appears in the APPS menu and gets executed just like a regular assembly application.

The TI-BASIC language itself provides three commands — Asm(, AsmPrgm, and AsmComp( — for running and compiling shell-independent assembly programs, which you simply run from the home screen or inside a program. Writing these kinds of assembly programs is actually more difficult, however, because the assembly language instructions are represented as hexadecimal numbers. There are some short assembly programs that can be written on the calculator and be of great use to BASIC programmers.

Two additional commands for running assembly programs have been added on the TI-84 Plus and TI-84 Plus SE calculators: OpenLib( and ExecLib. They can be used for running routines from Flash application libraries that have been specifically written for use with these commands. So far, however, most major libraries use other methods, for compatibility with pre-TI-84 calculators. The only existing software that uses OpenLib( and ExecLib is usb8x, a library for advanced use of the TI-84 Plus/SE USB port. Here, compatibility is obviously out of the question.

(For more on assembly, visit z80 Heaven and WikiTI.)

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/assembly


Abs

Command Summary

Returns the absolute value of a number

Command Syntax

abs(Number)

This command can be used to return the absolute value of a number, or an expression which evaluates to a number.

⁻5→X
abs(x)

Outputs: 5

Optimization

This section includes both ways to optimize use of the command, and other common pieces of code that this command can replace in an optimization. Make sure to mention if the optimization improves speed of the program, size, or both. Sample code should be included too, preferably in the following format:

If X<0
Then
⁻X→X

can be

abs(X)→X

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/nspire:abs


And

Command Summary

Boolean AND comparison of expressions or groupings of expressions.

Command Syntax

BooleanExpr1 and BooleanExpr2
BooleanList1 and BooleanList2
BooleanMatrix1 and BooleanMatrix2
Integer1 and Integer2

The and command compares two Boolean expressions (or lists or matrices of expressions) and performs the logical AND comparison, where the output is TRUE if and only if both inputs are also TRUE.

Command Output
0 and 0 0
1 and 0 0
0 and 1 0
1 and 1 1

and can also be used to simplify logical conditions. For example,

:x≥3 and x≥4
outputs
:x≥4

because, in order to satisfy both logical conditions, x need only satisfy x≥4. and can perform this process on a list or matrix of Boolean expressions:

:{x≥3,x≤0} and {x≥4,x≤-2}
outputs
:{x≥4,x≤-2}

which is the intersection of two inequalities. This can be thought of as the overlap of two regions of a number line, where x must lie in order to satisfy all of the logical conditions simultaneously.


and's final use is for bitwise comparison of integers. Consider two integers, 24 and 17, which when converted to binary become 0b11000 and 0b10001 respectively. To compare the two integers, and compares each bit of the binary number, outputing 1 when both bits are 1 and 0 otherwise:

0b11000: 24
0b10001: 17
  -----  --
0b10000: 16

Integers can be entered in any base for use with and, including binary (0b) and hexadecimal (0h). The output will match the base of the inputs (if they are identical), defaulting to decimal.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/nspire:and


Angle

Command Summary

Computes the angle of a complex number or a set of complex numbers.

Command Syntax

angle(Expr1)expression
angle(List1)list
angle(Matrix1)matrix

The angle( command computes the angle of a complex number, which corresponds to the rotation of a vector whose length is equivalent to the abs( of the number. The angle is returned in degrees, gradians, or radians, depending on the mode the calculator is in.

Degree mode
:angle(1+i) = 45
Radian mode
:angle(1+i) = π/4

angle( can also return the angles for a list or matrix of complex numbers, returning the outputs in a list or matrix respectively. angle( will attempt to return a closed-form expression for the value rather than a decimal expression when utilizing the CAS, and can also return a symbolic evaluation of an angle.

:angle(z) = π(sign(z)-1)/2

Formulas

The general formula for the angle of complex number x+iy is given by

(1)
\begin{align} \mathrm{angle}(x+iy) = \dfrac{\pi \times \mathrm{sign}(y)}{2} - \tan^{-1}\bigg(\dfrac{x}{y}\bigg) \end{align}

Often denoted as θ, the angle of a complex number is used in its polar representation

(2)
\begin{align} x+iy = re^{i\theta} \end{align}

where r is the absolute value of the number.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/nspire:angle


Binomcdf
sample.png

Command Summary

Calculates the binomial cumulative probability, either at a single value or for all values

Command Syntax

for a single value:
binomcdf(trials, probability, [lower_bound,] upper_bound)

for a list of all values (0 to trials)
binomcdf(trials, probability)

Menu Location

From inside a document:
Press Menu, then scroll to probability.
Press the right arrow, then scroll to Distributions.
Press the right arrow, then scroll to Binomial Cdf (B)

This command is used to calculate the binomial cumulative probability function. In plainer language, it solves a specific type of often-encountered probability problem, that occurs under the following conditions:

  1. A specific event has only two outcomes, which we will call "success" and "failure"
  2. This event is going to repeat a specific number of times, or "trials"
  3. Success or failure is determined randomly with the same probability of success each time the event occurs
  4. We're interested in the probability that there are at most N successes

For example, consider a couple that intends to have 4 children. What is the probability that at most 2 are girls?

  1. The event here is a child being born. It has two outcomes "boy" or "girl". In this case, since the question is about girls, it's easier to call "girl" a success.
  2. The event is going to repeat 4 times, so we have 4 trials
  3. The probability of a girl being born is 50% or 1/2 each time
  4. We're interested in the probability that there are at most 2 successes (2 girls)

The syntax here is binomcdf(trials, probability, value). In this case:

binomcdf(4,.5,2)

This will give .6875 when you run it, so there's a .6875 probability out of 4 children, at most 2 will be girls.

If you wanted the probability that at least 1 and at most 2 will be girls, the syntax would be:

binomcdf(4,.5,1,2)

Another alternate syntax for binomcdf( leaves off the last argument, value. This tells the calculator to compute a list of the results for all values. For example:

:binomcdf(4,.5

This will come to {.0625 .3125 .6875 .9375 1} when you run it. These are all the probabilities we get when you replace "at most 2 girls" with "at most 0", "at most 1", etc. Here, .0625 is the probability of "at most 0" girls (or just 0 girls), .3125 is the probability of at most 1 girl (1 or 0 girls), etc.

Several other probability problems actually are the same as this one. For example, "less than N" girls, just means "at most N-1" girls. "At least N" girls means "at most (total-N)" boys (here we switch our definition of what a success is). "No more than", of course, means the same as "at most".

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/nspire:binomcdf


Command Index (Black & White)

Ops | # | A | B | C | D | E | F | G | H | I | L | M | N | O | P | Q | R | S | T | U | V | W | X | Z

This page lists all of the commands for the TI-83/84/SE/+ models. If you have a newer TI-84 Plus C Silver Edition or TI-84 Plus CE with a color display, please visit the Color Command Index.

To access more information about the command, click on the command to go to the dedicated page for that command. To view the commands divided into sections, go to the Command Overview. To view most of the commands as they would on the calculator itself through the menus, go to the Command Menu Map.

Some commands have a superscript next to them that indicates compatibility:

  • 83+ indicates that the command requires a TI-83+, TI-83+SE, TI-84+, TI-84+SE, or TI-84+CSE calculator.
  • 84+ indicates that the command requires a TI-84+,TI-84+SE, or TI-84+CSE calculator.
  • 84+2.30 indicates that the command requires a TI-84+, TI-84+SE, or TI-84+CSE calculator with OS 2.30 or higher.
  • 84+2.53MP indicates that the command requires a TI-84+, TI-84+SE, or TI-84+CSE calculator with OS 2.53MP or higher.

See Compatibility for a chart of only the commands that require certain calculators or operating systems.

Ops

#

A

B

C

D

E

F

G

H

I

L

M

N

O

P

Q

R

S

T

U

V

W

X

Z

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/command-index-bw


Command Index (Color)

Ops | # | A | B | C | D | E | F | G | H | I | L | M | N | O | P | Q | R | S | T | U | V | W | X | Z

This page lists all of the commands for the TI-84 Plus C Silver Edition and the TI-84 Plus CE. If you have an older TI-83/84+ with a monochrome display, please visit the Monochrome Command Index.

To access more information about the command, click on the command to go to the dedicated page for that command. To view the commands divided into sections, go to the Command Overview. To view most of the commands as they would on the calculator itself through the menus, go to the Command Menu Map.

Some commands have a superscript next to them that indicates compatibility:

  • CSE indicates that the command requires a TI-84 Plus CSE
  • CE indicates that the command requires a TI-84 Plus CE or a specific OS version

See Compatibility for a chart of only the commands that require certain calculators or operating systems.

Ops

#

A

B

C

D

E

F

G

H

I

L

M

N

O

P

Q

R

S

T

U

V

W

X

Z

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/command-index


Fpart
sample.png

Command Summary

Returns the fractional part of a value.

Command Syntax

fPart(value)

fPart(value) returns the fractional part of value. Also works on complex numbers, lists and matrices.

fPart(5.32)
             .32
fPart(4/5)
              .8
fPart(‾5.32)
             ‾.32
fPart(‾4/5)
              ‾.8

Advanced Uses

fPart(, along with int( or iPart(, can be used for integer compression.


Also, fPart( is an easy way to find A mod B (the positive remainder when A is divided by B).

:B(A<0)+iPart(BfPart(A/B))

If A is guaranteed to be positive, the following shorter code can be used, omitting B(A<0):

:iPart(BfPart(A/B))

Finally, the easiest way to check if a number is a whole number is not(fPart(X:

:If not(fPart(X:Then
: // X is an integer
:Else
: // X is not an integer
:End

You can use this, for example, to check if a number is divisible by another: if X is divisible by N, then X/N is a whole number. This is useful when you want to find the factors of a number. Warning: when storing values with repeating decimals and later multiplying them to see if a number makes it an integer it can return a value of 1 or -1 instead of 0 even if it is an integer. Example: if you store 1/3 as X and then do fpart(3x) it will return 1 instead of 0. This is because fpart(.999…) results in .999… and then rounds to 1 when displaying rather than rounding to 1.0 and then displaying the fpart( as 0.

Optimization

Often you want to find the value of a-1 mod b — this occurs, for example, in movement routines with wraparound. However, the problem is that if a=0, a-1 will be negative. Rather than use the longer version of the modulo routine, you might replace subtracting 1 with adding (b-1). This will have the same result, but without sign problems.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/nspire:fpart


Overview of Commands

The TI-Basic programming language features a wide range of commands for all kinds of things, including output, user input, manipulating variables, linking calculators, and especially math — don't forget a calculator is primarily designed for doing math. In total, there are almost 400 commands on the TI-83+ calculators, and the TI-84+/SE calculators have an additional 22 commands (because of the new time and date commands and the new math commands added in OS 2.30).

Because sorting through all of these commands is a rather daunting task, especially when trying to figure out which one is appropriate for accomplishing a desired task, we have chosen to present them in three different formats:

  • Alphabetical Index — A listing of the commands sorted in alphabetical order.
  • Menu Map — A listing of the commands sorted by where they appear in their different menus on the calculator.
  • Category — A listing of the related commands grouped together based on their common function and purpose.

There are eleven different command categories that we have come up with:

We tried to do our best to come up with these categories because we believe they reflect the natural divisions of the commands, although some of the commands have functionality that overlaps more than one category. In this case, we decided to simply go with the primary use of the command.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/commands


Summationsigma

This command will open up a template that allows you to evaluate an expression in sigma notation.
This command is accessible by pressing ALPHA then WINDOW then 2.
This command is especially useful for statistics and algebra.
It is also available in the programming mode. You can access it either through the catalog or the same way specified above.
The syntax for this command is

Σ(Expression,Variable,Starting number,Ending number)

An example would be to determine the sum of 2*X for X going from 1 to 10.
It would look like this:
Σ(2X,X,1,10

The result would be
110

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/summationsigma


The ! Command
FACTORIAL.GIF

Command Summary

Calculates the factorial of a number or list.

Command Syntax

value!

Menu Location

Press:

  1. MATH to access the math menu.
  2. LEFT to access the PRB submenu.
  3. 4 to select !, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

! is the factorial function, where n! = n*(n-1)! and 0! = 1, n an nonnegative integer. The function also works for arguments that are half an odd integer and greater than -1/2: $(-\frac1{2})!$ is defined as $\sqrt{\pi}$ and the rest are defined recursively. 69 is the largest number for which the calculator can perform the operation.

3!
     6
(‾.5)!
     1.772453851
Ans²
     3.141592654

The combinatorial interpretation of factorials is the number of ways to arrange n objects in order.

Error Conditions

  • ERR:DOMAIN for any numbers except the ones mentioned above.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/factorial


The ! Command

factorial.png

Command Summary

Takes the factorial of a number.

Command Syntax

number!

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The ! operator takes the factorial of a number: for a positive, whole number, n! is defined as n*(n-1)*(n-2)*…*3*2*1. As a special case, 0! is defined to be 1.

The factorial has a special meaning in combinatorics: n! is the number of ways you can order n objects. For instance, 3!=6 because there are 6 ways to order 3 objects:

  • A B C
  • A C B
  • B A C
  • B C A
  • C A B
  • C B A

As can be expected, factorials get very large very quickly. The calculator can only compute an exact integer result for factorials up to 299!, and an approximate result for factorials up to 449!. Beyond that, the numbers involved are replaced by ∞ (infinity) in expressions.

While there are some formulas to define factorials of non-integer values, the calculator doesn't use them. It will leave an expression like (1/2)! unsimplified. However, the factorial of a number less than or equal to -1 will be "undef".

:5!
           120
:299!
           1020191707388... (600 more digits)
:449!
           3.85193e997
:(-2)!
           undef

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:factorial


The # Command

indirection.png

Command Summary

Gets a variable given its name as a string.

Command Syntax

#var-name

Menu Location

On a widescreen calculator, press 2nd # to paste #.

Or, on any calculator model, press:

  • 2nd CHAR to enter the CHAR popup menu.
  • 3 to enter the Punctuation submenu.
  • 3 again to paste #.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

The # operator takes a string containing a variable name, such as "x", and gives you the variable itself. This can be used to get the value of that variable (kind of like a weaker version of expr()), but the # operator really shines when you need to refer to the variable itself: storing to it, for example. 5→expr("var") will give you an error. 5→#"var", however, will work.

:"x"→str
:5→#str
           5
:x
           5
:DelVar #str
:x
           x

You'll see # called the "indirection" operator (for instance, in the command catalog). This is because using # is an indirect way of accessing a variable's value: you don't have the variable itself to work with, just its name.

Advanced Uses

The # command is particularly useful for dealing with picture variables, if you don't know the exact name of the picture ahead of time. For example, you might have two pictures, called 'cat' and 'dog', that you need to display depending on whether x=1 or x=2. This can be done with an If command, but that gets more and more complicated as you add pictures. On the other hand, you can always do this:

:{"cat","dog"}→pics
:RclPic #(pics[x])

The # command is necessary here because RclPic and commands like it want the actual picture variable as an argument, not a string with its name; expr() wouldn't work either because it would try to find the value of 'cat', and get an error.


Whenever you're dealing with external files created by someone else (such as external levels for a game), you don't know the variable names ahead of time, so you'll need the # operator. For the example of an external level, you would first input the variable name of the level into a string variable (say, the variable 'level'). Then you can use '#level', just as you would a regular variable, to refer to it.

Optimization

In many cases, both # and expr() will do the same thing. In these cases, it's still better to use #, because it's faster.

Error Conditions

360 - Indirection string is not a valid variable name happens when the string used with # isn't allowed as a variable name (e.g. longer than 8 characters).

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:indirection


The % Command
PERCENT.GIF

Command Summary

Short for dividing by 100.

Command Syntax

value%

Menu Location

This command can only be accessed through a hex editor (its hex code is 0xBB 0xDA)

Calculator Compatibility

TI-83/84+/SE, OS v1.15+

Token Size

2 bytes

The % symbol is an undocumented command on the TI-83 series calculators starting with OS version 1.15. It's useful as a shortcut for percents - it divides by 100, so it will convert numbers to percentages. For example, 50% will become 50/100 or 1/2, which is just what 50% should be.

Although this trick can save you a few bytes, it also makes your program incompatible with old OS versions — it's up to you to decide if the tradeoff is worth it.

The % symbol is not quite equivalent to the value 0.01: typing in % by itself will give you a syntax error, as expected.

Entering the % symbol

There are several assembly programs out there that can let you access the % symbol if you know what you're doing, but here is a short, self-contained way. First, create an assembly program by entering the following into the program editor:

:AsmPrgmEFF1423605C9
:BBDA

Then compile it: for example, if you entered the above into prgmX, and prgmY is free, then you can run

AsmComp(prgmX,prgmY

Then run the compiled assembly program:

Asm(prgmY

Now the compiled assembly program will become unlocked and contain the characters:

:??ˣ√B6BoxPlotsinh⁻¹(%

Most of this is garbage data and can be deleted, and the final character is the % character we wanted. (If you delete the other characters, then the % symbol can be accessed at any time by pressing [2nd][RCL] and choosing prgmY.)

Error Conditions

  • ERR:INVALID is thrown on older operating system versions.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/percent


The % Command

percent.png

Command Summary

Divides a number by 100.

Command Syntax

number%

Menu Location

  • Press 2nd CHAR to enter the CHAR menu.
  • Press 3 to enter the Punctuation submenu.
  • Press 5 to select %.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The % operator is a cheap shortcut for dividing a number by 100: for instance, 25% = 25/100 = 1/4. When used on a list or matrix, it divides every element by 100.

It's somewhat higher in priority than regular division, so you don't need parentheses as often with it: for instance, 4^50% is equal to 4^(1/2)=2, not to (4^50)%.

Related Commands

  • / (divide)
  • E

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:percent


The & Command

concatenate.png

Command Summary

Joins two strings together.

Command Syntax

string&string

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press D to enter the String submenu.
  • Press 4 to select &.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

The & operator joins two strings together, one after the other, returning one large string.

:"Hello"&"World"
           "HelloWorld"
:5→n
:"The value of n is "&string(n)
           "The value of n is 5"

Appending strings is very useful when you want to display text. If you want to display more than one string on the same line, for instance with the Text command, you'll need to use & to combine the strings.

By default, & doesn't put in any separation between the strings, which can look weird: you can see this in the above example, where joining "Hello" and "World" made "HelloWorld". With multiple uses of &, you can put in any separator you like:

:"Hello"&" "&"World"
           "Hello World"

If you want to use & to build up a string from scratch, start with "" — the empty string.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:append


The * Command
MULTIPLY.GIF

Command Summary

Returns the multiplication of two numbers.

Command Syntax

value1 * value2

Menu Location

Press [*]

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The * (multiply) operator takes two numbers, variables, or expressions and multiplies their values together, thus returning a single new value. The * operator appears higher in the order of operations than both + and -, so if those appear in an expression, * will be executed first. In addition, the / operator has the same order of operations as *, so the calculator simply executes them left to right in the order that they appear.

:1*1
           1

:5→X
:2*3X
           30

:2→A:3→B
:A/B*B/A
           1

Advanced Uses

As it turns out, the most advanced way to use * is by not using it at all. On z80-based TI calculators, two adjacent expressions or variables are implicilty multiplied even without a * mark.

:5*A
should be
:5A

:5*cos(N*θ
should be
:5cos(Nθ

There are a few cases in which omitting the multiplication sign doesn't work. For example, 2^4*E3 (which evaluates to 16000) can't be replaced by 2^4E3, since the latter is interpreted as 2^(4000).

Optimization

The * sign has the same truth value as the and operator because they both return zero if one or more of the numbers is zero (based on Boolean logic). Consequently, you sometimes see people implicitly multiplying expressions together in conditionals and loops, instead of joining them together with and. Unfortunately, this is not only usually larger in size, but often times slower.

:If (A=2)(B=7
should be
:If A=2 and B=7

It does save some space when you can avoid using parentheses:

:If A and B
could be
:If AB

Timing

The amount of time taken to multiply two real floating-point numbers varies with the sum of the digits (including in the fractional part) of the right argument. On a 15 MHz calculator, a single multiplication in the worst case (when the right argument is 99999999999999) takes 3.3 ms, the best case (when the right argument is 0) takes about 0.1 ms, and the average case (for fourteen-digit floating point numbers) takes about 1.7 ms.

These timings do not include parser overhead or variable recall time, which are often significant in overall program speed.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/multiply


The * Command

multiply.png

Command Summary

Returns the multiplication of two numbers.

Command Syntax

value1 * value2

Menu Location

Press the [*] key to paste *.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The * operator multiplies two numbers, variables, or expressions. In many cases, it's implied — 5x, for instance, will be assumed to be 5*x. There are two exceptions: long variable names — xy will be interpreted as a single variable, not as x*y — and function calls — f(x) will be interpreted as f() applied to x, not as f*x.

Multiplication has higher priority than + and -, so it will be done before them; it has the same priority as /.

:x*y
        x*y
:2*2
        4

Advanced Uses

Multiplying matrices is not the same as multiplying their individual elements (which the .* operator does). To multiply two matrices, the first must have the same number of columns as the second has rows. The product of an MxN matrix with an NxP matrix will be an MxP matrix, whose (a,b)th entry will be the dot product of the ath row of the first matrix with the bth column of the second.

Error Conditions

240 - Dimension mismatch happens when the dimensions of two matrices don't match up for multiplication to work.

Related Commands

  • - (subtract)
  • + (Add)
  • / (divide)

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:multiply


The + Command
ADD.GIF

Command Summary

Returns the sum of two numbers, or joins two strings together.

Command Syntax

value1 + value2

string1 + string2

Menu Location

Press [+]

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The + (add) operator takes two numbers, variables, or expressions and adds their values together, thus returning a single new value. The + operator appears lower in the order of operations than both * and /, so if those appear in an expression, they will be executed first. In addition, the - operator has the same order of operations as +, so the calculator simply executes them left to right in the order that they appear.

:1+1
           2

:5→X
:2+3X
           17

:2→A:3→B
:A/B+B/A
           2.166666667

Advanced Uses

The + operator is overloaded (meaning it has more than one function) by the calculator, and it can be used to put strings together. The strings can consist of whatever combination of text and characters that you want, but it unfortunately does not allow you to join a string to a number (i.e., "Hello5" cannot be made with "Hello"+5).

:"HELLO"+"WORLD
           "HELLOWORLD

:"TI"+"-"+"BASIC
           "TI-BASIC

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/add


The + Command

add.png

Command Summary

Returns the sum of two numbers.

Command Syntax

value1 + value2

Menu Location

Press the [+] key to paste +.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The + operator adds two numbers, variables, or expressions together. Order of operations dictates that it's calculated after * and /, and at the same time as -.

The + operator can also be used on lists and matrices. For the most part, it behaves in the intuitive way, distributing the operation over each element. However, adding a number to a matrix (in either order) behaves differently: the number is only added along the main diagonal of the matrix. For "normal" addition that applies to every element of the matrix, see .+.

:1+1
           2
:5→x
:2+3*x
           17
:[1,2;3,4]+100
           [101  2]
           [3  104]

Related Commands

  • - (subtract)
  • * (multiply)
  • / (divide)

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:add


The - Command
SUBTRACT.GIF

Command Summary

Returns the difference between two numbers.

Command Syntax

value1 - value2

Menu Location

Press [-]

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The - (subtract) operator takes two numbers, variables, or expressions and subtracts one from the other, thus returning the difference between them. The - operator appears lower in the order of operations than both * and /, so if those appear in an expression, they will be executed first. In addition, the + operator has the same order of operations as -, so the calculator simply executes them left to right in the order that they appear.

:1-1
           0

:5→X
:2-3X
           -13

:2→A:3→B
:A/B-B/A
           -.8333333333

Error Conditions

  • ERR:SYNTAX is thrown if you try to use - (subtract) in place of (negative). Because they look very similar, it's easy to get this error; at the same time, it's an easy error to fix.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/subtract


The - Command

subtract.png

Command Summary

Returns the difference of two numbers.

Command Syntax

value1 - value2

Menu Location

Press the [-] key to paste -.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The - operator subtracts two numbers, variables, or expressions. Order of operations dictates that it's calculated after * and /, and at the same time as +.

The - operator can also be used on lists and matrices. For the most part, it behaves in the intuitive way, distributing the operation over each element. However, subtracting a number from a matrix (or a matrix from a number) behaves differently: the number is only subtracted along the main diagonal of the matrix. For "normal" subtraction that applies to every element of the matrix, see .-.

:1-1
           0
:5→x
:2-3x
           -13
:[1,2;3,4]-100
           [-99  2]
           [3  -96]

Related Commands

  • + (add)
  • * (multiply)
  • / (divide)

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:subtract


The .* Command

dotmultiply.png

Command Summary

Multiples two values, using element-by-element multiplication for two matrices.

Command Syntax

value1 .* value2

Menu Location

  • Press 2nd MATH to enter the MATH menu.
  • Press 4 to enter the Matrix submenu.
  • Press K to enter the Element ops submenu.
  • Press 3 to select .*.

…frankly, just typing it is way easier.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

In most cases, .* does the same thing as *. The difference only applies to multiplying two matrices. Whereas * uses the linear-algebra definition (see its article for details), .* does the simple thing and multiplies the matrices element by element (obviously, they must match in size for this to work).

:[1,2;3,4] .* [a,b;c,d]
        [a    2*b]
        [3*c  4*d]

Error Conditions

240 - Dimension mismatch happens when the matrices being multiplied don't match in size.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:dotmultiply


The .+ Command

dotadd.png

Command Summary

Adds two values, using element-by-element addition when adding a matrix and a number.

Command Syntax

value1 .+ value2

Menu Location

  • Press 2nd MATH to enter the MATH menu.
  • Press 4 to enter the Matrix submenu.
  • Press K to enter the Element ops submenu.
  • Press 1 to select .+.

…frankly, just typing it is way easier.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The .+ command works like plain + in most cases, adding two values together. It's distinguished by its application to matrices: in particular, when adding a matrix and a scalar. Normal addition of a matrix and a single value will add that value along the main diagonal only: as though the value were multiplied by the identity matrix. However, .+ does the more intuitive thing (for anyone but an algebraist, anyway) and adds the value to every element of the matrix.

:[a,b;c,d]+x
        [x+a  b  ]
        [c    x+d]
:[a,b;c,d].+x
        [x+a  x+b]
        [x+c  x+d]

It doesn't really make much sense to use .+ to add other kinds of values, but you can do it if you like.

Although the order of the matrix and the scalar doesn't matter, be warned that in some cases, the . will be interpreted as a decimal point. You can put spaces to help the calculator figure out what you mean.

:5.+[a,b;c,d]
        [a+5.  b   ]
        [c     d+5.]
:5 .+ [a,b;c,d]
        [a+5  b+5]
        [c+5  d+5]

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:dotadd


The .- Command

dotsubtract.png

Command Summary

Subtracts two values, using element-by-element subtraction when subtracting a matrix and a number.

Command Syntax

value1 .- value2

Menu Location

  • Press 2nd MATH to enter the MATH menu.
  • Press 4 to enter the Matrix submenu.
  • Press K to enter the Element ops submenu.
  • Press 2 to select .-.

…frankly, just typing it is way easier.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The .- command works like plain - in most cases, taking the difference of two values. It's distinguished by its application to matrices: in particular, when subtracting a matrix and a scalar (in either order). Normally, the operation will be done along the main diagonal only: as though the value were multiplied by the identity matrix. However, .- does the more intuitive thing (for anyone but an algebraist, anyway) and subtracts the value from every element of the matrix (or, if the matrix is being subtracted, subtracts every element from the scalar value).

:[a,b;c,d]-x
        [-x+a  b   ]
        [c     -x+d]
:[a,b;c,d].-x
        [-x+a  -x+b]
        [-x+c  -x+d]

It doesn't really make much sense to use .- to add other kinds of values, but you can do it if you like.

When subtracting a matrix from a constant number, be warned that the . may be interpreted as a decimal point. You can put spaces to help the calculator figure out what you mean.

:5.-[a,b;c,d]
        [-a+5.  -b   ]
        [-c     -d+5.]
:5 .+ [a,b;c,d]
        [-a+5  -b+5]
        [-c+5  -d+5]

Related Commands

  • - (subtract)
  • .+

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:dotsubtract


The ./ Command

dotdivide.png

Command Summary

Divides two values, doing so element-by-element for two matrices.

Command Syntax

value ./ value

Menu Location

  • Press 2nd MATH to enter the MATH menu.
  • Press 4 to enter the Matrix submenu.
  • Press K to enter the Element ops submenu.
  • Press 4 to select ./.

…frankly, just typing it is way easier.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The ./ operator works just like / in most cases. The only exception is with matrices. The / command can't do anything with then (except for dividing a matrix by a value), but ./ will just apply the operation element-by-element. Obviously, when this is done for two matrices, their dimensions have to match up.

:[a,b;c,d] ./ [e,f;g,h]
           [a/e  b/f]
           [c/g  d/h]

When dividing a constant number by a matrix with ./, you may need to space it out so that there's no confusion between ./ and a decimal point.

:1./[a,b;c,d]
           Error: Data type
:1 ./ [a,b;c,d]
           [1/a  1/b]
           [1/c  1/d]

Error Conditions

240 - Dimension mismatch happens when dividing a matrix by another matrix of a different size.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:dotdivide


The .^ Command

dotpower.png

Command Summary

Raises a value to a power, doing this element-by-element for matrices.

Command Syntax

base .^ exponent

Menu Location

  • Press 2nd MATH to enter the MATH menu.
  • Press 4 to enter the Matrix submenu.
  • Press K to enter the Element ops submenu.
  • Press 1 to select .+.

…frankly, just typing it is way easier.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The .^ operator is generally the same as ^, except when dealing with matrices. While ^ does quite a lot of matrix-specific stuff (check out its page for more information), .^ just applies it element-by-element:

:[a,b;c,d] .^ 2
           [a^2  b^2]
           [c^2  d^2]

The command can handle any choice of matrix and scalar as the base and exponent. However, if you're raising a constant number to a matrix power, be careful that the dot in .^ is not confused for a decimal point, by adding extra spaces:

:2.^[a,b;c,d]
           Error: Data type
:2 .^ [a,b;c,d]
           [2^a  2^b]
           [2^c  2^d]

Although this doesn't come up often, be aware that .^, like ^, is evaluated from right to left: a.^b.^c is calculated as a.^(b.^c), not as (a.^b).^c.

Error Conditions

240 - Dimension mismatch happens when a matrix is raised to the power of another matrix, with different dimensions.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:dotpower


The / Command
DIVIDE.GIF

Command Summary

Returns the division of two numbers.

Command Syntax

value1 / value2

Menu Location

Press [/]

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The / (divide) operator takes two numbers, variables, or expressions and divides them, thus returning a single new value. The / operator appears higher in the order of operations than both + and -, so if those appear in an expression, / will be executed first. In addition, the * operator has the same order of operations as /, so the calculator simply executes them left to right in the order that they appear.

:1/1
           1

:5→X
:2/3X
           3.333333333

:2→A:3→B
:A/B/B/A
           .1111111111

Related Commands

Error Conditions

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/divide


The / Command

divide.png

Command Summary

Divides one number by another.

Command Syntax

value1 / value2

Menu Location

Press the [/] key to paste /.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The / operator divides two numbers, variables, or expressions. It has higher priority than + and -, so it will be done before them; it has the same priority as *.

:x/y
        x/y
:2/2
        1

Though division by zero isn't allowed, it will not cause an error; instead it returns the value undef — short for "undefined." Dividing by a variable that hasn't been defined yet will cancel it if it occurs on both sides: 5*x/x will equal 5; a short warning will be given to the effect that this isn't valid for x=0.

Related Commands

  • - (subtract)
  • * (multiply)
  • + (add)

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:divide


The < Command
LESSTHAN.PNG

Command Summary

Returns true if value1 is less than value2.

Command Syntax

value1<value2

Menu Location

Press:

  1. 2nd TEST to access the test menu.
  2. 5 to select <, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The < (less than) operator takes two numbers, variables, or expressions, and tests to see if the first one has a value less than the second one. It will return 1 if it is less than, and 0 if it is not. When determining the order of operations, < will be executed after the math operators, but it will be executed before the logical operators and in the order that it appears from left to right with the other relational operators.

:1<0
           0

:DelVar X3→Y
:X<Y
           1

Advanced Uses

Just like the other relational operators, < can take real numbers and lists for variables. In order to compare the lists, however, both must have the same dimensions; if they don't, the calculator will throw a ERR:DIM MISMATCH error. When comparing a real number to a list, the calculator will actually compare the number against each element in the list and return a list of 1s and 0s accordingly.

:{2,4,6,8}<{1,3,5,7
           {0 0 0 0}
:5<{1,2,3,4,5
           {0 0 0 0 0}

Unfortunately, < does not work with strings, matrices, or complex numbers (only = and do), and the calculator will actually throw a ERR:DATA TYPE error if you try to compare them. In the case of strings, however, it should be pretty obvious why: a string represents a sequence of characters, and does not associate a value to any character, so there is nothing to compare.

Error Conditions

  • ERR:DATA TYPE is thrown if you try to compare strings, matrices, or complex numbers.
  • ERR:DIM MISMATCH is thrown if you try to compare two lists that have different dimensions.

Related Commands

  • = (equal)
  • (not equal)
  • > (greater than)
  • (greater than equal)
  • (less than equal)

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/lessthan


The < Command

lessthan.png

Command Summary

Tests if one value is smaller than another.

Command Syntax

value1<value 2

Menu Location

Press [2nd][<] to enter <.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The < operator compares two values, returning true if the right side is greater, and false otherwise. It is a basic building block of the conditions used by commands such as If, when(), and While. The results of < and the other relational operators (=, , >, , and ) can be combined with the and, or, xor, and not operators to create more complicated conditions.

It returns a single value for most types of data, and returns false if the two sides are mismatched in type: comparing a single number to a list, for instance, or comparing two lists that are of a different size. The only exception is when comparing two lists or two matrices of the same size: in that case, it compares them element-by-element, and returns a list or matrix of true/false values.

:3<4
           true
:3<2
           false
:{1,2,3}<{3,2,1}
           {true  false  false}

If either side or both contains undefined variables, < will wait to return a value. You can do math with the resulting inequality, and if an operation makes sense, it will be applied to both sides: for instance, if x<y, then you can negate it to get -x>-y. An operation will not be applied to both sides if it wouldn't be consistent with the previous inequality: for example, you can't square both sides, since even if x<y the comparison between x^2 and y^2 could go in any order. You can also extract the two halves of the inequality with left() and right().

Advanced Uses

The < operator can also compare strings. It does so by comparing the character codes of each character, and orders the strings by the first difference it finds. This ideally means that the strings are ordered by dictionary order: for example, "aardvark"<"apple", since it would come later in the dictionary.

However, the problem is that all uppercase letters have a smaller character code than lowercase letters, so this only holds true if the strings are the same case. Otherwise, strange results can happen: for instance, "Apple"<"aardvark", since "A" comes before "a".

Related Commands

  • = (equal)
  • (not equal)
  • > (greater than)
  • (greater than or equal)
  • (less than or equal)

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:less-than


The = Command
EQUAL.PNG

Command Summary

Returns true if value1 is equal to value2.

Command Syntax

value1=value2

Menu Location

Press:

  1. 2nd TEST to access the test menu.
  2. 1 to select =, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The = (equal) operator takes two numbers, variables, or expressions, and tests to see if they are equal to each other. It will return 1 if they are, and 0 if they are not. When determining the order of operations, = will be executed after the math operators, but it will be executed before the logical operators and in the order that it appears from left to right with the other relational operators.

1=0
           0
0->X
           0
3→Y
           3
X=Y
           0

Precision

The TI-84+ calculator appears to round numbers to 10 significant digits when checking for equality (even though behind the scenes in memory numbers are stored up to 14 digits). So for example:

0.99999999999=1       // True  (11 digits get rounded to 10)
0.9999999999=1        // False (with 10 digits not rounded)
99999.999999=100000   // True  (11 digits get rounded to 10)
99999.99999=100000    // False (with 10 digits not rounded)

Advanced Uses

Just like the other relational operators, = can take real numbers and lists for variables. In order to compare the lists, however, both must have the same dimensions; if they don't, the calculator will throw a ERR:DIM MISMATCH error. When comparing a real number to a list, the calculator will actually compare the number against each element in the list and return a list of 1s and 0s accordingly.

{2,4,6,8}={1,3,5,7
           {0 0 0 0}
5={1,2,3,4,5
           {0 0 0 0 1}

Besides real numbers and lists, = also allows you compare strings, matrices, and complex numbers. However, the variables must be of the same type, otherwise the calculator will throw a ERR:DATA TYPE error.

[[1,2,3]]=[[1,2,3
                      1
"HELLO"="WORLD
                      0
(3+4i)=(5-2i)
                      0

When matrices are compared, the result is 1 if the matrices are identical. Both matrices must have the same dimensions, otherwise you will get a ERR:DIM MISMATCH error. Internally, the calculator compares values from the bottom right of each matrix, moving left across each row from bottom to top. If unequal elements are found, the calculator returns 0 without examining the rest of the matrix.

Optimization

When a variable is used in a conditional statement, and the only values that are possible for a variable are 1 and 0, you can get rid of the = sign and simply use the variable by itself.

:If X=1
can be
:If X

Error Conditions

  • ERR:DATA TYPE is thrown if you try to compare two different kinds of variables, such as a string and number or a list and matrix.
  • ERR:DIM MISMATCH is thrown if you try to compare two lists or matrices that have different dimensions.

Related Commands

  • (not equal)
  • > (greater than)
  • (greater than equal)
  • < (less than)
  • (less than equal)

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/equal


The = Command

equal.png

Command Summary

Tests if two values are equal.

Command Syntax

value1=value 2

Menu Location

Press the [=] key to enter =.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The = operator compares two values, returning true if they're equal, and false otherwise. It is a basic building block of the conditions used by commands such as If, when(), and While. The results of = and the other relational operators (, >, , <, and ) can be combined with the and, or, xor, and not operators to create more complicated conditions.

It returns a single value for most types of data, and returns false if the two sides are mismatched in type: comparing a single number to a list, for instance, or comparing two lists that are of a different size. The only exception is when comparing two lists or two matrices of the same size: in that case, it compares them element-by-element, and returns a list or matrix of true/false values.

:2+2=4
           true
:2+2=5
           false
:{1,2,3}={1,4,3}
           {true  false  true}

If either side or both contains undefined variables, = will wait to return a value unless it's something clearly true for any value of the variable (for instance, x=x). You can do math with the resulting equation (most operations will be applied to both sides), and extract the two halves of it with left() and right().

Optimization

Testing "If x=true" is redundant in most cases; you can shorten that to "If x". Similarly, "If x=false" can be "If not x".

Related Commands

  • (not equal)
  • > (greater than)
  • (greater than or equal)
  • < (less than)
  • (less than or equal)

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:equal


The > Command
GREATERTHAN.PNG

Command Summary

Returns true if value1 is greater than value2.

Command Syntax

value1>value2

Menu Location

Press:

  1. 2nd TEST to access the test menu.
  2. 3 to select >, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The > (greater than) operator takes two numbers, variables, or expressions, and tests to see if the first one has a value greater than the second one. It will return 1 if it is greater, and 0 if it is not. When determining the order of operations, > will be executed after the math operators, but it will be executed before the logical operators and in the order that it appears from left to right with the other relational operators.

:1>0
           1

:DelVar X3→Y
:X>Y
           0

Advanced Uses

Just like the other relational operators, > can take real numbers and lists for variables. In order to compare the lists, however, both must have the same dimensions; if they don't, the calculator will throw a ERR:DIM MISMATCH error. When comparing a real number to a list, the calculator will actually compare the number against each element in the list and return a list of 1s and 0s accordingly.

:{2,4,6,8}>{1,3,5,7
           {1 1 1 1}
:5>{1,2,3,4,5
           {1 1 1 1 0}

Unfortunately, > does not work with strings, matrices, or complex numbers (only = and do), and the calculator will actually throw a ERR:DATA TYPE error if you try to compare them. In the case of strings, however, it should be pretty obvious why: a string represents a sequence of characters, and does not associate a value to any character, so there is nothing to compare.

Error Conditions

  • ERR:DATA TYPE is thrown if you try to compare strings, matrices, or complex numbers.
  • ERR:DIM MISMATCH is thrown if you try to compare two lists that have different dimensions.

Related Commands

  • = (equal)
  • (not equal)
  • (greater than equal)
  • < (less than)
  • (less than equal)

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/greaterthan


The > Command

greaterthan.png

Command Summary

Tests if one value is larger than another.

Command Syntax

value1>value 2

Menu Location

Press [2nd][>] to enter >.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The > operator compares two values, returning true if the left side is greater, and false otherwise. It is a basic building block of the conditions used by commands such as If, when(), and While. The results of > and the other relational operators (=, , , <, and ) can be combined with the and, or, xor, and not operators to create more complicated conditions.

It returns a single value for most types of data, and returns false if the two sides are mismatched in type: comparing a single number to a list, for instance, or comparing two lists that are of a different size. The only exception is when comparing two lists or two matrices of the same size: in that case, it compares them element-by-element, and returns a list or matrix of true/false values.

:3>4
           false
:3>2
           true
:{1,2,3}>{3,2,1}
           {false  false  true}

If either side or both contains undefined variables, > will wait to return a value. You can do math with the resulting inequality, and if an operation makes sense, it will be applied to both sides: for instance, if x>y, then you can negate it to get -x<-y. An operation will not be applied to both sides if it wouldn't be consistent with the previous inequality: for example, you can't square both sides, since even if x>y the comparison between x^2 and y^2 could go in any order. You can also extract the two halves of the inequality with left() and right().

Advanced Uses

The > operator can also compare strings. It does so by comparing the character codes of each character, and orders the strings by the first difference it finds. This ideally means that the strings are ordered by dictionary order: for example, "apple">"aardvark", since it would come later in the dictionary.

However, the problem is that all uppercase letters have a smaller character code than lowercase letters, so this only holds true if the strings are the same case. Otherwise, strange results can happen: for instance, "aardvark">"Apple", since "a" comes after "A".

Related Commands

  • = (equal)
  • (not equal)
  • (greater than or equal)
  • < (less than)
  • (less than or equal)

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:greater-than


The ^ Command
POWER.GIF

Command Summary

Raises a number to a power.

Command Syntax

x^y

Menu Location

Press [^]

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The ^ operator is used to raise a number to a power. It can be used with numbers, expressions, and lists. It can be used for taking nonnegative integer powers of square matrices (up to the 255th power only, however), but not for negative powers (use ֿ¹ instead) or matrix exponentials (which the TI-83+ cannot do).

In general, x^y returns the same results as e^(y*ln(x)). For expressions of the form x^(p/q), where p and q are integers and q is an odd number, the principal branch is returned if x is complex, but the real branch is returned if x is a negative real number.

(-1)^(1/3)
        -1
(-1+0i)^(1/3)
        .5+.8660254038i

Optimization

When raising 10 or e to a power, use the 10^( and e^( commands instead. Similarly, use the ², ³, or ֿ¹ commands for raising a number to the 2, 3, or -1 power.

Error Conditions

  • ERR:DOMAIN is thrown when calculating 0^0, or raising 0 to a negative power.
  • ERR:NONREAL ANS is thrown in Real mode if the result is complex (and the operands are real)

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/power


The ^ Command

power.png

Command Summary

Raises a number to a power.

Command Syntax

base ^ exponent

Menu Location

Press the [^] key to paste ^.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The ^ operator is used to raise a number (the base) to a power (the exponent) — x^y is "pretty-printed" as xy. When the exponent is a positive integer, this is equivalent to multiplying the base by itself that many times.

When the base is a real number, the result will always be a real number if possible: for example (-1)^(1/3) will return -1. Some powers will return a complex number because there is no real number answer (or give an error, if the calculator is in real number mode). When the base is a complex number, the result will be the principal branch.

For lists, the ^ operator works componentwise — x^{a,b,c,…} will return {x^a,x^b,x^c,…}, {x,y,z,…}^a will return {x^a,y^a,z^a,…}, and two lists of the same length will be matched up element by element.

:2^4
           16
:(-1)^(1/2)
           i
:0^0
           undef

Typing [2nd] [LN] or [♦] [LN] also pastes e^( — this is not a separate command (unlike the TI-83 series), and just uses the ^ operator to do its work. It is, however, the simplest way to type the constant e.

A minor quirk of the ^ operator is that if it's present multiple times in one expression, it is evaluated right to left (unlike most commands, which are evaluated left to right). For example, x^y^z will be interpreted as x^(y^z) rather than (x^y)^z. The reason this is done is that (x^y)^z can easily be rewritten as x^(y*z), so there's no need for two powers. x^(y^z) can't be rewritten that way. Therefore, it's much more meaningful to interpret x^y^z as x^(y^z).

Advanced Uses

The ^ operator can be used as an alternative to an "xth root" operator, which the 68k calculators don't have. If you want to take the Nth root of a number, raise it to the 1/N-th power instead.


The ^ operator is also useful for square matrices. Raising a square matrix to an integer power between -32768 and 32767 just multiples the matrix by itself, taking the inverse first for negative matrices. A matrix to the 0th power is the identity.

For raising a matrix to a fractional power, or raising a number to a matrix power, a different definition is used: see Matrices and Their Commands. This definition is in fact compatible with the repeated-multiplication method, except that it is far more general.

None of these situations are equivalent to applying ^ to every element of a matrix. For that, see the .^ command.

Error Conditions

230 - Dimension happens when non-square matrices are used with ^.

230 - Domain error happens when a matrix is raised to an integer power not in the range -32768..32767.

665 - Matrix not diagonalizable happens when diagonalization (used to compute most uses of ^ with matrices) fails.

800 - Non-real result happens when there is no real result to return, and the calculator is in real number mode.

890 - Singular matrix happens when raising a matrix with no inverse to a negative power.

Related Commands

  • * (multiply)
  • / (divide)

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:power


The | Command

with.png

Command Summary

Substitutes a value for a variable temporarily.

Command Syntax

expression

Menu Location

Press the

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The | operator (which nobody seems to know how to pronounce, although TI suggests "with") temporarily sets a variable to some value, just for a single evaluation. For example:

:x^2+2x+1|x=5
           6

Using the | operator doesn't actually affect the value of the variable. However, it will work both if the variable is undefined, and if the variable already has a different value.

Only one | can occur in a single expression: if you have more, this will either cause an error or ignore all but the first substitution, depending on placement. However, one | is enough for any number of variables: just separate the values to use with and:

:x+y|x=2 and y=2
           4

Advanced Uses

The | operator has a more complicated use: rather than giving a specific value for a variable, you might give a condition (or several conditions) for its value, using the >, , <, and operators. This condition will be used if it helps simplify the expression, especially with solve(). For instance:

:abs(x)|x<0
           -x

Weird things can happen if you do this to a variable whose value is already defined, however:

:5→x
           5
:abs(x)|x<0
           |undef|

Optimization

If a complicated expression has a repeating element, you may be able to make the calculation smaller and faster by replacing this repeating element with a variable, for which you substitute the correct value. For example (here the repeating element is √(1-x^2)):

:x√(1-x^2)+tanֿ¹(x/√(1-x^2))

can be

:x*a+tanֿ¹(x/a)|a=√(1-x^2)

A related trick is to make a substitution with a function, for an operation that has to be done several times in a single line. For example:
:a*(a-1)/2+b*(b-1)/2+c*(c-1)/2

can be

:f(a)+f(b)+f(c)|f(x)=x*(x-1)/2

Error Conditions

200 - Constraint expression invalid happens when the condition doesn't make sense to the calculator.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:with


The © Command

comment.png

Command Summary

Marks the rest of the line (in a program) as a comment.

Command Syntax

:line of code © comment

Menu Location

Starting in the program editor:

  • Press F2 to enter the I/O menu.
  • Press 9 to select ©.

Calculator Compatibility

This command works on all calculators.

Token Size

4 bytes (+ length of comment)

The © character is used for adding comments in a program: everything after © is ignored by the calculator for the purposes of actually running the program, so it's a good way to make a note to yourself about what a part of your code does. This is especially helpful if you're going to be reading the program later when you don't quite remember what you were doing.

:If ok=0 © If the user pressed ESC
: Stop

There are other situations you might use comments in. For instance, you might make a rough sketch of your program and add comments about the code that has yet to be filled in:

:If key=264 Then
: © add a confirmation dialog here later
: Exit
:EndIf

Yet another use of © is to "comment out" lines of code that you might need later, but want to ignore for now — this is better than deleting the code, since you don't have to rewrite it later.

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:comment


The ° Command

degree.png

Command Summary

Converts an angle to degrees, if necessary.

Command Syntax

angle°

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press 2 to enter the Angle submenu.
  • Press 1 to select °.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

The ° symbol used after an angle makes sure the angle is interpreted as being in degrees. If the calculator is already in degree mode, x° is equal to x; in radian mode, x° is equal to π*x/180; and in gradian mode, x° is equal to 10*x/9.

If you're using degree measure extensively in a program, it's a better idea to use setMode() to switch to degree mode and not worry about this. However, there are two reasons you might want to use °:

  • If you need an angle in degrees only once or twice, don't bother changing the mode setting.
  • In a function, you're forced to use °, since setMode() isn't valid in a function.

In radian mode:

:sin(30)
           sin(30)
:sin(30°)
           1/2
:180°
           π

In degree mode (no conversion is necessary, so no conversion is done):

:sin(30)
           1/2
:sin(30°)
           1/2
:180°
           180

Another possible use of ° is to write an angle in degrees, minutes, and seconds as x°y'z" (using the usual apostrophe and quote symbols) — this stands for x degrees, y minutes (equal to 1/60th of a degree) and z seconds (equal to 1/60th of a minute). There's no "degree/minute/second" mode setting, so an angle entered in this form will always be simplified: first to (x+y/60+z/3600)2 degrees, and then (if necessary) converted to the correct angle measure. However, you can use ▶DMS to express output in this form.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:degree


The ×√ Command
XROOT.GIF

Command Summary

Takes the xth root of an input.

Command Syntax

A xB

Menu Location

While editing a program, press:

  1. MATH to open the math menu
  2. 5 or use the arrow keys to select

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

This command takes the xth root of a number. If used on a list, it will return a list with the xth root of each element. Also valid are the forms list×x and list1×list2.

:2×√4
        2
:5×√2
        1.148698355

:3×√{1,‾8,27}
        {1 ‾2 3}

:{3,2}×√{8,9}
        {2 3}

Real mode:
:4×√‾1
    <returns error>

a+bi mode:
:4×√‾1
        .7071067812+.7071067812i

See the notes on the ^ command for an explanation on how ×√ behaves depending on whether its input is real or complex.

Optimization

If you want to take the second or third root of a number, use √( or ³√( instead.

:2×√X
can be
:√(X

Error Conditions

  • ERR:NONREAL ANS if you try to take an even root of a negative number or list element in Real mode.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/xroot


The ‾ Command
NEGATIVE.GIF

Command Summary

Returns the negative value of a number.

Command Syntax

value

Menu Location

Press [(-)]

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The ‾ (negative) operator takes one number, variable, or expression and negates its value, thus returning the negative equivalent of it. The ‾ operator appears higher in the order of operations than both the relational and logical operators, so it will be executed first. In addition, it has the same order of operation as the other math operators, so the calculator simply executes them left to right in the order that they appear.

:‾1
           -1

:5→X
:‾3(X+2
           -21

:‾2→A:‾3→B
:AB
           6

Optimization

When adding a negative number to a positive number, switch the two numbers around and change the addition to subtraction. This allows you to get rid of the ‾ sign and save a byte.

:‾A+B→C
can be
:B-A→C

This is not always the case, however: if you subtract a command that uses a lot of parentheses and is followed by a newline/colon/STO→ arrow, it'd save space to put the subtraction at the beginning of the line. For instance:
:inString(Ans,sub(Str1,1,1+int(log(A))))-1
can be
:‾1+inString(Ans,sub(Str1,1,1+int(log(A

Error Conditions

If an ERR:SYNTAX is being thrown near a subtraction or negation where there should be no errors, check to make sure that ‾ (negation) and - (subtraction) were not swapped by mistake.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/negative


The ‾ Command

negative.png

Command Summary

Negates an expression.

Command Syntax

expression

Menu Location

Press the ‾ key to enter ‾.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The ‾ operator gives the negative of the value immediately following it. It's not to be confused with the - operator, which subtracts two numbers — while on paper you'd generally use the same symbol for -2 and 4-2, the calculator has two different symbols, and negation is represented by the slightly shorter and higher dash.

You can also use ‾ to negate lists and matrices, which will negate each element, as expected.

:1+‾1
           0
:‾(x-1)
           ‾x+1
:‾[1,2;3,4]
           [‾1  ‾2]
           [‾3  ‾4]

Other pages on this site will use - to mean both subtraction and negation, where it isn't confusing.

Related Commands

  • + (add)
  • - (subtract)

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:negative


The → Command
STORE.GIF

Command Summary

Stores a value to a variable.

Command Syntax

ValueVariable

Menu Location

Press [STO►]

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The → (store) command will store a number, variable, or expression to a variable, using the respective value(s) of the variable(s) at the time. When storing a value in a variable, you have the value on the left side of → and the variable that it will be stored to on the right side.

:1→X
           1

:{1.3,5.7,9.11→ABC
           {1.3 5.7 9.11}

:"HELLO WORLD→Str1
           "HELLO WORLD"

Advanced

It's not easy to put a → symbol into a string, since "→→Str1 would produce a syntax error (and in general, when the calculator 'sees' a → symbol, it assumes that the string is over, and interprets the symbol literally).

However, you can use Equ►String( (outside a program) to get the → or " symbols in a string:

  1. Type them on the home screen and press [ENTER]
  2. Select 1:Quit when the ERR:SYNTAX comes up.
  3. Press [Y=] to go to the equation editor.
  4. Press [2nd] [ENTRY] to recall the symbols to Y1
  5. Now, use Equ►String(Y1,Str1) to store the symbols to a string.

Optimization

You can remove closing parentheses, braces, brackets, and quotes that are before a → command.

Here are a series of examples of using the → command. The first line of each example uses more bytes than necessary. The line following strips out the unnecessary characters and uses less bytes.

Real Variables

1/(2*(3/4))→X
1/(2(3/4→X

Strings

"Hello"→Str1
"Hello→Str1

Lists

{1,2,3,2(X+1)}→L₁
{1,2,3,2(X+1→L₁
5→L₁(1)
5→L₁(1
{4,5,6}→∟LISTX
{4,5,6→LISTX

Tip: You can remove the character when storing an entire list to a custom named list, but you must keep the character present when storing to a specific item, such as 3→∟LISTX(1

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/store


The → Command

Command Summary

Stores a value to a variable.

Command Syntax

valuevariable

Menu Location

Press the STO> key to insert →.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The operator assigns a value to a variable.

Initially, a variable such as 'x', 'lastname', or 'cube' is undefined. When used in an expression, they will be treated as unknowns: 3*x-x may be simplified to 2*x, but will otherwise be left alone.

Once a value is assigned to a variable, that value will be substituted for the variable every time you use it. For example, you might store 5→x. Now, if you write 3*x-x, the answer won't be 2*x, but 10.

Any kind of value — a simple number, an expression, a string, list, or matrix, or even a function can be stored to a variable with →. The following are all valid:

:5→x
           5
:"Alighieri"→lastname
           "Alighieri"
:n^3→cube(n)
           Done

As a special case, you can even store to a single element of a list or matrix. For example:

:{1,2,3,4,5}→list
           {1  2  3  4  5}
:99→list[3]
           99
:list
           {1  2  99  4  5}

Advanced Uses

Using the # (indirection) operator, you can store a value to a variable given its name, in a string.

Optimization

There are alternatives to such as Define or CopyVar; they have their uses in special situations, but is better (smaller and easier to understand) in other cases.

Error Conditions

190 - Circular definition happens when an undefined variable is given a value in terms of itself (e.g. x+1→x).

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:store


The ∏() Command

product-pi.png

Command Summary

Multiplies together the evaluations of an expression with one variable taking on a range of values.

Command Syntax

∏(expression, variable, start, end)

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press B to enter the Calculus submenu.
  • Press 5 to select ∏(.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

∏() is used to multiply a sequence of numbers. ∏(expression, variable, start, end) will evaluate expression for variable=start, then for variable=start+1, all the way through variable=end, and multiply the results:

:∏(f(x),x,1,5)
           f(1)*f(2)*f(3)*f(4)*f(5)
:∏(x,x,1,5)
           120

In this way, ∏() is no different from taking product() of a sequence generated by seq(). However, ∏() can be used for more abstract calculations — for instance, when start or end is an undefined variable, it will try to find the product in terms of that variable. ∏() can also be used to find the product of an infinite series (just make the value of end infinity — ∞).

:∏(x,x,1,n)
           n!
:∏(1-1/x,x,2,n)
           1/n

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:product-pi


The ∑() Command

sum-sigma.png

Command Summary

Adds together the evaluations of an expression with one variable taking on a range of values.

Command Syntax

∑(expression, variable, start, end)

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press B to enter the Calculus submenu.
  • Press 4 to select ∑(.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

∑() is used to add a sequence of numbers. ∑(expression, variable, start, end) will evaluate expression for variable=start, then for variable=start+1, all the way through variable=end, and add up the results:

:∑(f(x),x,1,5)
           f(1)+f(2)+f(3)+f(4)+f(5)
:∑(x^2,x,1,5)
           55

In this way, ∑() is no different from taking sum() of a sequence generated by seq(). However, ∑() can be used for more abstract calculations — for instance, when start or end is an undefined variable, it will try to find the sum in terms of that variable. ∑() can also be used to sum an infinite series (just make the value of end infinity — ∞).

:∑(x^2,x,1,n)
           n*(n+1)*(2*n+1)/6           
:∑(2^-x,x,1,∞)
           1

Optimization

It's a good idea to replace sum(seq( by ∑( whenever it occurs. The only difficulty arises if seq() uses its step argument, since ∑() doesn't have one. There are three options:

  • Forget about using ∑() and just go with the sum(seq( alternative.
  • Use a when() expression (probably with mod()) to select the entries you care about.
  • Use a linear equation to transform values from 1 to N into the correct values with the step.

Here is an example of these approaches:

:sum(seq(x^2,x,1,9,2))

This calculates 12+32+52+72+92.
:∑(when(mod(x,2)=1,x^2,0),x,1,9)

The when() command selects only the odd numbers — those with mod(x,2)=1 — from 1 to 9.
:∑((2x-1)^2,x,1,5)

The equation 2*x-1 transforms the numbers 1..5 into the odd numbers 1..9.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:sum-sigma


The √() Command

square-root.png

Command Summary

Takes the square root of a number.

Command Syntax

√(number)

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The √() command takes the square root of a value: √(x) is a number that, when multiplied by itself, gives x. It's a special case of the ^ and root() commands: √(x) = x^(1/2) = root(x,2).

Unless the calculator is in approximate mode, or you force it to approximate (by pressing ♦+ENTER, or using approx()), it won't try to evaluate all square roots: it will take the square root of perfect squares, otherwise, it will just take out all the square factors (for instance, √(20) is simplified to 2√(5)).

For positive numbers, √() will return the positive square root; more generally, if the result is complex (and if the calculator is in complex number mode), the result of √() will be the one with non-negative real part.

:√(16)
           4
:√(-12)
           2*√(3)*i

If the square root of a list is taken, it will take the square root of every element of the list.

Advanced Uses

The √() of a matrix is not (in general) the same as taking the square root of every element of the matrix. A different definition is used to compute the result; see Matrices and Their Commands. It requires the matrix to be square and diagonalizable in order to apply.

Error Conditions

230 - Dimension happens when taking the square root of a non-square matrix.

665 - Matrix not diagonalizable happens when diagonalization (used to take square roots of matrices) fails.

800 - Non-real result happens when taking the square root of a negative or complex number, in real number mode.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:square-root


The √( Command
SQUAREROOT.PNG

Command Summary

Take the square root of a number.

Command Syntax

√(input)

Menu Location

Press 2nd √ to paste the √( command.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

Takes the square root of a positive or negative number. It works exactly the same as 2×√ or ^(1/2) but is smaller and uses an ending parenthesis. If used on a list, it will return a list with the square root of each element.

√(4)
        2
√(2)
        1.414213562

√({1,-1})
        {1 i}

This may return a complex number or throw ERR:NONREAL ANS (depending on mode settings) if taking the square root of a negative number.

Optimization

Never raise something to the one-half power explicitly; use this command instead.

:X^(1/2)→X
can be
:√(X→X

Error Conditions

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/square-root


The ∟ Command
L.GIF

Command Summary

Indicates the beginning of a custom list.

Command Syntax

LISTNAME

Menu Location

While editing a program, press:

  1. 2nd LIST to access the List menu
  2. RIGHT to access the OPS submenu
  3. 2nd B to select ∟, or use arrows

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The ∟ character is used at the start of the name of any custom list you create, for example:

{1,2,3}→∟HELLO
{4,5,6}→∟WORLD

In most cases you need to include this when accessing or manipulating a custom list (although there's a few exceptions, see the Optimization section below). You do not need this character when accessing the the default lists L₁L₆).

The maximum length of the list name (not including the ) is five letters. ∟ABCDE works, but ∟ABCDEF does not. List names must start with a letter A-Z but can also include numbers so ∟LIST1 and ∟LIST2 are valid list names, but ∟123 is not.

There are two ways to insert this character:

  1. Press 2nd, LIST, press right arrow to access the OPS menu, scroll to the bottom, and press ENTER to insert the character. You can then type the rest of the name of your list.
  2. If your custom list already exists, you can press 2nd, LIST, select the name of your list, and press ENTER. The whole name including the character will be inserted.

Optimization

You don't actually need to include the ∟ command when storing (→) to a list.

{1,2,3}→HELLO
{4,5,6}→WORLD
{7,8,9}→X

Although the name X as used above also matches the name of a regular real variable, since the data being stored is a list, it will be saved to ∟X.

When storing to a specific list item, you MUST still include the character:

1→∟HELLO(1)
2→∟WORLD(2)
3→∟X(3)

Some of the list commands also allow for leaving off the character, such as SetUpEditor. However, be careful when doing so with Input and Prompt because you might only be asking the user to input a list, but if a real value is entered, it would be saved to a real variable instead.

Error Conditions

  • ERR:SYNTAX is thrown if you try to reference/create a list with more than 5 characters in its name.
  • ERR:UNDEFINED is thrown if you try to use ∟ on an undefined list.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/l


The ∠ Command

angle-symbol.png

Command Summary

Used in entering a vector in polar, cylindrical, or spherical format, or a complex number in polar form.

Command Syntax

[r,∠θ]
[r,∠θ,z]
[r,∠θ,∠φ]
(rθ)

Menu Location

  • Press 2nd MATH to enter the MATH menu.
  • Press 2 to enter the Angle submenu.
  • Press 7 to select ∠.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The ∠ operator is used for alternate forms of entering vectors or complex numbers. It will be used for output depending on the Complex Format and Vector Format mode settings, but you can always use it in an expression.

For vectors (which are just 1x2 or 1x3 matrices, as far as ∠ is concerned):

  • [r,∠θ] is equivalent to [r*cos(θ),r*sin(θ)]
  • [r,∠θ,z] is equivalent to [r*cos(θ),r*sin(θ),z]
  • [r,∠θ,∠φ] is equivalent to [r*cos(θ)*sin(φ),r*sin(θ)*sin(φ),r*cos(φ)]

These have to be row vectors — you can't use column vectors with ∠.

For complex numbers, (r∠θ) is equivalent to r*(cos(θ)+i*sin(θ)). You have to have the parentheses there, and both r and θ must be real numbers or expressions.

Error Conditions

260 - Domain error happens when complex numbers are used in the vector notation.

580 - Invalid polar complex happens when the values of r and θ in the complex number notation are invalid.

640 - Invalid vector syntax happens when the ∠ mark is misplaced in the vector notation.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:angle-symbol


The ∫() Command

integral.png

Command Summary

Takes the integral of an expression.

Command Syntax

∫(expression,variable)
∫(expression,variable,constant)
∫(expression,variable,lower,upper)

Menu Location

Press [2nd][7] to enter ∫(.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

∫(expression,variable) takes the integral of expression (symbolically) with respect to variable. All other variables are treated as constant.

There are three ways to use ∫(). The syntax above returns an indefinite integral. ∫(expression,variable,c) does the same, but with a constant of integration, c (this will just get added on to the result). Finally, ∫(expression,variable,a,b) takes a definite integral from a to b. These limits can be anything, including undefined variables, ∞ and -∞, as long as they don't depend on variable.

:∫(x^2,x)
           x^3/3
:∫(x^2,x,c)
           x^3/3+c
:∫(x^2,x,a,b)
           b^3/3-a^3/3

Indefinite integrals are always computed exactly or not at all: if a part of the expression (or the entire expression) can't be integrated, the result will stay in terms of ∫(). However, definite integrals will sometimes be approximated, depending on the Exact/Approx mode setting:

  • If EXACT, integrals will never be approximated.
  • If AUTO, the calculator will approximate integrals like ∫(e^(-x^2),x,-1,1) that it can't compute exactly.
  • If APPROX, all definite integrals will be done numerically if possible.
:∫(e^(-x^2),x)
           ∫(e^(-x^2),x)
:∫(e^(-x^2),x,-1,1)
           2*∫(e^(-x^2),x,0,1) (in EXACT mode)
           1.49365 (in AUTO or APPROX mode)

Finally, you can take multiple integrals by applying ∫() to the result of another ∫() (any number of times). The integration limits of the inner integrals can involve the variables of the outer integrals.

:∫(∫(x*y,x),y)
           y^2*x^2/4
:∫(∫(x*y,x,0,y),y,0,1)
           1/8

If the expression is a list or matrix, ∫() takes the integral of each element.

Error Conditions

140 - Argument must be a variable name happens when the variable of integration isn't a variable.

220 - Dependent limit happens when the integration limits depend on the variable of integration.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:integral


The ≠ Command
NOTEQUAL.PNG

Command Summary

Returns true if value1 is not equal to value2.

Command Syntax

value1value2

Menu Location

Press:

  1. 2nd TEST to access the test menu.
  2. 2 to select ≠, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The ≠ (not equal) operator takes two numbers, variables, or expressions, and tests to see if they are not equal to each other. It will return 1 if they are not, and 0 if they are. When determining the order of operations, ≠ will be executed after the math operators, but it will be executed before the logical operators and in the order that it appears from left to right with the other relational operators.

1≠0
           1
0→X
           0
3→Y
           3
X≠Y
           1

Advanced Uses

Just like the other relational operators, ≠ can take real numbers and lists for variables. In order to compare the lists, however, both must have the same dimensions; if they don't, the calculator will throw a ERR:DIM MISMATCH error. When comparing a real number to a list, the calculator will actually compare the number against each element in the list and return a list of 1s and 0s accordingly.

:{2,4,6,8}≠{1,3,5,7
           {1 1 1 1}
:5≠{1,2,3,4,5
           {1 1 1 1 0}

Besides real numbers and lists, ≠ also allows you compare strings, matrices, and complex numbers. However, the variables must be of the same type, otherwise the calculator will throw a ERR:DATA TYPE error; and just like with lists, both matrices must have the same dimensions, otherwise you will get a ERR:DIM MISMATCH error.

:[[1,2,3]]≠[[1,2,3
           0
:"HELLO"≠"WORLD
           1
:(3+4i)≠(5-2i)    (the parentheses are added for clarity)
           1

Optimization

Don't compare a variable's value to zero in a conditional expression, because the calculator treats nonzero values as true and zero as false. Instead, just write the variable by itself:

:If C≠0
can be
:If C

Error Conditions

  • ERR:DATA TYPE is thrown if you try to compare two different kinds of variables, such as a string and number or a list and matrix.
  • ERR:DIM MISMATCH is thrown if you try to compare two lists or matrices that have different dimensions.

Related Commands

  • = (equal)
  • > (greater than)
  • (greater than equal)
  • < (less than)
  • (less than equal)

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/notequal


The ≠ Command

notequal.png

Command Summary

Tests if two values are different.

Command Syntax

value1value 2

Menu Location

Press [♦][=] key to enter ≠.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The ≠ operator compares two values, returning true if they're different, and false if they're equal. It is a basic building block of the conditions used by commands such as If, when(), and While. The results of ≠ and the other relational operators (=, >, , <, and ) can be combined with the and, or, xor, and not operators to create more complicated conditions.

It returns a single value for most types of data, and returns true if the two sides are mismatched in type: comparing a single number to a list, for instance, or comparing two lists that are of a different size. The only exception is when comparing two lists or two matrices of the same size: in that case, it compares them element-by-element, and returns a list or matrix of true/false values.

:2+2≠4
           false
:2+2≠5
           true
:{1,2,3}≠{1,4,3}
           {false  true  false}

If either side or both contains undefined variables, ≠ will wait to return a value unless it's something clearly true or false for any value of the variable (for instance, x≠x). You can do math with the resulting inequality: if an operation makes sense, it will be applied to both sides: for instance, if x≠y, then you can negate it to get -x≠-y. An operation will not be applied to both sides if it wouldn't be consistent with the previous inequality: for example, you can't square both sides, since if x≠y it can still be the case that x^2=y^2. You can also extract the two halves of the inequality with left() and right().

Related Commands

  • = (equal)
  • > (greater than)
  • (greater than or equal)
  • < (less than)
  • (less than or equal)

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:not-equal


The ≤ Command
LESSTHANEQUAL.PNG

Command Summary

Returns true if value1 is less than or equal to value2.

Command Syntax

value1value2

Menu Location

Press:

  1. 2nd TEST to access the test menu.
  2. 6 to select ≤, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The ≤ (less than equal) operator takes two numbers, variables, or expressions, and tests to see if the first one has a value less than or equal to the second one. It will return 1 if it is less than or equal to, and 0 if it is not. When determining the order of operations, ≤ will be executed after the math operators, but it will be executed before the logical operators and in the order that it appears from left to right with the other relational operators.

:1≤0
           0

:DelVar X3→Y
:X≤Y
           1

Advanced Uses

Just like the other relational operators, ≤ can take real numbers and lists for variables. In order to compare the lists, however, both must have the same dimensions; if they don't, the calculator will throw a ERR:DIM MISMATCH error. When comparing a real number to a list, the calculator will actually compare the number against each element in the list and return a list of 1s and 0s accordingly.

:{2,4,6,8}≤{1,3,5,7
           {0 0 0 0}
:5≤{1,2,3,4,5
           {0 0 0 0 1}

Unfortunately, ≤ does not work with strings, matrices, or complex numbers (only = and do), and the calculator will actually throw a ERR:DATA TYPE error if you try to compare them. In the case of strings, however, it should be pretty obvious why: a string represents a sequence of characters, and does not associate a value to any character, so there is nothing to compare.

Error Conditions

  • ERR:DATA TYPE is thrown if you try to compare strings, matrices, or complex numbers.
  • ERR:DIM MISMATCH is thrown if you try to compare two lists that have different dimensions.

Related Commands

  • = (equal)
  • (not equal)
  • > (greater than)
  • (greater than equal)
  • < (less than)

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/lessthanequal


The ≤ Command

lessthanequal.png

Command Summary

Tests if one value is smaller than or equal to another.

Command Syntax

value1value 2

Menu Location

Press [♦][<] to enter ≤.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The ≤ operator compares two values, returning true if the right side is greater or if the two are equal, and false otherwise. It is a basic building block of the conditions used by commands such as If, when(), and While. The results of ≤ and the other relational operators (=, , >, , and <) can be combined with the and, or, xor, and not operators to create more complicated conditions.

It returns a single value for most types of data, and returns false if the two sides are mismatched in type: comparing a single number to a list, for instance, or comparing two lists that are of a different size. The only exception is when comparing two lists or two matrices of the same size: in that case, it compares them element-by-element, and returns a list or matrix of true/false values.

:3≤4
           true
:3≤2
           false
:{1,2,3}≤{3,2,1}
           {true  true  false}

If either side or both contains undefined variables, ≤ will wait to return a value. You can do math with the resulting inequality, and if an operation makes sense, it will be applied to both sides: for instance, if x≤y, then you can negate it to get -x≥-y. An operation will not be applied to both sides if it wouldn't be consistent with the previous inequality: for example, you can't square both sides, since even if x≤y the comparison between x^2 and y^2 could go in any order. You can also extract the two halves of the inequality with left() and right().

Advanced Uses

The ≤ operator can also compare strings. It does so by comparing the character codes of each character, and orders the strings by the first difference it finds. This ideally means that the strings are ordered by dictionary order: for example, "aardvark"≤"apple", since it would come later in the dictionary.

However, the problem is that all uppercase letters have a smaller character code than lowercase letters, so this only holds true if the strings are the same case. Otherwise, strange results can happen: for instance, "Apple"≤"aardvark", since "A" comes before "a".

Related Commands

  • = (equal)
  • (not equal)
  • > (greater than)
  • (greater than or equal)
  • < (less than)

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:less-than-or-equal


The ≥ Command
GREATERTHANEQUAL.PNG

Command Summary

Returns true if value1 is greater than or equal to value2.

Command Syntax

value1value2

Menu Location

Press:

  1. 2nd TEST to access the test menu.
  2. 4 to select ≥, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The (greater than equal) operator takes two numbers, variables, or expressions, and tests to see if the first one has a value greater than or equal to the second one. It will return 1 if it is greater than or equal to, and 0 if it is not. When determining the order of operations, will be executed after the math operators, but it will be executed before the logical operators and in the order that it appears from left to right with the other relational operators.

:1≥0
           1

:DelVar X3→Y
:X≥Y
           0

Advanced Uses

Just like the other relational operators, can take real numbers and lists for variables. In order to compare the lists, however, both must have the same dimensions; if they don't, the calculator will throw a ERR:DIM MISMATCH error. When comparing a real number to a list, the calculator will actually compare the number against each element in the list and return a list of 1s and 0s accordingly.

:{2,4,6,8}≥{1,3,5,7
           {1 1 1 1}
:5≥{1,2,3,4,5
           {1 1 1 1 1}

Unfortunately, does not work with strings, matrices, or complex numbers (only = and do), and the calculator will actually throw a ERR:DATA TYPE error if you try to compare them. In the case of strings, however, it should be pretty obvious why: a string represents a sequence of characters, and does not associate a value to any character, so there is nothing to compare.

Error Conditions

  • ERR:DATA TYPE is thrown if you try to compare strings, matrices, or complex numbers.
  • ERR:DIM MISMATCH is thrown if you try to compare two lists that have different dimensions.

Related Commands

  • = (equal)
  • (not equal)
  • > (greater than)
  • < (less than)
  • (less than equal)

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/greaterthanequal


The ≥ Command

greaterthanequal.png

Command Summary

Tests if one value is larger than or equal to another.

Command Syntax

value1value 2

Menu Location

Press [♦][>] to enter ≥.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The ≥ operator compares two values, returning true if the left side is greater or if the two are equal, and false otherwise. It is a basic building block of the conditions used by commands such as If, when(), and While. The results of ≥ and the other relational operators (=, , >, <, and ) can be combined with the and, or, xor, and not operators to create more complicated conditions.

It returns a single value for most types of data, and returns false if the two sides are mismatched in type: comparing a single number to a list, for instance, or comparing two lists that are of a different size. The only exception is when comparing two lists or two matrices of the same size: in that case, it compares them element-by-element, and returns a list or matrix of true/false values.

:3≥4
           false
:3≥2
           true
:{1,2,3}≥{3,2,1}
           {false  true  true}

If either side or both contains undefined variables, ≥ will wait to return a value. You can do math with the resulting inequality, and if an operation makes sense, it will be applied to both sides: for instance, if x≥y, then you can negate it to get -x≤-y. An operation will not be applied to both sides if it wouldn't be consistent with the previous inequality: for example, you can't square both sides, since even if x≥y the comparison between x^2 and y^2 could go in any order. You can also extract the two halves of the inequality with left() and right().

Advanced Uses

The ≥ operator can also compare strings. It does so by comparing the character codes of each character, and orders the strings by the first difference it finds. This ideally means that the strings are ordered by dictionary order: for example, "apple"≥"aardvark", since it would come later in the dictionary.

However, the problem is that all uppercase letters have a smaller character code than lowercase letters, so this only holds true if the strings are the same case. Otherwise, strange results can happen: for instance, "aardvark"≥"Apple", since "a" comes after "A".

Related Commands

  • = (equal)
  • (not equal)
  • > (greater than)
  • < (less than)
  • (less than or equal)

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:greater-than-or-equal


The ▶ Command

convert.png

Command Summary

Converts an expression from one unit to another.

Command Syntax

expressionunits

Menu Location

Press [2nd][▶] to enter ▶: this is

  • [2nd][MODE] on a TI-89 or TI-89 Titanium
  • [2nd][Y] on a TI-92, TI-92 Plus, or Voyage 200

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

The ▶ operator converts an expression to a different unit. Usually, this refers to the built-in units (such as _m (meters), _mph (miles per hour, etc.) which you can select from the UNITS menu.

To use it, you must first have the expression on the left in terms of some unit — this is done by multiplying it by that unit. For instance, "5 meters" is written as 5_m or 5*_m (where _m is the unit). You can combine units as well: for instance, 5_m^2 (5 square meters) or 30_km/_hr (30 kilometers per hour).

To convert that into a different unit, type ▶ and then a different unit to convert to (again, you can combine units). For instance, to convert 5 square meters to acres, type 5_m^2▶_acre. (Note: the result will always be expressed as a decimal)

:30_km/_hr▶_m/_s
           8.33333*_m/_s
:5_N▶_dyne
           500000.*_dyne

You can't use ▶ to convert between units of temperature (degrees Celsius to degrees Fahrenheit, for instance), since the calculator isn't sure if you mean absolute temperature or a change in temperature instead. Use the tmpCnv() and ΔtmpCnv() commands instead.

Advanced Uses

It's possible to define your own units as well: units are just any variable beginning with an underscore, and ▶ will perform just as well converting between those. There are two ways to go about it. The first is to define your units in terms of existing ones: for instance, you might define a furlong (one-eighth of a mile) as follows:

:1/8_mi→_furlong
           1/8*_mi
:110_yd▶_furlong
           .5*_furlong

The second method is to start with a unit or several units to keep undefined (for instance, _x). You can then define other units in terms of _x, and convert between them:
:5_x→_y
           5*_x
:3_y▶_x
           15.*_x
:10_x/_s▶_y/_s
           2.*_y/_s

Units are treated just like variables, except that they're universal across folders: you can have only one instance of _x, and you can access it as _x no matter which folder you're in. You can use this if you want to define a universal variable to access in any folder: for instance, if you define a program as _prgm(), you can run it with _prgm() from any folder.

Error Conditions

345 - Inconsistent units happens when converting between two units that measure different types of quantities (for instance, converting length to time).

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:convert


The ° (Degree Symbol) Command
DEGREE%20(SYMBOL).GIF

Command Summary

If the calculator is in radian mode, the ° (degree) symbol converts an angle to radians.

Command Syntax

angle°

Menu Location

Press:

  1. [2nd]
  2. [Angle]
  3. [Enter] or [1]

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

Normally, when the calculator is in radian mode, the trigonometric functions only return values calculated in radians. With the ° symbol you can have the angle evaluated as if in degree mode because it converts the angle into radians.

You can insert the degree symbol by pressing [2ND] [ANGLE] [ENTER].

One full rotation around a circle is 2π radians, which is equal to 360°. To convert an angle in radians to degrees you multiply by 180/π, and to convert from degrees to radians multiply by π/180.

In radian mode:

sin(45)        \\ actually calculating sin(2578.31)
    .8509035245
sin(45°)
    .7071067812

In degree mode:

sin(45)
    .7071067812
sin(45°)
    .7071067812    \\ There's no difference when in degrees

Converting Degrees, Minutes & Seconds

The degree symbol also allows you to convert degrees, minutes and seconds into decimal degrees. For example:

90°30'
       90.5
90°30'09"
       90.5025

The minute symbol is inserted by pressing [2ND] [ANGLE] [2]. The seconds symbol is inserted via [ALPHA] [+].

To convert back the other way (decimal to degrees-minutes-seconds) use the ►DMS command, accessed via [2ND] [ANGLE] [4]:

90.5025►DMS
       90°30'09"

Optimization

When you only call the trig function once in a program and want it calculated in degrees, instead of changing the mode you can just use ° to save one-byte (the newline from using the command Degree)

:Degree
:sin(X)
can be
:sin(X°)

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/degree-symbol


The 0b Command

0b.png

Command Summary

Indicates that a number is written in binary.

Command Syntax

0bdigits

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

The calculator can work with numbers written in three bases: decimal (the usual), binary, and hexadecimal. The 0b command indicates that a number is written in binary:

:0b101
           5
:0b100000
           32

When written in binary, numbers are expressed as signed 32-bit integers, which means that only the integers between -231 and 231-1 can be expressed in binary. With other binary-related commands, numbers are simply truncated to fit in this range. Not so with 0b: if you enter more than 32 binary digits after the 0b, the result is a domain error.

Even if the calculator is in binary mode, you still have to write 0b for an integer to be interpreted as binary: binary mode only affects output. If the calculator is in decimal mode, which is the default, you have to use ▶Bin to get output in binary.

Error Conditions

260 - Domain error happens when 0b is used with more than 32 binary digits after it.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:0b


The 0h Command

0h.png

Command Summary

Indicates that a number is written in hexadecimal.

Command Syntax

0hdigits

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

The calculator can work with numbers written in three bases: decimal (the usual), binary, and hexadecimal. The 0h command indicates that a number is written in hexadecimal:

:0h10
           16
:0h2F6
           758

When written in hexadecimal, numbers are expressed as signed 32-bit integers (32 bits correspond to 8 hexadecimal digits), which means that only the integers between -231 and 231-1 can be expressed in hexadecimal. With other hexadecimal-related commands, numbers are simply truncated to fit in this range. Not so with 0h: if you enter more than 8 hexadecimal digits after the 0b, the result is a domain error.

Even if the calculator is in hexadecimal mode, you still have to write 0h for an integer to be interpreted as hexadecimal: the mode setting only affects output. If the calculator is in decimal mode, which is the default, you have to use ▶Hex to get output in hexadecimal.

Error Conditions

260 - Domain error happens when 0h is used with more than 8 hexadecimal digits after it.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:0h


The 10^( Command
TENPOWER.PNG

Command Summary

Raises 10 to a power.

Command Syntax

10^(value)

Menu Location

Press [2nd] [10x] to paste 10^(.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The 10^( command raises 10 to a power. Since it's possible to just type out 1, 0, ^, and (, the reason for having a separate function isn't immediately obvious, but the command is occasionally useful.

10^( accepts numbers and lists as arguments. It also works for complex numbers.

10^(2)
     100
10^({-1,0,1})
     {0.1 1 10}

Optimization

Don't type 10^( out, use this command instead. It's three bytes smaller and usually faster as well. However, keep in mind that you might be able to use the E command instead of 10^(, for constant values.

Command Timings

The command 10^( is faster than typing out 10^( in most cases, except for small integer arguments. Even faster is E, but that only works for raising 10 to a constant power.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/ten-exponent


The ֿ¹ Command
INVERSE.GIF

Command Summary

Returns the reciprocal of a number (1 divided by the number). For matrices, finds the matrix inverse.

Command Syntax

valueֿ¹

Menu Location

Press [xֿ¹]

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The ֿ¹ command returns the reciprocal of a number, equivalent to dividing 1 by the number (although reciprocals are sometimes more convenient to type). It also works for lists, by calculating the reciprocal of each element.

The ֿ¹ command can also be used on matrices, but it is the matrix inverse that is computed, not the reciprocal of each element. If [A] is an N by N (square) matrix, then [A]ֿ¹ is the N by N matrix such that [A][A]ֿ¹=[A]ֿ¹[A] is the identity matrix. ֿ¹ does not work on non-square matrices.

4ֿ¹
        .25
{1,2,3}ֿ¹
        {1 .5 .3333333333}
[[3,2][4,3]]ֿ¹
        [[3  -2]
         [-4 3 ]]

Much like the number 0 does not have a reciprocal, some square matrices do not have inverses (they are called singular matrices) and you'll get an error when you try to invert them.

Optimization

Writing Aֿ¹B instead of B/A is sometimes beneficial when B is a complicated expression, because it allows you to take off closing parentheses of B. For example:

:(P+√(P²-4Q))/2
can be
:2ֿ¹(P+√(P²-4Q

This may be slower than dividing. There are also situations in which this optimization might lose precision, especially when the number being divided is large:

7fPart(4292/7
        1
7fPart(7ֿ¹4292
        .9999999999

Error Conditions

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/inverse


The 1-PropZInt( Command
1-PROPZINT.GIF

Command Summary

Computes a Z confidence interval of a proportion.

Command Syntax

1-PropZInt(x, n[, confidence level])

Menu Location

When editing a program, press:

  1. STAT to access the statistics menu
  2. LEFT to access the TESTS submenu
  3. ALPHA A to select 1-PropZInt(, or use arrows

(this key sequence will give you the 1-PropZInt… screen outside a program)

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The 1-PropZInt( command calculates a confidence interval for a proportion, at a specific confidence level: for example, if the confidence level is 95%, you are 95% certain that the proportion lies within the interval you get. The command assumes that the sample is large enough that the normal approximation to binomial distributions is valid: this is true if, in the sample you take, the positive and negative counts are both >5.

The 1-PropZInt( command takes 3 arguments. The first, x, is the positive count in the sample. The second, n, is the total size of the sample. (So the sample proportion is equal to x out of n). The third argument is the confidence level, which defaults to 95.

The output gives you a confidence interval of the form (a,b), meaning that the true proportion π is most likely in the range a<π<b, and the value of x/n.

Sample Problem

You want to know the proportion of students at your school that support a particular political candidate. You take a random sample of 50 students, and find that 22 of them support that candidate. 22, the positive count, and 50-22=28, the negative count, are both >5, so the assumption is satisfied.

Using 22 for x, and 50 for n, you decide to find a 95% confidence interval. The syntax for that is:

:1-PropZInt(22,50,95
which can also be
:1-PropZInt(22,50,.95

The output if you run the above code will look approximately like this:
1-PropZInt
 (.30241,.57759)
 p=.44
 n=50

This tells you that between about 30.2% and about 57.8% of the students at your school are in support of the political candidate.

Optimization

If the confidence level is 95%, you can omit the final 95, since that is the default value:

:1-PropZInt(22,50,95
can be
:1-PropZInt(22,50

Error Conditions

  • ERR:DOMAIN is thrown if the sample proportion is not between 0 and 1, any argument is negative, or the confidence level is 100 or more.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/1-propzint


The 1-PropZTest( Command
1-PROPZTEST.GIF

Command Summary

Performs a z-test on a proportion.

Command Syntax

1-PropZTest(p0, x, n[, alternative, draw?] )

Menu Location

While editing a program, press:

  1. STAT to access the statistics menu
  2. LEFT to access the TESTS submenu
  3. 5 to select 1-PropZTest, or use arrows

(outside the program editor, this will select the 1-PropZTest… interactive solver)

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

1-PropZTest performs an z-test to compare a population proportion to a hypothesis value. This test is valid for sufficiently large samples: only when the number of successes (x in the command syntax) and the number of failures (n-x) are both >5.

The logic behind the test is as follows: we want to test the hypothesis that the true proportion is equal to some value p0 (the null hypothesis). To do this, we assume that this "null hypothesis" is true, and calculate the probability that the (usually, somewhat different) actual proportion occurred, under this assumption. If this probability is sufficiently low (usually, 5% is the cutoff point), we conclude that since it's so unlikely that the data could have occurred under the null hypothesis, the null hypothesis must be false, and therefore the true proportion is not equal to p0. If, on the other hand, the probability is not too low, we conclude that the data may well have occurred under the null hypothesis, and therefore there's no reason to reject it.

Commonly used notation has the letter π being used for the true population proportion (making the null hypothesis be π=p0). TI must have been afraid that this would be confused with the real number π, so on the calculator, "prop" is used everywhere instead.

In addition to the null hypothesis, we must have an alternative hypothesis as well - usually this is simply that the proportion is not equal to p0. However, in certain cases, our alternative hypothesis may be that the proportion is greater or less than p0.

The arguments to 1-PropZTest( are as follows:

  • p0 - the value for the null hypothesis (the proportion you're testing for)
  • x - the success count in the sample
  • n - the total size of the sample (so the sample proportion would be x/n)
  • alternative (optional if you don't include draw?) - determines the alternative hypothesis
    • 0 (default value) - prop≠p0
    • -1 (or any negative value) - prop<p0
    • 1 (or any positive value) - prop>p0
  • draw? (optional) set this to 1 if you want a graphical rather than numeric result

Although you can access the 1-PropZTest command on the home screen, via the catalog, there's no need: the 1-PropZTest… interactive solver, found in the statistics menu, is much more intuitive to use - you don't have to memorize the syntax.

In either case, it's important to understand the output of 1-PropZTest. Here are the meanings of each line:

  • The first line, involving "prop" and p0, is the alternative hypothesis.
  • z is the test statistic. If the null hypothesis is true, it should be close to 0.
  • p is the probability that the difference between the proportion and p0 would occur if the null hypothesis is true. When the value is sufficiently small, we reject the null hypothesis and conclude that the alternative hypothesis is true. You should have a cutoff value ready, such as 5% or 1%. If p is lower, you "reject the null hypothesis on a 5% (or 1%) level" in technical terms.
  • p-hat is the sample proportion, x/n.
  • n is the sample size.

Advanced Uses

The final optional argument of 1-PropZTest, draw?, will display the results in a graphical manner if you put in "1" for it. The calculator will draw the standard normal distribution, and shade the area of the graph that corresponds to the probability p. In addition, the value of z and the value of p will be displayed. You would make your conclusions in the same way as for the regular output.

Optimization

Some of the arguments of the 1-PropZTest command have default values, and the argument can be omitted if this value is used.

  • The draw? argument can be omitted if you don't want graphical output, although you could put "0" in as well.
  • If the above argument is omitted, and you're doing a two sided test, you may omit the alternative argument.

Example:

:1-PropZTest(.5,22,50,0,0
can be
:1-PropZTest(.5,22,50

Error Conditions

  • ERR:DOMAIN is thrown if p0 or x/n are not between 0 and 1, or x is negative or greater than n (however, any real value for alternative and draw? will work)

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/1-propztest


The 1-Var Stats Command
1-VARSTATS.GIF

Command Summary

Calculates some statistics for a single list of data, and stores them to statistical variables. They're also displayed in a scrollable list, if done outside a program.

Command Syntax

1-Var Stats [list, [freqlist]]

Menu Location

Press:

  1. STAT to access the statistics menu
  2. LEFT to access the CALC submenu
  3. 1 or ENTER to select 1-Var Stats

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

This command calculates a bunch of common (and a few uncommon) statistics for a list (it uses L1 by default, but you can use any list by supplying it as an argument). You have to store the list to a variable first, though, before calculating statistics for it. For example:

:{5,12,7,8,4,9→L1
:1-Var Stats

Like other statistical commands, you can use a frequency list as well, for cases where one element occurs more times than another (you can do this with a normal list, too, but that might be inconvenient when an element occurs very many times). For example:

:{1,2,3→L1
:{5,3,2→L2
:1-Var Stats L1,L2

is the frequency-list equivalent of:
:{1,1,1,1,1,2,2,2,3,3→L1
:1-Var Stats

When you're running it from the home screen, 1-Var Stats will display the statistics; this won't happen if you do it inside a program. Either way, it will also store what it calculated to the statistics variables found in VARS>Statistics… The variables 1-Var Stats affects are:

  • $\overline{\textrm{x}}$ is the mean (average) of the elements, as returned by mean(
  • Σx is the sum of the elements, as returned by sum(
  • Σx² is the sum of the squares of the elements
  • Sx is the sample standard deviation, as returned by stdDev(
  • σx is population standard deviation
  • n is the number of elements in the list, as returned by dim(
  • minX is the minimum value, as returned by min(
  • Q1 is the first quartile
  • Med is the median, as returned by median(
  • Q3 is the third quartile
  • maxX is the maximum value, as returned by max(

1-Var Stats will not work with "reserved" list names that the calculator uses internally. The only known such reserved list is the list RESID, and there's no reason to suspect there are any others. Ans, TblInput, and any expression which resolves to a list, are also not appropriate for this command: store all of these to a list before doing 1-Var Stats on them.

Optimization

Aside from statistical analysis, 1-Var Stats can also be used when you want to use the values it calculates more than once. This will save on size, since, for example Σx takes up less space than sum(L1), but considering how many calculations 1-Var Stats makes, it will usually be slower. Here's a short example which saves 1 byte:

:Disp "RANGE:",max(L1)-min(L1
can be
:1-Var Stats
:Disp "RANGE:",maxX-minX

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/1-var-stats


The ² Command
SQUARE.GIF

Command Summary

Raises the input to the second power.

Command Syntax

value²

Menu Location

Press [x²]

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The ² command raises an input to the second power. It has exactly the same function as "^2", but is one byte smaller. If used on a list, it will return a list with all of the elements squared. If used on a matrix, it will return the second matrix power of the input matrix.

2²
        4
{1,‾2,3}²
        {1 4 9}
[[2,‾1][‾3,0]]²
        [[1  ‾2]
         [6 ‾3]]

Optimization

Use this command instead of ^2 in all instances.

:X^2
can be
:X²

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/2


The 2-PropZInt( Command
2-PROPZINT.GIF

Command Summary

Computes a Z confidence interval of the difference between two proportions.

Command Syntax

2-PropZInt(x1, n1, x2, n2, level//

Menu Location

When editing a program, press:

  1. STAT to access the statistics menu
  2. LEFT to access the TESTS submenu
  3. ALPHA B to select 2-PropZInt(, or use arrows

(this key sequence will give you the 2-PropZInt… screen outside a program)

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The 2-PropZInt( command calculates a confidence interval for the difference between two proportions, at a specific confidence level: for example, if the confidence level is 95%, you are 95% certain that the difference lies within the interval you get. The command assumes that the sample is large enough that the normal approximation to binomial distributions is valid: this is true if, in both samples involved, the positive and negative counts are both >5.

The 1-PropZInt( command takes 5 arguments. The first two, x1 and n1 are the positive count and total count in the first sample (so the estimated value of the first proportion is x1 out of n1. The next two arguments, x2 and n2, are the positive count and total count in the second sample.

The output gives you a confidence interval of the form (a,b), which is the range of values for the difference π12 (where π1 and π2 are the first and second proportions respectively). If you were looking for the difference π21 all you have to do is switch two sides and negate the numbers in the interval.

Sample Problem

You want to compare the proportion of students at your school and at a friend's school. that support a particular political candidate. You take a random sample of 50 students, and find that 22 of them support that candidate. Your friend took a random sample of 75 students at his school, and found that 28 supported the candidate.

The first proportion is the proportion of supporters at your school. 22 out of 50 students support the candidate, so x1=22 and n1=50.
The second proportion is the proportion of supporters at your friend's school. 28 out of 75 students support the candidate, so x2=28 and n2=75.
If you decided to do a 95% confidence interval, you would add the argument 95 after all these, so the syntax would be as follows:

:2-PropZInt(22,50,28,75,95
which can also be
:2-PropZInt(22,50,28,75,.95

The output if you run the above code will look approximately like this:
1-PropZInt
 (-.1092,.24249)
 p1=.44
 p2=.3733333333
 n1=50
 n2=75

This tells you that between about the difference betwen the proportions is between about -0.11 (your school's proportion being about 0.11 less than your friend's school's proportion) to about 0.24 (your school's proportion being about 0.24 greater than your friend's school's proportion).

Optimization

If the confidence level is 95%, you can omit the final 95, since that is the default value:

:2-PropZInt(22,50,28,75,95
can be
:2-PropZInt(22,50,28,75

Error Conditions

  • ERR:DOMAIN is thrown if either proportion is not between 0 and 1, or xi is negative or greater than ni, or the confidence level is negative or at least 100.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/2-propzint


The 2-PropZTest( Command
2-PROPZTEST.GIF

Command Summary

Performs a z-test to compare two proportions.

Command Syntax

2-PropZTest(x1, n1, x2, n2, //draw?//

Menu Location

While editing a program, press:

  1. STAT to access the statistics menu
  2. LEFT to access the TESTS submenu
  3. 6 to select 2-PropZTest, or use arrows

(outside the program editor, this will select the 2-PropZTest… interactive solver)

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

2-PropZTest( performs az-test to compare two population proportions. This test is valid for sufficiently large samples: only when the number of successes (x in the command syntax) and the number of failures (n-x) are both >5, for both populations.

The logic behind the test is as follows: we want to test the hypothesis that the proportions are equal (the null hypothesis). To do this, we assume that this "null hypothesis" is true, and calculate the probability that the differences between the two proportions occurred, under this assumption. If this probability is sufficiently low (usually, 5% is the cutoff point), we conclude that since it's so unlikely that the data could have occurred under the null hypothesis, the null hypothesis must be false, and therefore the proportions are not equal. If, on the other hand, the probability is not too low, we conclude that the data may well have occurred under the null hypothesis, and therefore there's no reason to reject it.

Commonly used notation has the letters π1 and π2 being used for the true population proportions (making the null hypothesis be π12). TI must have been afraid that this would be confused with the real number π, so on the calculator, "p1" and "p2" are used everywhere instead.

In addition to the null hypothesis, we must have an alternative hypothesis as well - usually, this is simply that the proportions are not equal. However, in certain cases, our alternative hypothesis may be that one proportion is greater or less than the other.

The arguments to 2-PropZTest( (which must be integers, or the calculator will generate a domain error) are as follows:

  • x1 - the success count in the first sample
  • n1 - the total size of the first sample (so the sample proportion would be x1/n1)
  • x2 - the success count in the second sample
  • n2 - the total size of the second sample (so the sample proportion would be x2/n2)
  • alternative (optional if you don't include draw?) - determines the alternative hypothesis
    • 0 (default value) - p1≠p2
    • -1 (or any negative value) - p1<p2
    • 1 (or any positive value) - p1>p2
  • draw? (optional) set this to 1 if you want a graphical rather than numeric result

Although you can access the 2-PropZTest( command on the home screen, via the catalog, there's no need: the 2-PropZTest(… interactive solver, found in the statistics menu, is much more intuitive to use - you don't have to memorize the syntax.

In either case, it's important to understand the output of 2-PropZTest(. Here are the meanings of each line:

  • The first line, involving p1 and p2, is the alternative hypothesis.
  • z is the test statistic. If the null hypothesis is true, it should be close to 0.
  • p is the probability that the difference between the two proportions would occur if the null hypothesis is true. When the value is sufficiently small, we reject the null hypothesis and conclude that the alternative hypothesis is true. You should have a cutoff value ready, such as 5% or 1%. If p is lower, you "reject the null hypothesis on a 5% (or 1%) level" in technical terms.
  • p-hat1 is the sample proportion x1/n1.
  • p-hat2 is the sample proportion x2/n2.
  • p-hat is the total sample proportion
  • n1 is the first sample size.
  • n2 is the second sample size.

Advanced Uses

The final optional argument of 2-PropZTest(, draw?, will display the results in a graphical manner if you put in "1" for it. The calculator will draw the standard normal distribution, and shade the area of the graph that corresponds to the probability p. In addition, the value of z and the value of p will be displayed. You would make your conclusions in the same way as for the regular output.

Optimization

Some of the arguments of the 2-PropZTest( command have default values, and the argument can be omitted if this value is used.

  • The draw? argument can be omitted if you don't want graphical output, although you could put "0" in as well.
  • If the above argument is omitted, and you're doing a two-sided test, you may omit the alternative argument.

Example:

:2-PropZTest(22,50,48,100,0,0
can be
:2-PropZTest(22,50,48,100

Error Conditions

  • ERR:DOMAIN is thrown if the values of the arguments entered are not integers.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/2-propztest


The 2-SampFTest Command
2-SAMPFTEST.GIF

Command Summary

Performs a F-test to compare the standard deviations of two populations.

Command Syntax

2-SampFTest [list1, list2, frequency1, frequency2, alternative,draw?]
(data list input)

2-SampFTest s1, n1, s2, n2, [alternative,draw?]
(summary stats input)

Menu Location

While editing a program, press:

  1. STAT to access the statistics menu
  2. LEFT to access the TESTS submenu
  3. ALPHA D to select 2-SampFTest, or use arrows

Outside the program editor, this will select the 2-SampFTest… interactive solver.

Change the last keypress to ALPHA E on a TI-84+/SE with OS 2.30 or higher.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

2-SampFTest performs an F-test to compare the standard deviations of two populations. This test is valid for two normally distributed populations, but is extremely sensitive to non-normality, so it should not be used unless you are certain that the populations are normal.

The logic behind the test is as follows: we want to test the hypothesis that the standard deviations of the two populations are equal (the null hypothesis). The letter σ is used for a standard deviation, so this is usually written as σ12. To do this, we assume that this "null hypothesis" is true, and calculate the probability that the difference between the two standard deviations occurred, under this assumption. If this probability is sufficiently low (usually, 5% is the cutoff point), we conclude that since it's so unlikely that the data could have occurred under the null hypothesis, the null hypothesis must be false, and therefore the deviations are not equal. If, on the other hand, the probability is not too low, we conclude that the data may well have occurred under the null hypothesis, and therefore there's no reason to reject it.

In addition to the null hypothesis, we must have an alternative hypothesis as well - usually this is simply that the two standard deviations are not equal. However, in certain cases when we have reason to suspect that one deviation is greater than the other (such as when we are trying to verify a claim that one standard deviation is greater), our alternative hypothesis may be that the first standard deviation is greater than the second (σ12) or less (σ12).

As for the 2-SampFTest command itself, there are two ways of calling it: you may give it a list of all the sample data, or the necessary statistics about the list (s1 and s2 the sample standard deviations, and n1 and n2 the sample sizes). In either case, you can indicate what the alternate hypothesis is, by a value of 0, -1, or 1 for the alternative argument. 0 indicates a two-sided hypothesis of σ1σ2, -1 indicates σ1<σ2, and 1 indicates μ1>μ2. (In fact, the calculator will treat any negative value as -1, and any positive value as 1).

Although you can access the 2-SampFTest command on the home screen, via the catalog, there's no need: the 2-SampFTest… interactive solver, found in the statistics menu, is much more intuitive to use - you don't have to memorize the syntax.

In either case, it's important to understand the output of 2-SampFTest. Here are the meanings of each line:

  • The first line, involving σ1 and σ2, is the alternative hypothesis.
  • F is the test statistic, the ratio of the standard deviations. If the null hypothesis is true, it should be close to 1.
  • p is the probability that the difference between σ1 and σ2 (the two standard deviations) would occur if the null hypothesis is true. When the value is sufficiently small, we reject the null hypothesis and conclude that the alternative hypothesis is true. You should have a cutoff value ready, such as 5% or 1%. If p is lower, you "reject the null hypothesis on a 5% (or 1%) level" in technical terms.
  • Sx1 and Sx2 are the two sample standard deviations.
  • x-bar1 and x-bar2 are the two sample means. They aren't used in the calculation, and will only be shown with the data list syntax.
  • n1 and n2 are the sample sizes.

Advanced Uses

The final optional argument of 2-SampFTest, draw?, will display the results in a graphical manner if you put in "1" for it. The calculator will draw the distribution, and shade the area of the graph that corresponds to the probability p. In addition, the value of F and the value of p will be displayed. You would make your conclusions in the same way as for the regular output.

As with most other statistical commands, you may use frequency lists in your input (when using the data list syntax). If you do, then both lists must have frequencies, and the order of the arguments would be list1, list2, frequency1, frequency2.

Optimization

Some of the arguments of the 2-SampFTest command have default values, and the argument can be omitted if this value is accepted.

  • The draw? argument can be omitted if you don't want graphical output, although you could put "0" in as well.
  • If the above argument is omitted, and you're doing a two sided test, you may omit the alternative argument.
  • With data list input, you can always omit the frequency lists if you won't be using them.
  • With data list input, if the flags that go at the end are omitted, and you're using the default lists L1 and L2, you may omit those as well.

Example:

:2-SampFTest L1,L2,0
can be
:2-SampFTest

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/2-sampftest


The 2-SampTInt Command
2-SAMPTINT.GIF

Command Summary

Using either already-calculated statistics, or two data sets, computes a T confidence interval for the difference between two sample means.

Command Syntax

2-SampTInt list1, list2, [frequency1], [frequency2], [confidence level, pooled]
(data list input)

2-SampTInt x1, s1, n1, x2, s2, n2, [confidence level, pooled]
(summary stats input)

Menu Location

When editing a program, press:

  1. STAT to access the statistics menu
  2. LEFT to access the TESTS submenu
  3. 0 to select 2-SampTInt, or use arrows

(this key sequence will give you the 2-SampTInt… screen outside a program)

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The 2-SampTInt command uses the techniques of T Intervals to compute an interval for the difference between the means of two independent populations, at a specified confidence level. Use 2-SampTInt( when you have two independent variables to compare, and you don't know their standard deviations. The 2-SampTInt command assumes that both your variables are normally distributed, but it will work for other distributions if the sample size is large enough.

There are two ways to call this command: by supplying it with needed sample statistics (mean, standard deviation, and sample size, for both data sets), or by entering two lists and letting the calculator work the statistics out. In either case, you will need to enter the desired confidence level as well.

In the summary stats syntax, x1 and x2 the two sample means, s1 and s2 are the two sample standard deviations, and n1 and n2 the two sample sizes.

The output will contain an open interval (a, b) that is your answer: the difference between the two means will lie in this interval. Specifically, it is the second mean subtracted from the first - μ12. If you're interested in the reverse difference, just flip the signs on the interval.

Tip: don't use this command in a matched-pairs setting when you can match the two samples up by units or subjects. Instead, take the difference between the two samples in each matched pair, and use a regular TInterval.

Sample Problem

You want to compare the average height of a freshman and a senior at your school. You haven't asked everyone, but you took a random sample of 40 people from each class and found out their heights (and stored them to L1 and L2). You've decided to use a 95% confidence interval.

Based on the data list syntax for a 2-SampTInt, here is your code:

:2-SampTInt L1,L2,95
you can also use
:2-SampTInt L1,L2,.95

Alternatively, you could calculate the mean and sample size and enter those instead. The sample size in this case is 40 for both data sets; let's say the means were 57 inches and 67 inches and the standard deviations 5.2 and 7.1 inches. You now have all the needed statistics:

  • x1 is the mean height of freshmen: 57 inches
  • s1 is the sample standard deviation for freshmen: 5.2 inches
  • n1 is the number of freshmen in the sample: 40
  • x2 is the mean height of seniors: 67 inches
  • s2 is the sample standard deviation for seniors: 7.1 inches
  • n2 is the number of seniors in the sample: 40

This means that the code is:

:2-SampTInt 57,5.2,40,67,7.1,40,95
you can also use
:2-SampTInt 57,5.2,40,67,7.1,40,.95

Of course, the main use of the 2-SampTInt command is in a program. While you can enter the command on the home screen as well (just look in the catalog for it), it would probably be easier to select 2-SampTInt… from the STAT>TEST menu (see the sidebar), since you don't have to remember the syntax.

Advanced Uses

As with most other statistical commands, you can add frequencies to the lists (only with the data list syntax, of course); if you do, both lists must have frequencies, and the arguments go in the order first data list, second data list, first freq. list, second freq. list. Each frequency list must contain non-negative real numbers, which can't be all 0.

There is a final argument to 2-SampTInt: pooled. It can be either 0 or 1 (although any argument that isn't 0 will get treated as a 1); the default value is 0. If the value is 1, then then the variances will be pooled: that is, the calculator will assume that the variances of the two populations are equal, and use a combined form of the two standard deviations in place of each population's individual standard deviation. Set this flag if you have reason to believe that the standard deviations are equal.

Optimization

Using the data list syntax, all items are optional: the calculator will assume you want to use L1 and L2 for your data unless other lists are supplied, and that the confidence level you want is 95% unless you give another one. Using the summary stats syntax, the confidence level is also optional - again, the calculator will assume 95%. This means we can rewrite our code above in a simpler manner:

:2-SampTInt L1,L2,95
can be
:2-SampTInt
:2-SampTInt 57,5.2,40,67,7.1,40,95
can be
:2-SampTInt 57,5.2,40,67,7.1,40

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/2-samptint


The 2-SampTTest Command
2-SAMPTTEST.GIF

Command Summary

Performs a t significance test to compare the means of two populations.

Command Syntax

2-SampTTest [list1, list2, frequency1, frequency2, alternative, pooled? draw?]
(data list input)

2-SampTTest x1, s1, n1, x2, s2, n2, [alternative, pooled?, draw?]
(summary stats input)

Menu Location

While editing a program, press:

  1. STAT to access the statistics menu
  2. LEFT to access the TESTS submenu
  3. 4 to select 2-SampTTest, or use arrows

(outside the program editor, this will select the 2-SampTTest… interactive solver)

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

2-SampTTest performs a t significance test to compare the means of two populations. This test is valid for simple random samples from populations with unknown standard deviations. In addition, either the populations must be normally distributed, or the sample sizes have to be sufficiently large (usually, greater than 10).

The logic behind the test is as follows: we want to test the hypothesis that the true means of the two populations are equal (the null hypothesis). The letter μ is used for a population mean, so this is usually written as μ12. To do this, we assume that this "null hypothesis" is true, and calculate the probability that the difference between the two means occurred, under this assumption. If this probability is sufficiently low (usually, 5% is the cutoff point), we conclude that since it's so unlikely that the data could have occurred under the null hypothesis, the null hypothesis must be false, and therefore the means are not equal. If, on the other hand, the probability is not too low, we conclude that the data may well have occurred under the null hypothesis, and therefore there's no reason to reject it.

In addition to the null hypothesis, we must have an alternative hypothesis as well - usually this is simply that the two means are not equal. However, in certain cases when we have reason to suspect that one mean is greater than the other (such as when we are trying to verify a claim that one mean is greater), our alternative hypothesis may be that the first mean is greater than the second (μ12) or less (μ12).

As for the 2-SampTTest command itself, there are two ways of calling it: you may give it a list of all the sample data, or the necessary statistics about the list (x1 and x2 are the sample means, s1 and s2 the sample standard deviations, and n1 and n2 the sample sizes). In either case, you can indicate what the alternate hypothesis is, by a value of 0, -1, or 1 for the alternative argument. 0 indicates a two-sided hypothesis of μ1μ2, -1 indicates μ1<μ2, and 1 indicates μ1>μ2. (In fact, the calculator will treat any negative value as -1, and any positive value as 1).

Although you can access the 2-SampTTest command on the home screen, via the catalog, there's no need: the 2-SampTTest… interactive solver, found in the statistics menu, is much more intuitive to use - you don't have to memorize the syntax.

In either case, it's important to understand the output of 2-SampTTest. Here are the meanings of each line:

  • The first line, involving μ1 and μ2, is the alternative hypothesis.
  • t is the test statistic, the standardized difference between the means. If the null hypothesis is true, it should be close to 0.
  • p is the probability that the difference between μ1 and μ2 (the two means) would occur if the null hypothesis is true. When the value is sufficiently small, we reject the null hypothesis and conclude that the alternative hypothesis is true. You should have a cutoff value ready, such as 5% or 1%. If p is lower, you "reject the null hypothesis on a 5% (or 1%) level" in technical terms.
  • x-bar1 and x-bar2 are the two sample means.
  • Sx1 and Sx2 are the two sample standard deviations.
  • n1 and n2 are the sample sizes.

Sample Problem

Your school claims that the average SAT score of students at the school is higher than at a rival school. You took samples of SAT scores from students at both schools (and stored them to L1 and L2).
Since the school's claim is that your school's score is higher, that will be your alternative hypothesis (μ1>μ2), which corresponds to a value of 1. The code you'd use is:

:2-SampTTest L1,L2,1

Alternatively, you could calculate the mean, standard deviation, and size of your samples, and put those into the command instead. Suppose you obtained SAT scores from 60 students at your school and 40 students at the rival school, the means were 1737 and 1623, and the standard deviation 211 and 218. Then your code is:

:2-SampTTest 1737,211,60,1623,218,40,1

You will see the following output:

2-SampTTest
 μ1>μ2
 z=2.594854858
 p=.0056059824
 x1=1737
 x2=1623
 Sx1=211
 Sx2=218
 n1=60
 n2=40

The most important part of this output is "p=.0056059824". This value of p is smaller than 1% or 0.01. This is significant on the 1% level, so we reject the null hypothesis and conclude that the alternative hypothesis is true: μ12, that is, your school's average SAT score is indeed higher.

Advanced Uses

The final optional argument of 2-SampTTest, draw?, will display the results in a graphical manner if you put in "1" for it. The calculator will draw the distribution, and shade the area of the graph beyound the t statistic. In addition, the value of t and the value of p will be displayed (the value of p corresponds to the shaded area). You would make your conclusions in the same way as for the regular output.

The optional argument pooled?, if given a nonzero value, will pool the standard deviations to find a combined value which will then be used for both populations. Use this feature if you have reason to believe that the two populations have the same standard deviation.

As with most other statistical commands, you may use a frequency list in your input (when using the data list syntax). If you do, then both lists must have frequencies, and the order of the arguments would be list1, list2, frequency1, frequency2.

Optimization

Some of the arguments of the 2-SampTTest command have default values, and the argument can be omitted if this value is accepted.

  • The draw? argument can be omitted if you don't want graphical output, although you could put "0" in as well.
  • If the draw? argument is omitted, you can omit the pooled? argument if you do not want your standard deviations pooled.
  • If both the above arguments are omitted, and you're doing a two sided test, you may omit the alternative argument.
  • With data list input, you can always omit the frequency lists if you won't be using them.
  • With data list input, if the flags that go at the end are omitted, and you're using the default lists L1 and L2, you may omit those as well.

The code in the sample problem above can't be optimized, because the alternative argument is 1:

:2-SampTTest L1,L2,1

However, if we were doing a two-sided test, we could omit the alternative argument as well as the lists:

:2-SampTTest L1,L2,0
can be just
:2-SampTTest

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/2-sampttest


The 2-SampZInt( Command
2-SAMPZINT.GIF

Command Summary

Using either already-calculated statistics, or two data sets, computes a Z confidence interval for the difference between two sample means.

Command Syntax

2-SampZInt(σ1, σ2, [list1, list2, [frequency1], [frequency2], [confidence level]
(data list input)

2-SampZInt(σ1, σ2, x1, n1, x2, n2, level//
(summary stats input)

Menu Location

When editing a program, press:

  1. STAT to access the statistics menu
  2. LEFT to access the TESTS submenu
  3. 9 to select 2-SampZInt(, or use arrows

(this key sequence will give you the 2-SampZInt… screen outside a program)

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The 2-SampZInt( command uses the techniques of Z Intervals to compute an interval for the difference between the means of two independent populations, at a specified confidence level. Use 2-SampZInt( when you have two independent variables to compare, and you already know their standard deviations. The 2-SampZInt( command assumes that both variables are distributed normally, but it will work for other distributions if the sample size is large enough.

There are two ways to call this command: by supplying it with needed sample statistics (mean and sample size, for both data sets), or by entering two lists and letting the calculator work the statistics out. In either case, you will need to enter the standard deviation and desired confidence level as well.

In the data list syntax, σ1 and σ2 are the two standard deviations.
In the summary stats syntax, σ1 and σ2 are the two standard deviations, x1 and x2 the two sample means, and n1 and n2 the two sample sizes.

The output will contain an open interval (a, b) that is your answer: the difference between the two means will lie in this interval. Specifically, it is the second mean subtracted from the first - μ12. If you're interested in the reverse difference, just flip the signs on the interval.

Tip: don't use this command in a matched-pairs setting when you can match the two samples up by units or subjects. Instead, take the difference between the two samples in each matched pair, and use a regular ZInterval.

Sample Problem

You want to compare the average height of a freshman and a senior at your school. You haven't asked everyone, but you took a random sample of 40 people from each class and found out their heights (and stored them to L1 and L2). You've read in your textbook that the standard deviation of teenagers' heights is usually 6 inches. You've decided to use a 95% confidence interval.

Based on the data list syntax for a 2-SampZInt(, here is your code:

:2-SampZInt(6,6,L1,L2,95
you can also use
:2-SampZInt(6,6,L1,L2,.95

Alternatively, you could calculate the mean and sample size and enter those instead. The sample size in this case is 40 for both data sets; let's say the means were 57 inches and 67 inches. You now have all the needed statistics:

  • σ1 is the standard deviation for freshmen: 6 inches
  • σ2 is the standard deviation for seniors: also 6 inches
  • x1 is the mean height of freshmen: 57 inches
  • n1 is the number of freshmen in the sample: 40
  • x2 is the mean height of seniors: 67 inches
  • n2 is the number of seniors in the sample: 40

This means that the code is:

:2-SampZInt(6,6,57,40,67,40,95
you can also use
:2-SampZInt(6,6,57,40,67,40,.95

Of course, the main use of the 2-SampZInt( command is in a program. While you can enter the command on the home screen as well (just look in the catalog for it), it would probably be easier to select 2-SampZInt… from the STAT>TEST menu (see the sidebar), since you don't have to remember the syntax.

Advanced Uses

As with most other statistical commands, you can add frequencies to the lists (only with the data list syntax, of course); if you do, both lists must have frequencies, and the arguments go in the order first data list, second data list, first freq. list, second freq. list. Each frequency list must contain non-negative real numbers, which can't be all 0.

Optimization

Using the data list syntax, all items but the standard deviations are optional: the calculator will assume you want to use L1 and L2 for your data unless other lists are supplied, and that the confidence level you want is 95% unless you give another one. Using the summary stats syntax, the confidence level is also optional - again, the calculator will assume 95%. This means we can rewrite our code above in a simpler manner:

:2-SampZInt(6,6,L1,L2,95
can be
:2-SampZInt(6,6
:2-SampZInt(6,6,57,40,67,40,95
can be
:2-SampZInt(6,6,57,40,67,40

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/2-sampzint


The 2-SampZTest( Command
2-SAMPZTEST.GIF

Command Summary

Performs a z significance test to compare the means of two populations.

Command Syntax

2-SampZTest(σ1, σ2 //list2//, //frequency1//, //frequency2//, //alternative//, //draw?//
(data list input)

2-SampZTest(σ1, σ2 x1, n1, x2, n2, //draw?//
(summary stats input)

Menu Location

While editing a program, press:

  1. STAT to access the statistics menu
  2. LEFT to access the TESTS submenu
  3. 3 to select 2-SampZTest(, or use arrows

(outside the program editor, this will select the 2-SampZTest… interactive solver)

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

2-SampZTest( performs a z significance test to compare the means of two populations. This test is valid for simple random samples from populations with known standard deviations. In addition, either the populations must be normally distributed, or the sample sizes have to be sufficiently large (usually, greater than 10).

The logic behind the test is as follows: we want to test the hypothesis that the true means of the two populations are equal (the null hypothesis). The letter μ is used for a population mean, so this is usually written as μ12. To do this, we assume that this "null hypothesis" is true, and calculate the probability that the difference between the two means occurred, under this assumption. If this probability is sufficiently low (usually, 5% is the cutoff point), we conclude that since it's so unlikely that the data could have occurred under the null hypothesis, the null hypothesis must be false, and therefore the means are not equal. If, on the other hand, the probability is not too low, we conclude that the data may well have occurred under the null hypothesis, and therefore there's no reason to reject it.

In addition to the null hypothesis, we must have an alternative hypothesis as well - usually this is simply that the two means are not equal. However, in certain cases when we have reason to suspect that one mean is greater than the other (such as when we are trying to verify a claim that one mean is greater), our alternative hypothesis may be that the first mean is greater than the second (μ12) or less (μ12).

As for the 2-SampZTest( command itself, there are two ways of calling it: after giving the two standard deviations, you may give it a list of all the sample data, or the necessary statistics about the list (x1 and x2 are the sample means, and n1 and n2 are the sample sizes). In either case, you can indicate what the alternate hypothesis is, by a value of 0, -1, or 1 for the alternative argument. 0 indicates a two-sided hypothesis of μ1μ2, -1 indicates μ1<μ2, and 1 indicates μ1>μ2. (In fact, the calculator will treat any negative value as -1, and any positive value as 1).

Although you can access the 2-SampZTest( command on the home screen, via the catalog, there's no need: the 2-SampZTest… interactive solver, found in the statistics menu, is much more intuitive to use - you don't have to memorize the syntax.

In either case, it's important to understand the output of 2-SampZTest. Here are the meanings of each line:

  • The first line, involving μ1 and μ2, is the alternative hypothesis.
  • z is the test statistic, the standardized difference between the means. If the null hypothesis is true, it should be close to 0.
  • p is the probability that the difference between μ1 and μ2 (the two means) would occur if the null hypothesis is true. When the value is sufficiently small, we reject the null hypothesis and conclude that the alternative hypothesis is true. You should have a cutoff value ready, such as 5% or 1%. If p is lower, you "reject the null hypothesis on a 5% (or 1%) level" in technical terms.
  • x-bar1 and x-bar2 are the two sample means.
  • n1 and n2 are the sample sizes.

Sample Problem

Your school claims that the average SAT score of students at the school is higher than at a rival school. You took samples of SAT scores from students at both schools (and stored them to L1 and L2). Although you didn't know the standard deviations, you decided to use the value 200 that you found online as an estimate.

You now have all the data. You're assuming σ1 and σ2 are both 200; the two data lists are L1 and L2. Since the school's claim is that your school's score is higher, that will be your alternative hypothesis (μ1>μ2), which corresponds to a value of 1. The code you'd use is:

:2-SampZTest(200,200,L1,L2,1

Alternatively, you could calculate the mean and sample size of your sample, and put those into the command instead. Suppose you obtained SAT scores from 60 students at your school and 40 students at the rival school, and that the means were 1737 and 1623. Then your code is:

:2-SampZTest(200,200,1737,60,1623,40,1

You will see the following output:

Z-Test
 μ1>μ2
 z=2.792418307
 p=.0026158434
 x1=1737
 x2=1623
 n1=60
 n2=40

The most important part of this output is "p=.0026158434". This value of p is much smaller than 1% or 0.01. This is significant on the 1% level, so we reject the null hypothesis and conclude that the alternative hypothesis is true: μ12, that is, your school's average SAT score is indeed higher.

Advanced Uses

The final argument of 2-SampZTest(, draw?, will display the results in a graphical manner if you put in "1" for it. The calculator will draw the standard normal curve, and shade the area of the graph beyond the z statistic. In addition, the value of z and the value of p will be displayed (the value of p corresponds to the shaded area). You would make your conclusions in the same way as for the regular output.

As with most other statistical commands, you may use a frequency list in your input (when using the data list syntax). If you do, then both lists must have frequencies, and the order of the arguments would be list1, list2, frequency1, frequency2.

Optimization

Most of the arguments of the 2-SampZTest( command have default values, and the argument can be omitted if this value is accepted.

  • The draw? argument can be omitted if you don't want graphical output, although you could put "0" in as well.
  • If the draw? argument is omitted, you can omit the alternative argument to use a two-sided test (μ1μ2). If you include the draw? argument, you have to include this - otherwise there will be confusion as to what the 5th argument means.
  • With data list input, you can always omit the frequency lists if you won't be using them.
  • With data list input, if the draw? and alternative arguments are omitted, and your data is in L1 and L2 (and you're not using frequency lists), you may omit L1 and L2 - those are default parameters. However, if alternative or draw? is present, you have to include it, or else the syntax may be confused with the syntax for summary stats input.

The code in the sample problem above can't be optimized, because the alternative argument is 1:

:2-SampZTest(200,200,L1,L2,1

However, if we were doing a two-sided test, we could omit the alternative argument as well as the lists:

:2-SampZTest(200,200,L1,L2,0
can be
:2-SampZTest(200,200

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/2-sampztest


The 2-Var Stats Command
2-VARSTATS.GIF

Command Summary

Calculates some common statistics for two lists of data, and stores them to statistical variables. They're also displayed in a scrollable list, if done outside a program.

Command Syntax

2-Var Stats [list1, list2, [freqlist]]

Menu Location

Press:

  1. STAT to access the statistics menu
  2. LEFT to access the CALC submenu
  3. 2 to select 2-Var Stats, or use arrows

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

This command calculates a bunch of common (and a few uncommon) statistics for a pair of lists (it uses L1 and L2 by default, but you can use any list by supplying it as an argument). You have to store the lists to variables first, though, before calculating statistics for them. For example:

:{5,12,7,8,4,9→L1
:{1,0,2,5,7,4→L2
:2-Var Stats

The calculator treats the two lists as a list of ordered pairs. Some of the statistics calculated assume that this is the case, and the two lists are the same size: an error will occur if the lists don't match.

Like other statistical commands, you can use a frequency list as well, for cases where one element occurs more times than another (you can do this with a normal list, too, but that might be inconvenient when an element occurs very many times). There is only one frequency list for both data lists, and the frequency applies to the ordered pair formed by an element taken from each list. For example:

:{1,2,3→L1
:{1,2,3→L2
:{5,3,2→L3
:2-Var Stats L1,L2,L3

is the frequency-list equivalent of:
:{1,1,1,1,1,2,2,2,3,3→L1
:{1,1,1,1,1,2,2,2,3,3→L2
:2-Var Stats

When you're running it from the home screen, 2-Var Stats will display the statistics; this won't happen if you do it inside a program. Either way, it will also store what it calculated to the statistics variables found in VARS>Statistics… The variables 2-Var Stats affects are:

  • $\definecolor{darkgreen}{rgb}{0.90,0.91,0.859}\pagecolor{darkgreen} \overline{\textrm{x}}$ is the mean (average) of the first list
  • Σx is the sum of the first list
  • Σx² is the sum of the squares of the first list
  • Sx is the sample standard deviation of the first list
  • σx is population standard deviation of the first list
  • minX is the minimum element of the first list
  • maxX is the maximum element of the first list
  • $\definecolor{darkgreen}{rgb}{0.90,0.91,0.859}\pagecolor{darkgreen} \overline{\textrm{y}}$ is the mean (average) of the second list
  • Σy is the sum of the second list
  • Σy² is the sum of the squares of the second list
  • Sy is the sample standard deviation of the second list
  • σy is population standard deviation of the second list
  • minY is the minimum element of the second list
  • maxY is the maximum element of the second list
  • Σxy is the sum of products of each matching pair of elements in the lists
  • n is the number of elements in both lists

2-Var Stats will not work with "reserved" list names that the calculator uses internally. The only known such reserved list is the list RESID, and there's no reason to suspect there are any others. Ans, TblInput, and any expression which resolves to a list, are also not appropriate for this command: store all of these to a list before doing 2-Var Stats on them.

Advanced uses

If you consider the two lists to be vectors, then Σxy is their dot product, and Σx² and Σy² are the squares of their norms; math done with these and other statistics can produce the shortest (but not necessarily quickest) way to calculate many vector operations.

Optimization

Aside from statistical analysis, 2-Var Stats can also be used when you want to use the values it calculates more than once. This will save on size, since, for example Σx takes up less space than sum(L1), but considering how many calculations 2-Var Stats makes, it will usually be slower.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/2-var-stats


The ³√( Command
CUBEROOT.GIF

Command Summary

Take the cube root of a number.

Command Syntax

³√(input)

Menu Location

While editing a program, press:

  1. MATH to open the math menu
  2. 4 or use the arrow keys to select.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

Takes the cube root of a positive or negative number. It works exactly the same as 3×√ or ^(1/3) but is smaller and uses an ending parenthesis. If used on a list, it will return a list with the cube root of each element.

³√(8)
        2
³√(2)
        1.25992105

³√({1,‾8,27})
        {1 ‾2 3}

For complex numbers, the principal cube root is returned, which may be different from the cube root you'd get for the same real number:

³√(-8)
        -2
³√(-8+0i)
        1+1.732050808i

Optimization

Never raise something to the one-third power explicitly; use this command instead.

:X^(1/3)→X
can be
:³√(X→X

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/cube-root


The ³ Command
CUBE.GIF

Command Summary

Raises the input to the third power.

Command Syntax

value³

Menu Location

While editing a program, press:

  1. MATH to enter the MATH menu
  2. 3 or use the arrow keys to select.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The ³ command raises an input to the third power. It has exactly the same function as "^3", but is one byte smaller. If used on a list, it will return a list with all of the elements cubed. If used on a matrix, it will return the third matrix power of the input matrix.

2³
        8
{1,‾2,3}³
        {1 ‾8 27}
[[2,‾1][‾3,0]]³
        [[20  ‾7]
         [‾21  6]]

Advanced Uses

One trick with ³ is to use it to save space (at the cost of speed) when using hard-coded values. For instance, use 5³ instead of 125 to save one byte.

Optimization

Use this command instead of ^3 in all instances.

:X^3
can be
:X³

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/3


The a+bi Command
APLUSBI.GIF

Command Summary

Puts the calculator into a+bi mode.

Command Syntax

a+bi

Menu Location

Press:

  1. MODE to access the mode menu.
  2. Use the arrow keys and ENTER to select a+bi

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The a+bi command puts the calculator into rectangular complex number mode. This means that:

  • Taking square roots of negative numbers, and similar operations, no longer returns an error.
  • Complex results are displayed in the form a+bi (hence the name of the command)

This is the standard way of displaying complex numbers, though they can also be displayed in polar form (see re^θi for more details). To extract the coefficients a and b, use the real( and imag( commands.

Advanced Uses

Rather than switch to a+bi mode, you might want to force the calculations to use complex numbers by making the original argument complex. The general way to do this is by adding +0i to the number. However, there may be an optimization in any particular case. See the quadratic formula routine for a good example of this.

Real
        Done
√(-1)    
        (causes an error)
√(-1+0i)        
        i

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/a-bi


The abs( Command
ABS.GIF

Command Summary

Returns the absolute value of a real number, and the complex absolute value of a complex number.

Command Syntax

abs(value)

Menu Location

Press:

  1. MATH to access the math menu.
  2. RIGHT to access the NUM submenu.
  3. ENTER to select abs(.

Alternatively, press:

  1. MATH to access the math menu.
  2. RIGHT twice to access the CPX (complex) submenu.
  3. 5 to select abs(, or use arrows.

Calculator Compatibility

TI-83/84/+/SE/CSE/CE

Token Size

1 byte

abs(x) returns the absolute value of the real number x. Also works on a list or matrix of real numbers.

abs(3)
     3

abs(‾3)
     3

For complex numbers, abs(z) returns the absolute value (also known as the complex modulus, norm, or a hundred other terms) of the complex number z. If z is represented as x+iy where x and y are both real, abs(z) returns √(x²+y²). Also works on a list of complex numbers.

abs(3+4i)
     5

Optimization

The abs( command, used properly, may be a smaller method of testing if a variable is in some range. For example:

:If 10<X and X<20
can be
:If 5>abs(X-15

In general, the first number, A, in the expression A>abs(X-B) should be half the length of the range, half of 10 in this case, and the second number, B, should be the midpoint of the range (here, 15).

This can be taken to extreme degrees. For example, the following code uses abs( three times to test if X is the getKey keycode of one of the keys 1, 2, 3, 4, 5, 6, 7, 8, or 9:

:If 2>abs(5-abs(5-abs(X-83

For complex numbers given by a separate real and complex part, abs(X+iY) can be optimized to R►Pr(X,Y).

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/abs


The and Command
AND.GIF

Command Summary

Returns the logical value of value1 and value2 being true.

Command Syntax

value1 and value2

Menu Location

Press:

  1. 2nd TEST to access the test menu.
  2. RIGHT to access the LOGIC submenu.
  3. ENTER to select and.

Calculator Compatibility

TI-83/84/+/SE/CSE/CE

Token Size

1 byte

and takes two numbers, variables, or expressions and tests to see if they are both True (not equal to 0). If they are, it returns 1. If either input is False (0), it returns 0. Note that the order of the operators doesn't matter (i.e. and is commutative), and that multiple and's can be used together

:0 and 0 
           0

:0 and 1
           0 

:1 and 2           (2 counts as True, just like one)
           1

:1→X
:X and 2+2         (you can use variables and expressions)
           1

:1 and 1 and 2-2   (the last input evaluates to 0, or false)
           0

Optimization

Multiplying two values has the same truth value as and; thus, and can sometimes be replaced by multiplication. Because the calculator does implicit multiplication, meaning it automatically recognises when you want to multiply, you don't need to use the * sign.

:If A and B
can be
:If AB

However, do not use this optimization if A and B might be expected to take on large values, as an overflow error might occur.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/and


The and Command

and.png

Command Summary

Tests if two conditions are both true.
Can also be used as a bitwise "and" on integers.

Command Syntax

condition1 and condition2
integer1 and integer2

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press 8 to enter the Test submenu.
  • Press 8 to select and.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The and operator combines two conditions into one, which will be true if both sides are true, and false otherwise. You can create these conditions with the relational operators =, , >, , <, and , with functions such as isPrime(), pxlTest(), and ptTest(), or with any other expression that returns 'true' or 'false'. Other operators for dealing with conditions are or, xor, and not.

:2+2=4 and 1=0
           false
:2+2=4 and 1+1=2
           true

The operator can also be applied to integers, treating them as 32-bit signed integers (larger integers will be truncated to fit) expressed in binary. The bits will be matched up, and "and" will be applied to the bits individually — a bit in the result will be 1 if the two corresponding bits of the original integers were 1, and 0 otherwise.

:(0b11111100 and 0b00111111)▶Bin
           0b111100
:1000 and 512
           512

In complicated logical expressions (both with conditions and with integers), and has greater priority than the others ("or" and "xor"). For instance:

X or Y and Z

will be interpreted as:

X or (Y and Z)

Error Conditions

60 - Argument must be a Boolean expression or integer happens when the data type is incorrect (or mismatched).

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:and


The AndPic Command

andpic.png

Command Summary

Logically "ands" a picture variable and the graph screen at [row, column]

Command Syntax

AndPic picVar,[row, column]

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

The AndPic command logically takes the picture variable specified, and takes the current graph, and it finds the points at which both the graph and the picture have pixels, and it displays them only. If specified, [row,column] tells where the top left corner of the picture is to be placed. If not specified, the default is (0,0), which is the top left corner of the screen.

Error Conditions

260 - Domain error happens when the [row,column] argument is outside the screen range..

960 - Undefined variable happens when the picture variable specified does not exist..

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:andpic


The angle( Command
ANGLE.GIF

Command Summary

Returns the complex argument of a complex number.

Command Syntax

angle(z)

Menu Location

Press:

  1. MATH to access the math menu.
  2. RIGHT, RIGHT to access the CPX (complex) submenu
  3. 4 to select angle(, or use arrows.

Calculator Compatibility

TI-83/84/+/SE/CSE/CE

Token Size

2 bytes

angle(z) returns the complex argument (also known as the polar angle) of the complex number z. If z is represented as x+iy where x and y are both real, angle(z) returns R►Pθ(x,y) (which is equivalent to tanֿ¹(y/x) if x is nonzero). Also works on a list of complex numbers.

angle(3+4i)
     .927295218
R►Pθ(3,4)
     .927295218

When writing a complex number z in the form $re^{i\theta}$ (or, equivalently, $r(\cos\theta+i\sin\theta)$), then $\theta$ is equal to the value of angle(z), suitably reduced so that the result returned is in the interval $-\pi<\theta\leq\pi$.

The angle( command also works on matrices, though not in any useful way: angle([A] will return a matrix of the same size as [A], but with all elements 0. If you plan to use this, don't: 0[A] does the same thing, but is smaller and not as questionable (because this behavior is clearly unintentional on TI's part, and may be changed in an OS update).

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/angle


The ANOVA( Command
ANOVA.GIF

Command Summary

Performs a one way ANOVA (analysis of variance) test to compare the means of multiple populations (up to 20).

Command Syntax

ANOVA(list, list, …

Menu Location

Press:

  1. STAT to access the statistics menu
  2. LEFT to access the TESTS submenu
  3. ALPHA F to select ANOVA(, or use arrows

Change the last keypress to ALPHA H on a TI-84+/SE with OS 2.30 or higher.

Calculator Compatibility

TI-83/84/+/SE/CSE/CE

Token Size

2 bytes

The ANOVA (analysis of variance) command is used to test if there is a significant difference between the means of several populations (this is an extension of the two-sample t-test which compares only two populations). The calculator assumes the null hypothesis, that all means are equal, and returns a probability value, p, of the differences in the data occurring if the null hypothesis were true. If p is small (usually, if it's less than .05), then it's unlikely we'd get such differences just by chance if the null hypothesis were true, so we reject it and conclude that at least one of the means is different.

There are two reasons why we don't test the means in pairs using a simpler test. First of all, it would take a long time: there's so many pairs to compare. Second of all, when you're doing many tests, there's a high probability you'll get a low p-value by chance. Imagine that you're doing 10 tests. If the probability of getting a low p-value on one test is .05, then the probability that at least one test will return one is 1-.9510: about 0.4 - this is quite likely to happen. The ANOVA test avoids this by having only one null hypothesis to test.

If you're only interested in the result of the test, the only thing you'll need in the output is the second line: "p=…" This is your p-value, and determines whether you should reject the null hypothesis or not. If you need more detail, here are the meanings of the other variables:

  • F is the test statistic. If the null hypothesis is true, it should follow Snedecor's F distribution, and Fcdf( can be used to determine the p-value.
  • For both Factor and Error:
    • MS is the mean squares (SS/df). If the null hypothesis is true, Factor MS should be roughly equal to Error MS
    • SS is the sum of squares - see the TI-83+ Manual for formulas
    • df is the number of degrees of freedom - for Factor, it's the df between the categorical variables, and for Error, it's the sum of df between each variable.
  • Sxp is the pooled variation.

Advanced Uses

The statistics F, p, and Sxp will be stored to the appropriate variables after this test. The other six statistics do not have a normal variable associated with them. However, the two-byte tokens 0x6237 through 0x623C are, in fact, used to store the values of Factor MS, Factor SS, Factor df, Error MS, Error SS, and Error df respectively. They can't be accessed through a menu, but if you use a hex editor to paste them into your program, you will be able to use them just like any other variable.

However, be careful because the Factor and Error tokens look exactly alike (even though they refer to different variables), and can be confused. Also, there is a chance that future OS versions will change the behavior of ANOVA(, though this is unlikely, and this trick will no longer work.

Error Conditions

  • ERR:ARGUMENT is thrown if one of the lists is blank, only one list is used, or the function is completely blank.
  • ERR:SYNTAX is thrown if you do not use lists (Matrixes, numbers,etc)
  • * ERR:INVALID DIM is thrown if you use a list that has 0 or a negative number.
  • * ERR:DATA TYPE is thrown by using "l" or a list with a different set of data.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/anova


The Ans Variable
ANS.GIF

Command Summary

Returns the last answer.

Command Syntax

Ans[→Variable]

Menu Location

While editing a program, press [2nd] then [(-)]

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The Ans variable holds the last answer that was stored in the calculator. Because Ans is stored in a special storage area built-in to the calculator, and it is extensively used by the calculator, you cannot delete it. Ans is also useful; it can make your programs both smaller and faster:

  • Unlike other variables which have a value type hard-coded in (i.e., a string can only hold text, and lists and matrices can only hold numbers), Ans can take on whatever value you want: a real or complex, list, matrix, or string are all acceptable.
  • Along with the finance variables, Ans is faster than the real, complex, list, matrix, and string variables; and subsequently, you should try to use it as much as possible.

One of the most common places to use Ans is in place of storing a value to a variable. Just paste the Ans variable to the location where the variable was called, and then when the expression is evaluated, the calculator will use the current value of Ans. Using the Ans variable allows you to eliminate the variable, which helps save a little or a lot of memory (depending on the type of variable and its size).

Instead of:

30+5A→B
Disp 25A,B

A shorter version would be:

30+5A
Disp 25A,Ans

(Since the Ans token is only 1 byte, you've just saved two bytes. In longer programs the savings can add up!)

The one major drawback to using Ans is that its current value is only temporary.

What commands modify Ans?

Whenever you:

  • Store a value to a variable, such as 1→X
  • Place an expression or string on a line by itself, such as 1+2 or "Hello"
  • Use the optional argument of the Pause command such as Pause X. Ans will be updated to the new value.

If you're performing multiple calculations across multiple variables, you might be better off storing each in a separate variable.

What commands do NOT modify Ans?

There are several cases in which changing the value of a variable does not modify Ans, thus preserving its current value for later use:

  • Asking a user for input via Prompt X or Input "X:",X
  • Using DelVar to delete a variable (i.e. set its value to zero, if it's a real variable)

Also most other commands that do not modify variables will preserve Ans, including:

  • ClrHome
  • If … Then … Else … End
  • Disp
  • Output()
  • Repeat
  • While
  • Lbl
  • Goto
  • Menu()
  • Pause (when there's no parameter following it, otherwise the parameter will be stored in Ans!)

Knowing these cases can be very useful, allowing you to make efficient use of Ans to store a result and re-use it in later lines rather than create a temporary variable for it.

Using Ans with Lists

Ans can be used to store lists and access individual items. Take the following example:

10→A
{11,22,33}
Disp Ans(1),Ans(2)

In this example, the calculator is smart enough to know that Ans is currently holding a list, and so will interpret the (1) and (2) as accessing items from the list. As such it will display 11 and 22. Trying to access Ans(4) will display an error.

However if we removed line 2 from the code above, Ans would instead be holding the value 10, and as such Ans would be multiplied by 1 and 2, resulting in 10 and 20.

The augment() function can also be used with Ans to add additional items to your list, for example:

{1,2}
augment(Ans,{3,4})
Disp Ans

This will display {1 2 3 4}

Timing

Storing a real value into Ans takes approximately 1.0 ms. This does not include the time needed to compute or retrieve the value, which may be significant.

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/ans


The approx() Command

approx.png

Command Summary

Gives a decimal approximation of an expression.

Command Syntax

approx(expression)

Menu Location

While on the home screen:

  • Press F2 to enter the Algebra menu.
  • Press 5 to paste approx(.

Calculator Compatibility

This command works on all calculators.

Token Size

7 bytes

The approx() command forces an expression to be evaluated in approximate mode, temporarily ignoring the mode setting. It's equivalent to pressing ♦ and ENTER when performing a calculation on the home screen.

:approx(π)
           3.14159265359

When applied to a complicated expression, matrix, or list, it approximates every number that occurs there.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:approx


The Archive Command
ARCHIVE.GIF

Command Summary

Moves a variable from RAM to the archive.

Command Syntax

Archive variable

Menu Location

Press:

  1. 2nd MEM to access the memory menu
  2. 5 to select Archive, or use arrows

Calculator Compatibility

TI-83+/84+/SE

(not available on the regular TI-83)

Token Size

2 bytes

The Archive command moves a variable from RAM to the archive (also known as ROM). A quick synopsis of the difference between the two:

  • Data in the archive cannot be accessed, but it's protected from RAM clears (which may occur during battery removal if not done carefully); also, the archive can hold much more data.
  • Data in RAM can be accessed for calculations, but it can also be deleted during a RAM clear or accidentally overwritten by another program.

Nothing happens if the variable in question is already archived.

You might want to use this command to protect data such as saved games from being accidentally deleted. It's not, in general, a good idea to archive commonly used variables, such as the real variables A-Z, since programs usually expect to be able to access these variables without problems, and won't check if they're archived.

Also, some variables cannot be archived. These include:

  • The real variables R, T, X, Y, θ, and n (due to their use in graphing)
  • The equation variables Yn, XnT, YnT, rn, u, v, and w
  • The stat plots Plot#
  • Window, table, and zoom variables such as TblInput or Xmin
  • Statistical variables and the list ∟RESID
  • Finance variables

Finally, the Archive command does not work on programs when using it from a program (it does, however, archive programs from the home screen). However, an assembly program can be executed as a subroutine so that Archive and UnArchive can be used within a program. The program should however be run again afterwards.

Advanced Uses

As archived variables (and programs) can not be accessed by the calculator's inbuilt OS, archiving programs can be quite problematic when trying to execute them. However; by enabling your programs to be viewable in assembly shells, you can execute your programs without needing to unarchive them first. This is because the assembly shell copies the program to the RAM automatically, and is then executed. Closing the program will automatically remove the copy from the RAM, so no RAM is lost in the end.

Error Conditions

  • ERR:ARCHIVE FULL is thrown when there isn't enough space in the archive for the variable.
  • ERR:INVALID is thrown when trying to archive a program from within a program.
  • ERR:VARIABLE is thrown when trying to archive a variable that cannot be archived.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/archive


The Archive Command

archive.png

Command Summary

Moves a variable from RAM to the archive.

Command Syntax

Archive variable, [another, …]

Menu Location

Starting in the program editor:

  • Press F4 to enter the Var menu.
  • Press 8 to select Archive.

Calculator Compatibility

This command works on all calculators.

Token Size

3 bytes

The Archive command moves a variable, or several variables, from RAM to the archive. This serves two purposes:

  • More RAM is now available for other variables.
  • The variable is protected from being edited or deleted.

On the 68k series of calculators, a variable in the archive can still be read (compare this to the behavior of TI-83 series calculators, where doing anything at all to an archived variable is forbidden). However, trying to store anything to the variable will give an error: it must be unarchived first.

Variables in the archive are also protected from being deleted. This means that a DelVar command called on it will cause an error. Commands such as NewProb or DelType that delete multiple variables will skip over any that are archived. Finally, in the event of a RAM clear (which is more likely to happen by accident than a total memory clear), archived variables will be preserved.

Any type of variable can be archived. However, you cannot archive system variables (such as xmin) or variables beginning with _.

Advanced Uses

It seems natural to archive programs, since they usually aren't written to, and they are valuable enough that you want to give them some protection. However, keep in mind that the first time you run a program after editing it, it gets tokenized — the text is converted into tokens that stand in for commands. The process might take several seconds.

If you edit a program and then immediately archive it, it is "protected" from this conversion process. That means that every time you run the program, it will be tokenized. To avoid this, run the program once to tokenize it, and then archive it.

Error Conditions

140 - Argument must be a variable name happens when archiving a system variable or an invalid variable name.

870 - Reserved name or system variable happens when archiving a variable starting with _.

960 - Undefined variable happens when archiving an undefined variable.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:archive


The arcLen() Command

arclen.png

Command Summary

Returns the arc length of expression1 from start to end with respect to variable var.

Command Syntax

arcLen(expression1,var,start,end)

Menu Location

Describe how to get the command from a menu.

Calculator Compatibility

This command works on all calculators.

Token Size

X byte(s)

The arcLen() command uses the integral arc length formula to calculate the arc length of a function over the specified interval.

arcLen(cos(x),x,0,π)
                              3.82019...

Advanced Uses

The arcLen() command also works on lists of expressions:

arcLen({sin(x),cos(x)},x,0,π)
                         {3.820...  3.810...}

Separate unrelated advanced uses with a horizontal bar.

Optimization

This section includes both ways to optimize use of the command, and other common pieces of code that this command can replace in an optimization. Make sure to mention if the optimization improves speed of the program, size, or both. Sample code should be included too, preferably in the following format:

:∫(√(1+d(f(x),x)²),x,a,b)
can be
:arcLen(f(x),x,a,b)

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:arclen


The Asm( Command
ASM.GIF

Command Summary

Runs an assembly program.

Command Syntax

Asm(prgmNAME)

Menu Location

This command is only found in the catalog. Press:

  1. 2nd CATALOG to access the command catalog.
  2. DOWN six times.
  3. ENTER to select Asm(.

Calculator Compatibility

TI-83+/84+/SE

(not available on the regular TI-83)

Token Size

2 bytes

The Asm( command is used for running an assembly program. Unlike TI-Basic programs, assembly programs are written in the calculator's machine code directly, which makes them more powerful in both speed and functionality. However, it also means that if they crash, they crash hard — there is no built-in error menu to protect you.

Keep in mind that many assembly programs these days are written for a shell such as Ion or MirageOS. If you're dealing with one of those programs, calling Asm( on it will do nothing; you need to get the appropriate shell and run that instead.

With the AsmPrgm and AsmComp( commands, you can create small assembly programs yourself, directly on the calculator. If you are using at TI-84+CE with OS 5.3, the Asm( is unnecessary to run such programs.

Error Conditions

  • ERR:INVALID is thrown if the program isn't an assembly program.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/asm-command


The AsmComp( Command
ASMCOMP.GIF

Command Summary

Compresses an assembly program in hexadecimal form into binary form.

Command Syntax

Asm(prgmORIGINAL,prgmRESULT)

Menu Location

This command is only found in the catalog. Press:

  1. 2nd CATALOG to access the command catalog.
  2. Scroll down to AsmComp( and press enter.

Calculator Compatibility

TI-83+/84+/SE/CSE/CE

(not available on the regular TI-83)

Token Size

2 bytes

This command is used to compress an assembly program written using AsmPrgm into an "assembled" assembly program. This will make the program about twice as small, and protect it from being edited, in addition to making execution faster.

To use AsmComp(, give it the ASCII represented assembly program, followed by the name you want the assembled program to have. That name can't be already taken. Since it's not easy to rename an assembled assembly program, if you want to write a program called prgmGAME, you type the ASCII represented code in a program with a different name (e.g. GAMEA) and then do AsmComp((prgmGAMEA,prgmGAME).

Assembly programs can be run with Asm(.

Error Conditions

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/asmcomp


The AsmPrgm Command
ASMPRGM.GIF

Command Summary

This command must be the beginning of an assembly program.

Command Syntax

AsmPrgm

Menu Location

This command is only found in the catalog. Press:

  1. 2nd CATALOG to access the command catalog.
  2. Scroll down to AsmPrgm and press ENTER.

Calculator Compatibility

TI-83+/84+/SE/CSE/CE

(not available on the regular TI-83)

Token Size

2 bytes

This command denotes the start of an assembly program in hexadecimal form. The command must go at the beginning of a program.

Using AsmPrgm is the only built-in way to create assembly programs on the calculator, and it's not very convenient. To use it, after AsmPrgm itself, you must type in the hexadecimal values (using the numbers 0-9, and the letters A-F) of every byte of the assembly program. Even for assembly programmers, this is a complicated process: unless you've memorized the hexadecimal value of every assembly command (which is about as easy as memorizing the hexadecimal value of every TI-Basic token) you have to look every command up in a table.

In addition, it's easy to make a typo while doing this. For this reason, it's recommended not to use AsmPrgm to write assembly programs on the calculator, but instead write assembly programs on the computer. This also lets you use emulators and debuggers and such, as opposed to crashing your calculator (possibly permanently) every time you have a bug.

Just about the only use for AsmPrgm is to enter the hex codes for simple assembly routines that can be called from Basic programs or used for some other short task. For example, the following program will allow you to type in lowercase letters (by pressing ALPHA twice, you go into lowercase letter mode):

AsmPrgmFDCB24DEC9

To use this, create a program, and enter the code above into it. Then run the program using Asm(. Voila! Lowercase letters are now enabled.

More such short programs can be found here.

TI-84+ Color Calculators

For the TI-84+ C series of calculators, AsmPrgm has been replaced by two new commands: AsmPrgm84C for the TI-84+ CSE and AsmPrgmCE for the TI-84+ CE. The commands function in the exact same manner as the original AsmPrgm command. However, it is important to note that sending assembly programs between a CSE and CE (or vice versa) may cause errors due to a difference in commands.

Many of the hex codes involving AsmPrgm also no longer function correctly on C series calculators. The updated hex codes can be found here. Please note, however, that directly entering hex codes has been disabled on the CE with OS 5.3.1; attempting to view AsmPrgmCE in the catalog will show the command crossed-out. Hex codes can be still be run from older programs.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/asmprgm


The augment( Command
AUGMENT.GIF

Command Summary

Combines two lists or matrices into one. In the case of matrices, this is done horizontally rather than vertically.

Command Syntax

augment(list1,list2

augment(matrix1,matrix2

Menu Location

Press:

  1. 2nd LIST to access the List menu
  2. RIGHT to access the OPS submenu
  3. 9 to select augment(, or use arrows

Alternatively, press:

  1. MATRX (on the TI-83) or 2nd MATRX (TI-83+ or higher) to access the Matrix menu
  2. RIGHT to access the MATH submenu
  3. 7 to select augment(, or use arrows

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The augment( command is used to combine two lists or two matrices into one. For lists, this is done the obvious way: adding the elements of the second on to the elements of the first. For example:

augment({1,2,3,4},{5,6,7
    {1 2 3 4 5 6 7}

The lists must have at least one value. If you attempt to augment(L₁,L₂) and either of the lists are empty, you will receive an error. If you're using this within a program, you may want to use dim() to check the size before performing an augment.

For matrices, the columns of the second matrix are added after the columns of the first matrix: an R by C matrix augmented with an R by D matrix will result in an R by (C+D) matrix. For example:

augment([[1][2]],[[3][4]
    [[1 3]
     [2 4]]

Combining 3 or more lists

The augment() command only accepts two parameters. If you need to combine 3 or more lists, you can nest the augment calls.

This will NOT work:  augment(L₁,L₂,L₃)
But this will:       augment(augment(L₁,L₂),L₃)

Just be sure that all lists have at least 1 value to prevent errors.

Advanced Uses

Use the T (transpose) command if you want to combine two matrices vertically, rather than horizontally. For example:

augment([[1,2]]T,[[3,4]]T)T
    [[1 2]
     [3 4]]

Optimization

You may be tempted to use augment( to add one element to the end of a list:

augment(L1,{X→L1

However, the following way is faster and more memory-efficient while the program is running (although it increases the program's size):

X→L1(1+dim(L1

Error Conditions

  • ERR:DATA TYPE is thrown if you try to augment a single number to a list, a common error — use {X instead of X.
  • ERR:DIM MISMATCH is thrown if you try to augment two matrices with a different number of rows.
  • ERR:INVALID DIM is thrown if one of the arguments is a list with dimension 0, or if the result would have dimension over 999 (for lists) or 99x99 (for matrices).

Related Commands

  • dim( – for retrieving the size of a list
  • seq( – for creating a list based on a formula, or to create a subset of an existing list
  • T – to transpose a 2D matrix

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/augment


The AUTO Answer Command

Command Summary

Mode command that sets Answers to AUTO.

Command Syntax

AUTO Answer

Menu Location

Press:

  1. MODE
  2. DOWN until you see Answers
  3. ENTER on AUTO

Alternatively, access the catalog.

Calculator Compatibility

TI-84 2.53MP only

Token Size

2 bytes

The AUTO Answer command is a mode command that changes the Answers mode to AUTO. The AUTO mode is in essence the same mode that lower OS models use. The calculator will evaluate a numerical expression and return a decimal or number in scientific notation, unless ►Frac is used.

In the Mathprint mode, no noticeable difference is seen unless the answer is converted to a fraction.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/auto-answer


The AxesOff Command
AXESOFF.GIF

Command Summary

Disables the X- and Y- axes on the graph screen.

Command Syntax

AxesOff

Menu Location

Press:

  1. 2nd FORMAT to access the format menu.
  2. Use arrows and ENTER to select AxesOff.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The AxesOff command disables the X and Y axes on the graph screen, so that they aren't drawn. They can be enabled again with the AxesOn command.

(the y=x line that is drawn when both Seq and Web modes are enabled is also controlled by this command)

Generally, the AxesOff command should be used at the beginning of the program to disable the axes if the program is going to use the graph screen, since the axes get in the way. However, you should consider using StoreGDB and RecallGDB to save this setting if that's the case.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/axesoff


The AxesOn Command
AXESON.GIF

Command Summary

Enables the X- and Y- axes on the graph screen.

Command Syntax

AxesOn

Menu Location

Press:

  1. 2nd FORMAT to access the format menu.
  2. Use arrows and ENTER to select AxesOn.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The AxesOn command enables the X and Y axes on the graph screen, so that they are drawn. They can be disabled with the AxesOff command.

(the y=x line that is drawn when both Seq and Web modes are enabled is also controlled by this command)

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/axeson


The bal( Command
BAL.GIF

Command Summary

Calculates the remaining balance after n payments in an amortization schedule.

Command Syntax

bal(n,[roundvalue]

Menu Location

On the TI-83, press:

  1. 2nd FINANCE to access the finance menu.
  2. 9 to select bal(, or use arrows and ENTER.

On the TI-83+ or higher, press:

  1. APPS to access the applications menu.
  2. 1 or ENTER to select Finance…
  3. 9 to select bal(, or use arrows and ENTER.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The bal( command calculates the remaining balance after n payments in an amortization schedule. It has only one required argument: n, the payment number. However, it also uses the values of the finance variables PV, PMT, and I% in its calculations.

The optional argument, roundvalue, is the number of digits to which the calculator will round all internal calculations. Since this rounding affects further steps, this isn't the same as using round( to round the result of bal( to the same number of digits.

Usually, you will know the values of N, PV, and I%, but not PMT. This means you'll have to use the finance solver to solve for PMT before calculating bal(); virtually always, FV will equal 0.

Sample Problem

Imagine that you have taken out a 30-year fixed-rate mortgage. The loan amount is $100000, and the annual interest rate (APR) is 8%. Payments will be made monthly. After 15 years, what amount is still left to pay?

We know the values of N, I%, and PV, though we still need to convert them to monthly values (since payments are made monthly). N is 30*12, and I% is 8/12. PV is just 100000.

Now, we use the finance solver to solve for PMT. Since you intend to pay out the entire loan, FV is 0. Using either the interactive TVM solver, or the tvm_Pmt command, we get a value of about -$733.76 for PMT.

We are ready to use bal(. We are interested in the payment made after 15 years; this is the 15*12=180th payment. bal(180) gives us the result $76781.55 — as you can see, most of the loan amount is still left to pay after 15 years.

Formulas

The calculator uses a recursive formula to calculate bal():

(1)
\begin{align} \operatorname{bal}(0)=\operatorname{PV} \end{align}
(2)
\begin{align} \operatorname{bal}(m)=\left(1-\frac{I\%}{100}\right)\operatorname{bal}(m-1)+\operatorname{PMT} \end{align}

In the case that roundvalue is given as an argument, the rounding is done at each step of the recurrence (which virtually forces us to use this formula). Otherwise, if no rounding is done (and assuming I% is not 0), we can solve the recurrence relation to get:

(3)
\begin{align} \operatorname{bal}(m)=\frac{1-\left(1-\frac{I\%}{100}\right)^m}{\frac{I\%}{100}}\operatorname{PMT}+\left(1-\frac{I\%}{100}\right)^m\operatorname{PV} \end{align}

Error Conditions

  • ERR:DOMAIN is thrown if the payment number is negative or a decimal.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/bal


The binomcdf( Command
BINOMCDF.GIF

Command Summary

Calculates the binomial cumulative probability, either at a single value or for all values

Command Syntax

for a single value:
binomcdf(trials, probability, value

for a list of all values (0 to trials)
binomcdf(trials, probability

Menu Location

Press:

  1. 2ND DISTR to access the distribution menu
  2. ALPHA A to select binomcdf(, or use arrows.

Press ALPHA B instead of ALPHA A on a TI-84+/SE with OS 2.30 or higher.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

This command is used to calculate the binomial cumulative probability function. In plainer language, it solves a specific type of often-encountered probability problem, that occurs under the following conditions:

  1. A specific event has only two outcomes, which we will call "success" and "failure"
  2. This event is going to repeat a specific number of times, or "trials"
  3. Success or failure is determined randomly with the same probability of success each time the event occurs
  4. We're interested in the probability that there are at most N successes

For example, consider a couple that intends to have 4 children. What is the probability that at most 2 are girls?

  1. The event here is a child being born. It has two outcomes "boy" or "girl". In this case, since the question is about girls, it's easier to call "girl" a success.
  2. The event is going to repeat 4 times, so we have 4 trials
  3. The probability of a girl being born is 50% or 1/2 each time
  4. We're interested in the probability that there are at most 2 successes (2 girls)

The syntax here is binomcdf(trials, probability, value). In this case:

:binomcdf(4,.5,2

This will give .6875 when you run it, so there's a .6875 probability out of 4 children, at most 2 will be girls.

An alternate syntax for binomcdf( leaves off the last argument, value. This tells the calculator to compute a list of the results for all values. For example:

:binomcdf(4,.5

This will come to {.0625 .3125 .6875 .9375 1} when you run it. These are all the probabilities we get when you replace "at most 2 girls" with "at most 0", "at most 1", etc. Here, .0625 is the probability of "at most 0" girls (or just 0 girls), .3125 is the probability of at most 1 girl (1 or 0 girls), etc.

Several other probability problems actually are the same as this one. For example, "less than N" girls, just means "at most N-1" girls. "At least N" girls means "at most (total-N)" boys (here we switch our definition of what a success is). "No more than", of course, means the same as "at most".

Advanced (for programmers)

The binompdf( and binomcdf( commands are the only ones apart from seq( that can return a list of a given length, and they do it much more quickly. It therefore makes sense, in some situations, to use these commands as substitutes for seq(.

Here's how to do it:

  1. cumSum(binomcdf(N,0 gives the list {1 2 … N+1}, and cumSum(not(binompdf(N,0 gives the list {0 1 2 … N}.
  2. With seq(, you normally do math inside the list: seq(3I2,I,0,5
  3. With these commands, you do the same math outside the list: 3Ans2 where Ans is the list {0 1 … 5}.
:seq(2^I,I,1,5
can be
:cumSum(binomcdf(4,0
:2^Ans
which in turn can be
:2^cumSum(binomcdf(4,0

In general (where f() is some operation or even several operations):

:seq(f(I),I,1,N
can be
:cumSum(binomcdf(N-1,0
:f(Ans
which can sometimes be
:f(cumSum(binomcdf(N-1,0

If the lower bound on I in the seq( statement is 0 and not 1, you can use binompdf( instead:

:seq(f(I),I,0,N
can be
:cumSum(not(binompdf(N,0
:f(Ans
which can sometimes be
:f(cumSum(not(binompdf(N,0

This will not work if some command inside seq( can take only a number and not a list as an argument. For example, seq(L1(I),I,1,5 cannot be optimized this way.

Formulas

Since "at most N" is equivalent to "0 or 1 or 2 or 3 or … N", and since we can combine these probabilities by adding them, we can come up with an expression for binomcdf( by adding up values of binompdf(:

(1)
\begin{align} \operatorname{binomcdf}(n,p,k) = \sum_{i=0}^{k}\operatorname{binompdf}(n,p,i) = \sum_{i=0}^{k}\binom{n}{i}\,p^i\,(1-p)^{n-i} \end{align}

(If you're not familiar with sigma notation, $\sum_{i=0}^{k}$ just means "add the following up for each value of i 0 through k")

Error Conditions

  • ERR:DATATYPE is thrown if you try to generate a list of probabilities with p equal to 0 or 1, and at least 257 trials.
  • ERR:DOMAIN is thrown if the number of trials is at least 1 000 000 (unless the other arguments make the problem trivial).
  • ERR:INVALID DIM is thrown if you try to generate a list of probabilities with at least 999 trials.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/binomcdf


The binompdf( Command
BINOMPDF.GIF

Command Summary

Calculates the binomial probability, either at a single value or for all values

Command Syntax

for a single value:
binompdf(trials, probability, value

for a list of all values (0 to trials)
binompdf(trials, probability

Menu Location

Press:

  1. 2ND DISTR to access the distribution menu
  2. 0 to select binompdf(, or use arrows.

Press ALPHA A instead of 0 on a TI-84+/SE with OS 2.30 or higher.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

This command is used to calculate the binomial probability. In plainer language, it solves a specific type of often-encountered probability problem, that occurs under the following conditions:

  1. A specific event has only two outcomes, which we will call "success" and "failure"
  2. This event is going to repeat a specific number of times, or "trials"
  3. Success or failure is determined randomly with the same probability of success each time the event occurs
  4. We're interested in the probability that there are exactly N successes

For example, consider a couple that intends to have 4 children. What is the probability that 3 of them are girls?

  1. The event here is a child being born. It has two outcomes "boy" or "girl". We can call either one a success, but we'll choose to be sexist towards guys and call a girl a success in this problem
  2. The event is going to repeat 4 times, so we have 4 trials
  3. The probability of a girl being born is 50% or 1/2 each time
  4. We're interested in the probability that there are exactly 3 successes (3 girls)

The syntax here is binompdf(trials, probability, value). In this case:

:binompdf(4,.5,3

This will give .25 when you run it, so there's a .25 (1/4) probability out of 4 children, 3 will be girls.

An alternate syntax for binompdf( leaves off the last argument, value. This tells the calculator to compute a list of the results for all values. For example:

:binompdf(4,.5

This will come to {.0625 .25 .375 .25 .0625} when you run it. These are the probabilities of all 5 outcomes (0 through 4 girls) for 4 children with an equal probability of being born. There's a .0625 probability of no girls, a .25 probability of 1 girl, etc.

Advanced (for programmers)

The binompdf( and binomcdf( commands are the only ones apart from seq( that can return a list of a given length, and they do it much more quickly. It therefore makes sense, in some situations, to use these commands as substitutes for seq(.

Here's how to do it:

  1. cumSum(binomcdf(N,0 gives the list {1 2 … N+1}, and cumSum(not(binompdf(N,0 gives the list {0 1 2 … N}.
  2. With seq(, you normally do math inside the list: for example, seq(3I2,I,0,5
  3. With these commands, you do the same math outside the list: 3Ans2 where Ans is the list {0 1 … 5}.

An example:

:seq(2^I,I,1,5
can be
:cumSum(binomcdf(4,0
:2^Ans
which in turn can be
:2^cumSum(binomcdf(4,0

In general (where f() is some operation or even several operations):

:seq(f(I),I,1,N
can be
:cumSum(binomcdf(N-1,0
:f(Ans
which can sometimes be
:f(cumSum(binomcdf(N-1,0

If the lower bound on I in the seq( statement is 0 and not 1, you can use binompdf( instead:

:seq(f(I),I,0,N
can be
:cumSum(not(binompdf(N,0
:f(Ans
which can sometimes be
:f(cumSum(not(binompdf(N,0

This will not work if some command inside seq( can take only a number and not a list as an argument. For example, seq(L1(I),I,1,5 cannot be optimized this way.

Formulas

The value of binompdf( is given by the formula

(1)
\begin{align} \operatorname{binompdf}(n,p,k) = \binom{n}{k}\,p^k\,(1-p)^{n-k} = \frac{n!}{k!\,(n-k)!}\,p^k\,(1-p)^{n-k} \end{align}

This formula is fairly intuitive. We want to know the probability that out of n trials, exactly k will be successes, so we take the probability of k successes - $p^k$ - multiplied by the probability of (n-k) failures - $(1-p)^{n-k}$ - multiplied by the number of ways to choose which k trials will be successes - $\binom{n}{k}$.

Error Conditions

  • ERR:DOMAIN is thrown if the number of trials is at least 1 000 000 (unless the other arguments make the problem trivial).
  • ERR:INVALID DIM is thrown if you try to generate a list of probabilities with at least 999 trials.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/binompdf


The ceiling() Command

ceiling.png

Command Summary

Returns the ceiling of a number.

Command Syntax

ceiling(value)

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press 1 to enter the Number submenu.
  • Press 7 to select ceiling(.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The ceiling() command rounds a number up to the nearest integer at least as large as the number. For instance, ceiling(π) returns 4, while ceiling(-π) returns -3.

There are several commands available to round a number to an integer in slightly different ways:

  • int() and floor() — like ceiling(), but round down instead.
  • iPart() — truncates a number to just its integer part (or, if you prefer, rounds a number toward 0).
  • round() — rounds to a specific place value, not just to an integer, but round(x,0) will round x to the nearest integer, up or down.

ceiling() can also be applied to complex numbers, lists, and matrices, rounding everything that there is to round in each of them.

:ceiling(3)
           3
:ceiling({-π,π})
           {-3  4}

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:ceiling


The char() Command

char.png

Command Summary

Returns a character given its ASCII code.

Command Syntax

char(code)

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press D to enter the String submenu.
  • Press A to paste char(.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

The char() command converts an integer between 0 and 255 to the corresponding character in the calculator's internal code (which is a modification of ASCII). It can also operate on a list or matrix by converting each of their elements to a character.

This command, and its inverse ord(), can be useful for programs that deal with arbitrary strings (which could, potentially, contain any character), but they can come up in other cases as well. For example, since the letters A..Z are consecutive characters in the calculator's internal code, with A being char(65), you can calculate the nth letter in the alphabet with the expression char(n+64).

There are two special values of char() to be aware of. The character given by char(0) is actually the empty string, which you usually want to avoid using; the character given by char(13) is a newline "enter" character, which is replaced by ":" when you type it somewhere. If you actually want to store char(13) to a string, you have to use the char() command.

Advanced Uses

TI-Basic does not allow lists to contain picture variables, and in many cases (such as tilemaps) you want to get around this limitation. One way to do so is to name the variables "tile1", "tile2", "tile3", and so on, with only the number changing — then #("tile"&string(n)) gives the nth picture variable.

A more efficient way is to assign the pictures numbers in a different range, such as 65-90, and name the variables "tilea", "tileb", "tilec", etc. Then, #("tile"&char(n)), which is faster, converts a number to the corresponding picture variable. This allows for a maximum of 146 different tiles, if you use all the characters that could conceivably be part of a variable name.

Error Conditions

260 - Domain error happens when the character code isn't in the range 0..255.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:char


The checkTmr() Command

checktmr.png

Command Summary

Checks the value of the system clock.

Command Syntax

checkTmr(time)

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command requires a calculator with AMS version 2.07 or higher (it will also work on any TI-89 Titanium or Voyage 200 calculator)

Token Size

2 bytes

The checkTmr() command, together with startTmr() uses the built-in system clock to measure the time (in seconds) that passed between two points of the program. Make sure that the clock is on (with ClockOn before using these).

The name of the commands reflects their use: you can think of a startTmr() call as creating and starting a timer:

:startTmr()→timer

The checkTmr() command will then return the number of seconds that have elapsed on the timer (without stopping it):

:Disp "Seconds elapsed:",checkTmr(timer)

This is a good abstraction and you don't need to know the details of how startTmr() and checkTmr() work to use them. In reality, what startTmr() actually returns is the current value of a system timer (which increases by 1 every second). The checkTmr() command does the same thing, but subtracts its parameter: so checkTmr(x) is equivalent to startTmr()-x.

Because both startTmr() and checkTmr() deal with whole numbers of seconds, the resulting difference in time could be off by up to a second in either direction. That is, if checkTmr() gives 15 seconds as the time, you know the time that actually passed is between 14 and 16 seconds.

Advanced Uses

The startTmr() and checkTmr() commands can be used to figure out how much time a command or routine takes with much greater precisions by running it multiple times. For example:

:startTmr()→t
:For i,1,1000
: somecmd()
:Disp checkTmr(t)

Suppose that the result displayed was 100 seconds. This is accurate to 1 second, so the actual time was between 99 and 101 seconds. However, this actual time is for 1000 repetitions of somecmd() (we assume that the time the code takes to increment i is negligible, although that may also be taken into account). So somecmd() repeated only once takes between 99/1000 and 101/1000 seconds, so the actual time is 100 ms, measured to within 1 millisecond error.

See Code Timings for more information on this, as well as the results of some common comparisons.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:checktmr


The checkTmr( Command
CHECKTMR.GIF

Command Summary

Returns the number of seconds since the timer was started.

Command Syntax

checkTmr(Variable)

Menu Location

This command can only be found in the catalog. Press:

  1. 2nd CATALOG to enter the command catalog
  2. C to skip to command starting with C
  3. Scroll down to checkTmr( and select it

Calculator Compatibility

TI-84+/SE/CSE

Token Size

2 bytes

The checkTmr( command is used together with the startTmr command to determine how much time has elapsed since the timer was started on the TI-84+/SE calculators. In particular, it returns the number of seconds since the built-in timer was started. An application of these commands is timing different commands or pieces of code, as well as countdowns in games, or a time-based score (such as in Minesweeper).

To use the timer, you first store startTmr to a variable (usually, a real variable) whenever you want the count to start. Now, whenever you want to check the elapsed time, you can use checkTmr( with the variable from above, giving you the number of seconds that have passed. Using checkTmr( doesn't stop the timer, you can do it as many times as you want to.

In the case of Minesweeper, for example, you would store startTmr to, for example, T, after setting up and displaying the board, display the result of checkTmr(T) in the game's key-reading loop, and store checkTmr(T) to the player's score if he wins.

Advanced Uses

To time a command or routine using startTmr and checkTmr(, use the following template:

:ClockOn
:startTmr→T
:Repeat checkTmr(Ans
:End
:For(n,1,(number)                    //sequence variable n
   (command(s) to be tested)
:End
:checkTmr(T+1)/(number)

Making (number) higher increases accuracy, but takes longer. Also, make sure not to modify the variables n or T inside the For( loop.

While this method eliminates human error from counting, it's prone to its own faults. For example, startTmr and checkTmr( always return the time rounded down to a whole second. To take this into account, replace the last line:

:(checkTmr(T+{1,0})/(number)

When testing code, be aware that many different things affect the time: the strength of the batteries, the amount of free RAM, and including the closing parenthesis on the For( loop. The last one, in particular, has an impact when using a single-line If statement or one of the IS>( and DS<( commands on the first line inside a For( loop.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/checktmr


The Circle( Command
CIRCLE.GIF

Command Summary

Draws a circle.

Command Syntax

Circle(X,Y,r)

(83+ and higher only)
Circle(X,Y,r,{i})

(84+ CSE only)
Circle(X,Y,r

Menu Location

Press:

  1. Press [2ND] [PRGM] to enter the DRAW menu
  2. Press [9] to insert Circle(

Calculator Compatibility

TI-83/84/+/SE/CSE/CE

Token Size

1 byte

Circle(X,Y,r) will draw a circle at (X,Y) with radius r. X and Y will be affected by the window settings. The radius will also be affected by the window settings.

:Circle(5,5,5)

Advanced Uses

The radius of a circle is affected by the window settings. This means that if the x- and y-increment is two, the radius will be two pixels. However, there is another way to take advantage of this to draw ellipses. If the x- and y-increment are different, then the shape will not be a circle. For instance, with Xmin=0, Xmax=20, Ymin=0, and Ymax=31, Circle(10,10,2) will draw an ellipse, where the width is greater than the height.

Optimization

If a complex list such as {i} is passed to Circle( as the fourth argument, the "fast circle" routine is used instead, which uses the symmetries of the circle to only do 1/8 of the trig calculations. For example:

:Circle(0,0,5
can be
:Circle(0,0,5,{i

Any list of complex numbers will work as the fourth argument in the same way, but there's no benefit to using any other list.

Note: The "fast circle" routine is not available on the TI-84+CSE or TI-84+CE calculators.

Command Timings

The ordinary Circle( is extremely slow. The fast circle trick discussed above cuts the time down to only about 30% of the "slow Circle(" time! While still not instant, this is faster than any replacement routine that can be written in TI-Basic.

For small radii, replace Circle( with Pt-On( instead.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/circle


The CLASSIC Command

Command Summary

Mode command that puts the calculator into Classic mode.

Command Syntax

CLASSIC

Menu Location

Press:

  1. MODE
  2. DOWN until you reach MathPrint or Classic
  3. ENTER on Classic

Alternatively, use the catalog.

Calculator Compatibility

TI-84 2.53MP only

Token Size

2 bytes

CLASSIC will put the calculator into Classic mode as opposed to MathPrint mode. The Classic mode will make the calculator display everything as pre-MathPrint OS would, including input. For instance, rather than superscripting exponents as MathPrint mode would, Classic mode uses the simple caret syntax (^).

MathPrint mode:
24
     16

Classic mode:
2^4
     16

Advanced Uses

When in Classic mode, text and numbers are displayed much faster on the home screen and the function menus load faster. This can be useful in games that use the home screen, or just with calculations in general.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/classic-mode


The Clear Entries Command
CLEARENTRIES.GIF

Command Summary

Clears the history of commands previously entered on the homescreen.

Command Syntax

Clear Entries

Menu Location

Press:

  1. 2nd MEM to access the memory menu.
  2. 3 to select Clear Entries, or use arrows and ENTER.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

Normally, by pressing 2nd ENTER repeatedly, you can cycle through some of the recent entries on the home screen. With the Clear Entries command, this history is cleared (only Clear Entries remains in the history).

This can be used to free some memory, although it's recommended not to do this in a program (because clearing things without asking first isn't nice). Aside from that, maybe the only reason to use Clear Entries is to protect your privacy — although someone looking at your entries will know you cleared something, so it's not that effective.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/clear-entries


The ClockOff Command
CLOCKOFF.GIF

Command Summary

Turns off the clock display in the mode screen.

Command Syntax

ClockOff

Menu Location

This command can only be found in the catalog. Press:

  1. 2nd CATALOG to enter the command catalog
  2. C to skip to command starting with C
  3. Scroll down to ClockOff and select it

Calculator Compatibility

TI-84+/SE

Token Size

2 bytes

The ClockOff command turns off the clock display at the bottom of the mode screen on the TI-84+/SE calculators. You can turn the clock back on by using the ClockOn command, or by selecting 'TURN CLOCK ON' ,displayed in place of the clock on the mode screen.

The ClockOff command does not actually turn the clock off. The time can still be accessed through use of the getTime and getDate commands, and all their cousins.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/clockoff


The ClockOff Command

clockoff.png

Command Summary

Turns off the hardware clock.

Command Syntax

ClockOff

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command requires a calculator with AMS version 2.07 or higher (it will also work on any TI-89 Titanium or Voyage 200 calculator)

Token Size

2 bytes

The ClockOff Command turns off the calculator's clock as far as the time and date commands are concerned: that is, the timer used by startTmr(), getTime(), and other commands will not keep updating every second, but will stay the same until the clock is turned on again.

It's not usually a good idea to use this in a program: there's no real benefit to doing so (it doesn't make the calculator run faster or anything like that) but there's the real drawback that it throws off the calculator's time. However, the mere existence of this command means that you should probably use ClockOn anytime you need to use the time and date commands.

Since it modifies the global status of the calculator, ClockOff can't be used in a function.

Error Conditions

450 - Invalid in a function or current expression happens when ClockOff is used inside a function.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:clockoff


The ClockOn Command
CLOCKON.GIF

Command Summary

Turns on the clock display in the mode screen.

Command Syntax

ClockOn

Menu Location

This command can only be found in the catalog. Press:

  1. 2nd CATALOG to enter the command catalog
  2. C to skip to command starting with C
  3. Scroll down to ClockOn and select it

Calculator Compatibility

TI-84+/SE

Token Size

2 bytes

The ClockOn command turns on the clock display at the bottom of the mode screen on the TI-84+/SE calculators. Alternatively, you can scroll down to the 'TURN CLOCK ON' message that is displayed in place of the clock on the mode screen and press ENTER twice. You can turn the clock off by using the ClockOff command.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/clockon


The ClockOn Command

clockon.png

Command Summary

Turns on the hardware clock.

Command Syntax

ClockOn

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command requires a calculator with AMS version 2.07 or higher (it will also work on any TI-89 Titanium or Voyage 200 calculator)

Token Size

2 bytes

The ClockOn command turns on the calculator's clock, used by most time and date commands. Only when the clock is on, will the value returned by startTmr(), getTime(), and other commands actually change with the passage of time. If you write a program that uses any of these commands, be sure to include this command at the beginning of the program.

Since it modifies the global status of the calculator, ClockOn can't be used inside a function. If you're writing a function that depends on measuring time (so you need the clock to be on), the best thing you can do is use the isClkOn() command to check if the clock is on or off, and return an error message if it's off.

Error Conditions

450 - Invalid in a function or current expression happens when ClockOn is used in a function.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:clockon


The ClrAllLists Command
CLRALLLISTS.GIF

Command Summary

Sets the size of all defined lists to 0 (equivalent to applying the ClrList command to all defined lists).

Command Syntax

ClrAllLists

Menu Location

Press:

  1. 2nd MEM to access the Memory menu
  2. 4 to select ClrAllLists, or use arrows

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The ClrAllLists command sets the dimension (length) of all lists to zero. This is virtually equivalent to deleting the lists, except for two differences:

  • The lists still exist and will show up in the list menu and the memory management menu.
  • The dim( command will return 0 for a cleared list, rather than an error.

However, accessing a cleared list in any other way will return an error, just as for a deleted list.

The ClrAllLists command should never be used in a program you give to someone else or upload - unless the user is aware of this effect, they might lose important data stored in one of their lists. There is no way to limit the effect of ClrAllLists, so a program should use ClrList instead to avoid affecting unrelated lists (this is assuming you already want to use this questionably-useful effect).

Outside a program (or in a program for personal use), you might use this command to clear the contents of your lists to free up memory, while still not deleting the lists. This might possibly be convenient. Maybe.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/clralllists


The ClrDraw Command
CLRDRAW.GIF

Command Summary

Clears the graph screen, redrawing functions, plots, and axes/grid/labels, if applicable.

Command Syntax

ClrDraw

Menu Location

Press:

  1. 2nd PRGM to enter the DRAW menu
  2. 1 or ENTER to select ClrDraw

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The ClrDraw command is useful clearing away something drawn on the graph screen; in particular, you want to do this at the beginning of a program that uses the graph screen, to get rid of anything that might be on it initially. If there are functions, plots, axes, labels, or grid enabled, these will be redrawn even after you ClrDraw. If you don't want these, you should turn them off before the ClrDraw command.

Like many other drawing commands, if you're outside a program and on the graph screen, you can use this command directly, without going to the home screen. Just select ClrDraw from the menu, and the screen will be cleared immediately.

Advanced Uses

Unless the final state of the graph screen is the intended effect of the program, you want to use ClrDraw at the end of the program so that the user doesn't have to deal with it.

Caution: if the graph screen is displayed even before you execute ClrDraw, the user variable Y will be reset to 0. This might be useful as a side effect, but it's more likely to turn out to be a nuisance if you were relying on Y to store something useful. Also, such a wacky effect might get removed in later OS versions1, so it's a gamble relying on it to work for all users.

The RecallPic command does not erase what is previously on the graph screen when recalling a picture. Unless this is what you intend, use ClrDraw to erase the graph screen's old contents before recalling a picture.

Optimization

The ClrDraw command is not the only way to clear the screen. If something changes about the state of the functions or plots plotted on the graph, about the window dimensions, or the axes, grid, and labels, the graph screen will be marked as 'dirty' by the calculator, and will be cleared the next time you display it.

Don't be too confident about relying on this however. For example, if you cleared Y1 before displaying the graph, and Y1 previously contained something, the graph will be redrawn. However, if Y1 never existed, then you haven't changed anything, and the graph will remain.

A lot of people choose their preferred window settings using the following two commands, which sets the window to X= -47..47, Y= -31..31:

ZStandard:ZInteger

Since this actually switches two window settings, at least one will be different from the previous settings, so the next time the graph screen is shown, it will be cleared without a ClrDraw command. There are other friendly window settings that you can use as well.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/clrdraw


The ClrDraw Command

clrdraw.png

Command Summary

Clears the graph screen, redrawing any functions, plots, or axes/grid/labels.

Command Syntax

ClrDraw

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

The ClrDraw command clears away anything drawn on the graph screen — that is, the result of any of the graphics commands, except for Graph (which you can only clear with ClrGraph). It also leaves alone any functions or plots (which are disabled by FnOff and PlotsOff, respectively), as well as axes, labels, a grid, etc. (which can be disabled by the setGraph() command).

Be warned that it doesn't update the screen. For example, if you run the following program:

:circ()
:Prgm
:Circle 0,0,5
:ClrDraw
:EndPrgm

it will draw a circle and then end on the graph screen with the circle still drawn. The screen will actually update the next time you change something on the graph screen; you can also use DispG to update it (although in the program above, DispHome might be more appropriate).

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:clrdraw


The ClrHome Command
CLRHOME_ANIMATED.GIF

Command Summary

Clears the home screen of any text or numbers.

Command Syntax

ClrHome

Menu Location

While editing a program, press:

  1. PRGM to enter the PRGM menu
  2. RIGHT to enter the I/O menu
  3. 8 to choose ClrHome, or use arrows

Calculator Compatibility

TI-83/84/+/SE/CSE/CE

Token Size

1 byte

There are numerous times in a program that you need a clear screen, so that you can display whatever text you want without it being interrupted. One place, in particular, is at the beginning of a program, since the previous program call(s) and any other text is typically still displayed on the screen. The simple ClrHome command is the command you use to clear the home screen.

When you use the ClrHome, it resets the cursor position to the top left corner of the home screen. This is what the Disp and Pause commands use as the reference for what line to display their text on, but it does not have any effect on Output(.

Advanced Uses

You want to make sure to clear the home screen when exiting programs (at the end of a program). This ensures that the next program that the user runs will not have to deal with whatever text your program left behind. It also helps the user, because they will not have to manually clear the home screen by pressing the CLEAR key; you have already done it for them.

Error Conditions

  • ERR:INVALID occurs if this statement is used outside a program.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/clrhome


The ClrHome Command

clrhome.png

Command Summary

Clears the home screen.

Command Syntax

ClrHome

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

The ClrHome command clears the home screen — not the I/O screen where the result of commands like Disp or Output is displayed (you'd need ClrIO for that), but the screen where you run programs and evaluate expressions. This isn't usually something you want a program to clear, so this isn't a very exciting command.

It also has the drawback that the ClrHome command itself (or the program it's used in) is displayed on the home screen after it is cleared, so the end result is not a blank screen but something like what you see in the screenshot to the right.

Finally, ClrHome cannot be used inside a function, because functions aren't allowed to modify the state of the calculator.

Error Conditions

450 - Invalid in a function or current expression happens when ClrHome is used inside a function.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:clrhome


The ClrList Command
CLRLIST.GIF

Command Summary

Sets the dimension of a list or lists to 0.

Command Syntax

ClrList list1, [list2, list3, …]

Menu Location

Press:

  1. STAT to access the statistics menu
  2. 4 to select ClrList, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

ClrList sets the length of a list (or several lists) to 0. This is virtually equivalent to deleting the list, except for several differences:

  • The list still exists — it will be shown in the memory management menu and the list menu
  • Calling the dim( command on it will return 0, rather than an error.
  • ClrList can clear multiple lists at the same time

Advanced Uses

You might use ClrList when building up a list element by element and using dim( in the process:

:ClrList L1
:While 10>dim(L1
:Input X
:X→L1(1+dim(L1
:End

Optimization

Using DelVar instead of ClrList allows you to save a tiny bit of memory (between 12 and 16 bytes) that ClrList doesn't delete, while keeping almost every aspect of the list clearing the same. If you are clearing several lists, you can separate them with commas as the arguments to ClrList, which can save space. Using ClrList is also substantially faster than DelVar if the list is going to be cleared many times.

Error Conditions

  • ERR:SYNTAX is thrown if you leave off the symbol when referring to a custom list (i.e., ClrList B will not work; you have to use ClrList ∟B).

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/clrlist


The ClrTable Command
CLRTABLE.GIF

Command Summary

Clears saved calculations for the table screen.

Command Syntax

ClrTable

Menu Location

While editing a program, press:

  1. PRGM to access the program menu.
  2. RIGHT to access the I/O submenu.
  3. 9 to select ClrTable.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The ClrTable command clears all calculations for the table screen shown if you press 2nd TABLE. That is, all already-calculated values in the table are cleared, and TblInput is deleted. In IndpntAuto and DependAuto mode, this usually isn't noticeable because the table will be recalculated almost immediately when you next look at it (unless one of the entered functions is so complicated it takes a while to calculate). This mainly has an effect in IndpntAsk or DependAsk mode, where the corresponding parts of the table will be cleared entirely.

Advanced Uses

As a side effect, ClrTable seems to have all the effects of ClrDraw — it clears the graph screen, and any equations or plots will be regraphed the next time the graph screen is displayed.

Command Timings

ClrTable and ClrDraw take the same amount of time to clear the screen.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/clrtable


The conj( Command
CONJ.GIF

Command Summary

Calculates the complex conjugate of a complex number.

Command Syntax

conj(value)

Menu Location

Press:

  1. MATH to access the math menu.
  2. RIGHT, RIGHT to access the CPX (complex) submenu
  3. ENTER to select conj(.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

conj(z) returns the complex conjugate of the complex number z. If z is represented as x+iy where x and y are both real, conj(z) returns x-iy. Also works on a list of complex numbers.

conj(3+4i)
     3-4i

The conjugate of a number $z$ is often written $\overline{z}$, and is useful because it has the property that $z\overline{z}$ and $z+\overline{z}$ are real numbers.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/conj


The Connected Command
CONNECTED.GIF

Command Summary

Sets all equations to use the connected graphing style, and makes it the default setting.

Command Syntax

Connected

Menu Location

Press:

  1. MODE to access the mode menu.
  2. Use arrows to select Connected.

Calculator Compatibility

TI-83/84/+/SE (Not available on TI-84+CE calculators)

Token Size

2 bytes

The Connected command sets all equations to use the usual graph style - a connected line. In addition, this graph style is made the default, so that when a variable is deleted it will revert to this graph style. The other possible setting for this option is Dot.

Compare this to the GraphStyle( command, which puts a single equation into a specified graph style.

The Connected and Dot commands don't depend on graphing mode, and will always affect all functions, even in other graphing modes. The exception to this is that sequence mode's default is always the dotted-line style, even when Connected mode is set. The Connected command will still change their graphing style, it just won't change the default they revert to.

In addition to graphing equations, this setting also affects the output of DrawF, DrawInv, and Tangent(.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/connected


The CoordOff Command
COORDOFF.GIF

Command Summary

Turns off the cursor coordinate display on the graph screen.

Command Syntax

CoordOff

Menu Location

Press:

  1. 2nd FORMAT to access the graph format menu
  2. Use arrows and ENTER to select CoordOff

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

When moving a cursor on a screen, it's possible for the calculator to display the coordinates of the current point (either polar or rectangular coordinates, depending on which of RectGC or PolarGC is set). The CoordOff command turns off this option.

To turn it on, use the CoordOn command.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/coordoff


The CoordOn Command
COORDON.GIF

Command Summary

Turns on the cursor coordinate display on the graph screen.

Command Syntax

CoordOn

Menu Location

Press:

  1. 2nd FORMAT to access the graph format menu
  2. Use arrows and ENTER to select CoordOn

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

When moving a cursor on a screen, it's possible for the calculator to display the coordinates of the current point (either polar or rectangular coordinates, depending on which of RectGC or PolarGC is set). The CoordOn command turns on this option (to disable it, use the CoordOff command).

The coordinates are displayed in practically every situation when you're moving a cursor on the graph screen, even including the Trace, Input or Select( commands in a program. The interactive mode of Text( and the Pen tool are the exceptions — this is because these two situations involve a pixel coordinate, and not a point.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/coordon


The cos() Command

cos.png

Command Summary

Takes the cosine of a number (usually, an angle).

Command Syntax

cos(angle)

Menu Location

Press the COS button to enter cos(.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The cos() command returns the cosine of an angle measure. Naturally, the result depends on the angle mode the calculator is in: radian, degree, or (in AMS version 3.10) gradian. You can also use one of the r, °, G marks to specify an angle mode.

For many common angles, cos() can compute an exact result. Other angles, the calculator will leave alone unless it's in approximate mode (or unless you make it approximate), and then it will give a decimal approximation. As long as the calculator is in radian mode, cos() can be used with complex numbers as well.

:cos(60°)
           1/2
:cos(x+2π)
          cos(x)
:cos(πi/2)
          cosh(π/2)

If cos() is applied to a list, it will take the cosine of every element in the list.

Advanced Uses

The cos() of a matrix is not (in general) the same as taking the cosine of every element of the matrix. A different definition is used to compute the result; see Matrices and Their Commands. It requires the matrix to be square and diagonalizable in order to apply.

Error Conditions

230 - Dimension happens when taking cos() of a matrix that isn't square.

260 - Domain error happens when taking cos() of a complex number in degree or gradian mode.

665 - Matrix not diagonalizable happens when taking cos() of a matrix that isn't diagonalizable.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:cos


The cos( Command
COS.GIF

Command Summary

Returns the cosine of a real number.

Command Syntax

cos(angle)

Menu Location

Press [COS]

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

cos(θ) returns the cosine of θ, which is defined as the x-value of the point of intersection of the unit circle and a line containing the origin that makes an angle θ with the positive x-axis

The value returned depends on whether the calculator is in Radian or Degree mode. A full rotation around a circle is 2π radians, which is equal to 360°. The conversion from radians to degrees is angle*180/π and from degrees to radians is angle*π/180. The cos( command also works on a list of real numbers.

In radians:

cos(π/3)
    .5

In degrees:

cos(60)
    .5

Advanced Uses

You can bypass the mode setting by using the ° (degree) and r (radian) symbols. These next two commands will return the same values no matter if your calculator is in degrees or radians:

cos(60°)
    .5
cos(π/3ֿ¹ )
    .5

Error Conditions

  • ERR:DATA TYPE is thrown if you supply a matrix or a complex argument.
  • ERR:ARGUMENT is thrown if you use more than one number.
  • ERR:DOMAIN is thrown if you supply an input ≥1E12.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/cos


The cosֿ¹( Command
COSINVERSE.GIF

Command Summary

Returns the inverse cosine (also called arccosine)

Command Syntax

cosֿ¹(number)

Menu Location

Press:

  1. [2nd]
  2. [cosֿ¹]

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

cosֿ¹( returns the arccosine of its argument. It is the inverse of cos(, which means that cosֿ¹(n) produces an angle θ such that cos(θ)=n.

Like cos(, the result of cosֿ¹( depends on whether the calculator is in Radian or Degree mode. However, unlike cosine, the result is in degrees or radians, not the argument. A full rotation around a circle is 2π radians, which is equal to 360°. The conversion of θ=cosֿ¹(n) from radians to degrees is θ*180/π and from degrees to radians is θ*π/180. The cosֿ¹( command also works on a list.

The cosֿ¹( function can be defined for all real and complex numbers, but assumes real values only in the closed interval [-1,1]. Because Z80 calculators have their trigonometric functions and inverses restricted only to real values, the calculator will throw ERR:DOMAIN if the argument is outside of this interval, no matter what the mode setting may be.

In radians:

:cosֿ¹(-1)
    3.141592654

In degrees:
:cosֿ¹(-1)
    180

Advanced Uses

Since the function cosine itself doesn't have the restrictions that arccosine does, and since arccosine is the inverse of cosine, you can use cosֿ¹(cos( to keep a variable within a certain range (most useful for the home screen). Here is an example for a game like pong. The ball travels between 0 and 12.

You could use a flag like this:

:If X=12 or not(X     \\ X is the position
:-D→D        \\ D is the direction
:X+D→X        \\ new position
:Output(8,X,"=

An easier way to do this, without needing a flag or even an If statement, is using cosֿ¹(cos(

:X+1→X        \\ Note: the calculator is in Degree mode
:Output(8,cosֿ¹(cos(15X))/15,"=")    \\ I used 15 because cosֿ¹ ranges from [0,180]
                                        and X from [0,12],  so 180/12=15

Error Conditions

  • ERR:DOMAIN is thrown if you supplied an argument outside the interval [-1,1]
  • ERR:DATA TYPE is thrown if you input a complex value or a matrix.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/arccos


The cosh() Command

cosh.png

Command Summary

Takes the hyperbolic cosine of a number.

Command Syntax

cosh(value)

Menu Location

  • Press 2nd MATH to enter the MATH menu.
  • Press C to enter the Hyperbolic submenu.
  • Press 2 to select cosh(.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The cosh() command returns the hyperbolic cosine of a number.

As long as the calculator is in radian mode, cosh() can be used with complex numbers according to the rule that cosh(ix)=cos(x) and cos(ix)=cosh(x). This rule only works in radian mode, and cosh() of a complex number will return a domain error when working in degrees or gradians.

Occasionally, cosh() can compute an exact result; most of the time, the calculator will leave an expression with cosh() alone unless it's in approximate mode (or you force an approximation). When cosh() is used with symbolic expressions, the calculator can go back and forth between the cosh() expression and its exponential equivalent.

:cosh(0)
           1
:expand(cosh(x))
          e^x/2+1/(2*e^x)
:comDenom(e^x/2+1/(2*e^x))
          cosh(x)

If cosh() is applied to a list, it will take the hyperbolic cosine of every element in the list.

Advanced Uses

The cosh() of a matrix is not (in general) the same as taking the hyperbolic cosine of every element of the matrix. A different definition is used to compute the result; see Matrices and Their Commands. It requires the matrix to be square and diagonalizable in order to apply.

Formulas

The definition of hyperbolic cosine is given in terms of exponents:

(1)
\begin{align} \cosh{x} = \frac{e^x+e^{-x}}{2} \end{align}

Error Conditions

230 - Dimension happens when taking cosh() of a matrix that isn't square.

260 - Domain error happens when taking cosh() of a complex number in degree or gradian mode.

665 - Matrix not diagonalizable happens when taking cosh() of a matrix that isn't diagonalizable.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:cosh


The cosh( Command
COSH.GIF

Command Summary

Calculates the hyperbolic cosine of a value.

Command Syntax

cosh(value)

Menu Location

The cosh( command is only found in the Catalog. Press:

  1. 2nd CATALOG to access the command catalog.
  2. C to skip to commands starting with C.
  3. Scroll down and select cosh(.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

Calculates the hyperbolic cosine of a value. The hyperbolic trig functions sinh(, cosh(, and tanh( are an analog of normal trig functions, but for a hyperbola, rather than a circle. They can be expressed in terms of real powers of e, and don't depend on the Degree or Radian mode setting.

cosh(0)
    1
cosh(1)
    1.543080635

Like normal trig commands, cosh( works on lists as well, but not on complex numbers, even though the function is often extended to the complex numbers in mathematics.

Formulas

The definition of hyperbolic cosine is:

(1)
\begin{align} \cosh{x}=\frac{e^x+e^{-x}}{2} \end{align}

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/cosh


The coshֿ¹( Command
COSHINVERSE.GIF

Command Summary

Calculates the inverse hyperbolic cosine of a value.

Command Syntax

coshֿ¹(value)

Menu Location

The coshֿ¹( command can only be found in the catalog. Press:

  1. 2nd CATALOG to access the command catalog.
  2. C to skip to commands starting with C.
  3. Scroll down and select coshֿ¹(

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The coshֿ¹( function gives the inverse hyperbolic cosine of a value. coshֿ¹(x) is the number y such that x = cosh(y).

Although coshֿ¹(x) can be defined for all real and complex numbers, it assumes real values only for x≥1. Since hyperbolic functions in the Z80 calculators are restricted only to real values, ERR:DOMAIN is thrown when x<1.

The coshֿ¹( command also works for lists.

coshֿ¹(1)
    0
coshֿ¹({2,3})
    {1.316957897 1.762747174}

Error Conditions

  • ERR:DOMAIN when taking the inverse cosh of a number less than 1.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/arcosh


The cot() Command

cot.png

Command Summary

Takes the cotangent of a number (usually, an angle).

Command Syntax

cot(angle)

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press A to enter the Trig submenu.
  • Press 6 to select cot(.

Calculator Compatibility

This command requires a calculator with AMS version 2.07 or higher (it will also work on any TI-89 Titanium or Voyage 200 calculator)

Token Size

1 byte

The cot() command returns the cotangent (the reciprocal of the tangent) of an angle measure. Naturally, the result depends on the angle mode the calculator is in: radian, degree, or (in AMS version 3.10) gradian. You can also use one of the r, °, G marks to specify an angle mode.

The cot() command, along with 11 other trig and hyperbolic functions, was added with AMS version 2.07. It can be easily replaced on earlier versions with 1/tan(x), which is what it simplifies to anyway.

For many common angles, cot() can compute an exact result. Other angles, the calculator will leave alone unless it's in approximate mode (or unless you make it approximate), and then it will give a decimal approximation. As long as the calculator is in radian mode, cot() can be used with complex numbers as well.

:cot(60°)
           √3/3
:cot(x)
          1/tan(x)
:cot(0)
          undef

If cot() is applied to a list, it will take the cotangent of every element in the list. However, it can't be applied to matrices the way cos() can (this is probably an oversight; all the trig and hyperbolic functions that were present in all AMS versions work with matrices, but the ones added in version 2.07 do not).

Error Conditions

260 - Domain error happens when taking cot() of a complex number in degree or gradian mode.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:cot


The coth() Command

coth.png

Command Summary

Takes the hyperbolic cotangent of a number.

Command Syntax

coth(value)

Menu Location

  • Press 2nd MATH to enter the MATH menu.
  • Press C to enter the Hyperbolic submenu.
  • Press 6 to select coth(.

Calculator Compatibility

This command requires a calculator with AMS version 2.07 or higher (it will also work on any TI-89 Titanium or Voyage 200 calculator)

Token Size

1 byte

The coth() command returns the hyperbolic cotangent of a number. Along with 11 other trig and hyperbolic functions, it was added in AMS version 2.07; on earlier versions, coth(x) can be replaced by 1/tanh(x).

As long as the calculator is in radian mode, coth() can be used with complex numbers according to the rule that coth(ix)=-cot(x)*i and cot(ix)=-coth(x)*i. This rule only works in radian mode, and coth() of a complex number will return a domain error when working in degrees or gradians.

Occasionally, coth() can compute an exact result; most of the time, the calculator will leave an expression with coth() alone unless it's in approximate mode (or you force an approximation). When coth() is used with symbolic expressions, the calculator can go back and forth between the coth() expression and its exponential equivalent.

:coth(0)
           undef
:expand(coth(x))
          -1/(e^x+1)+1/(e^x-1)+1
:comDenom(1-2/((e^x)^2+1))
          1/tanh(x)

If coth() is applied to a list, it will take the hyperbolic cotangent of every element in the list. However, it can't be applied to matrices the way tanh() can (this is probably an oversight; all the trig and hyperbolic functions that were present in all AMS versions work with matrices, but the ones added in version 2.07 do not).

Formulas

The definition of hyperbolic cotangent is, by analogy with cot(), the ratio of cosh() and sinh():

(1)
\begin{align} \coth{x}=\frac{\cosh{x}}{\sinh{x}} = \frac{e^x+e^{-x}}{e^x-e^{-x}} \end{align}

Error Conditions

260 - Domain error happens when taking coth() of a complex number in degree or gradian mode.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:coth


The csc() Command

csc.png

Command Summary

Takes the cosecant of a number (usually, an angle).

Command Syntax

csc(angle)

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press A to enter the Trig submenu.
  • Press 4 to select csc(.

Calculator Compatibility

This command requires a calculator with AMS version 2.07 or higher (it will also work on any TI-89 Titanium or Voyage 200 calculator)

Token Size

1 byte

The csc() command returns the cosecant (the reciprocal of the sine) of an angle measure. Naturally, the result depends on the angle mode the calculator is in: radian, degree, or (in AMS version 3.10) gradian. You can also use one of the r, °, G marks to specify an angle mode.

The csc() command, along with 11 other trig and hyperbolic functions, was added with AMS version 2.07. It can be easily replaced on earlier versions with 1/sin(x), which is what it simplifies to anyway.

For many common angles, csc() can compute an exact result. Other angles, the calculator will leave alone unless it's in approximate mode (or unless you make it approximate), and then it will give a decimal approximation. As long as the calculator is in radian mode, csc() can be used with complex numbers as well.

:csc(30°)
           2
:csc(x)
          1/sin(x)
:csc(0)
          undef

If csc() is applied to a list, it will take the secant of every element in the list. However, it can't be applied to matrices the way sin() can (this is probably an oversight; all the trig and hyperbolic functions that were present in all AMS versions work with matrices, but the ones added in version 2.07 do not).

Error Conditions

260 - Domain error happens when taking csc() of a complex number in degree or gradian mode.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:csc


The csch() Command

csch.png

Command Summary

Takes the hyperbolic cosecant of a number.

Command Syntax

csch(value)

Menu Location

  • Press 2nd MATH to enter the MATH menu.
  • Press C to enter the Hyperbolic submenu.
  • Press 4 to select csch(.

Calculator Compatibility

This command requires a calculator with AMS version 2.07 or higher (it will also work on any TI-89 Titanium or Voyage 200 calculator)

Token Size

1 byte

The csch() command returns the hyperbolic cosecant of a number. Along with 11 other trig and hyperbolic functions, it was added in AMS version 2.07; on earlier versions, csch(x) can be replaced by 1/sinh(x).

As long as the calculator is in radian mode, csch() can be used with complex numbers according to the rule that csch(ix)=-csc(x)*i and csc(ix)=-csch(x)*i. This rule only works in radian mode, and csch() of a complex number will return a domain error when working in degrees or gradians.

Occasionally, csch() can compute an exact result; most of the time, the calculator will leave an expression with csch() alone unless it's in approximate mode (or you force an approximation). When csch() is used with symbolic expressions, the calculator can go back and forth between the csch() expression and its exponential equivalent.

:csch(0)
           undef
:expand(csch(x))
          1/(e^x+1)+1/(e^x-1)
:comDenom(1/(e^x+1)+1/(e^x-1))
          1/sinh(x)

If csch() is applied to a list, it will take the hyperbolic cosecant of every element in the list. However, it can't be applied to matrices the way sinh() can (this is probably an oversight; all the trig and hyperbolic functions that were present in all AMS versions work with matrices, but the ones added in version 2.07 do not).

Formulas

The definition of hyperbolic cosecant is, by analogy with csc(), the reciprocal of sinh():

(1)
\begin{align} \operatorname{csch}{x}=\frac{1}{\sinh{x}} = \frac{2}{e^x-e^{-x}} \end{align}

Error Conditions

260 - Domain error happens when taking csch() of a complex number in degree or gradian mode.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:csch


The CubicReg Command
CUBICREG.GIF

Command Summary

Calculates the best fit cubic function through a set of points.

Command Syntax

CubicReg [x-list, y-list, [frequency list], [equation variable]

Menu Location

Press:

  1. [STAT] to access the statistics menu
  2. [LEFT] to access the CALC submenu
  3. 6 to select CubicReg, or use arrows

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The CubicReg command can calculate the best fit cubic function through a set of points. To use it, you must first store the points to two lists: one of the x-coordinates and one of the y-coordinates, ordered so that the nth element of one list matches up with the nth element of the other list. L₁ and L₂ are the default lists to use, and the List Editor (STAT > Edit…) is a useful window for entering the points. You must have at least 4 points because there are infinitely many cubics that can go through 3 points or less.

In its simplest form, CubicReg takes no arguments, and calculates a cubic through the points in L₁ and L₂:

:{9,13,21,30,31,31,34→L₁
:{260,320,420,530,560,550,590→L₂
:CubicReg

On the home screen, or as the last line of a program, this will display the equation of the quadratic: you'll be shown the format, y=ax³+bx²+cx+d, and the values of a, b, c, and d. It will also be stored in the RegEQ variable, but you won't be able to use this variable in a program — accessing it just pastes the equation wherever your cursor was. Finally, the statistical variables a, b, c, d, and R² will be set as well. This latter variable will be displayed only if "Diagnostic Mode" is turned on (see DiagnosticOn and DiagnosticOff).

You don't have to do the regression on L₁ and L₂, but if you don't you'll have to enter the names of the lists after the command. For example:

:{9,13,21,30,31,31,34→FAT
:{260,320,420,530,560,550,590→CALS
:CubicReg ∟FAT,∟CALS

You can attach frequencies to points, for when a point occurs more than once, by supplying an additional argument — the frequency list. This list does not have to contain integer frequencies. If you add a frequency list, you must supply the names of the x-list and y-list as well, even when they're L₁ and L₂.

Finally, you can enter an equation variable (such as Y₁) after the command, so that the equation is stored in this variable automatically. This doesn't require you to supply the names of the lists, but if you do, the equation variable must come last. You can use polar, parametric, or sequential variables as well, but since the quadratic will be in terms of X anyway, this doesn't make much sense.

An example of CubicReg with all the optional arguments:

:{9,13,21,30,31,31,34→FAT
:{260,320,420,530,560,550,590→CALS
:{2,1,1,1,2,1,1→FREQ
:CubicReg ∟FAT,∟CALS,∟FREQ,Y₁

Advanced

Note that even if a relationship is actually linear or quadratic, since a cubic regression has all the freedom of a linear regression and more, it will produce a better R² value, especially if the number of points is small, and may lead you to (falsely) believe that a relationship is cubic when it actually isn't. Take the correlation constant with a grain of salt, and consider if the fit is really that much better at the expense of doubling the complexity and if there's any reason to believe the relationship between the variables may be cubic.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/cubicreg


The cumSum( Command
CUMSUM.GIF

Command Summary

Calculates cumulative sums of a list or of the columns of a matrix.

Command Syntax

cumSum(list or matrix)

Menu Location

Press:

  1. 2nd LIST to access the list menu.
  2. RIGHT to access the OPS submenu.
  3. 6 to select cumSum(, or use arrows.

Alternatively, press:

  1. MATRIX (TI-83) or 2nd MATRIX (TI-83+ or higher) to access the matrix menu.
  2. RIGHT to access the MATH submenu.
  3. 0 to select cumSum(, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

cumSum( calculates the cumulative sums of a list, or of the columns of a matrix, and outputs them in a new list or matrix variable.

For a list, this means that the Nth element of the result is the sum of the first N elements of the list:

cumSum({1,3,5,7,9})
    {1 4 9 16 25}

For a matrix, cumSum( is applied to each column in the same way as it would be for a list (but numbers in different columns are never added):

[[0,1,1][0,1,3][0,1,5][0,1,7]]
    [[0 1 1]
     [0 1 3]
     [0 1 5]
     [0 1 7]]
cumSum(Ans)
    [[0 1 1]
     [0 2 4]
     [0 3 9]
     [0 4 16]]

Advanced Uses

The ΔList( command is very nearly the inverse of the cumSum( command - it calculates the differences between consecutive elements. For any list, ΔList(cumSum(list)) will return the same list, but without its first element:

ΔList(cumSum({1,2,3,4,5,6,7}))
    {2 3 4 5 6 7}

Removing the first element would otherwise be a difficult procedure involving the seq( command, so this is a useful trick to know.


For a matrix, if you want to sum up the rows instead of the columns, use the T (transpose) command.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/cumsum


The Custom Command

custom.png

Command Summary

Creates a custom toolbar menu.

Command Syntax

:Custom
(list of titles and items)
:EndCustm

Menu Location

Starting in the program editor:

  • Press F2 to enter the Control menu.
  • Press 7 to select Custom…EndCustm.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes for Custom;
2 bytes for EndCustm.

A Custom..EndCustm block creates a custom toolbar menu. The menu can have up to eight tabs for the F1 .. F8 keys, each with any number of sub-items. The contents of the menu are defined using the Title and Item commands inside the Custom..EndCustm block.

The Title command indicates a new tab, so you can have up to eight of these. After Title, put a string to use as the label for the tab. If the title has no items, you'll be able to select the title itself to insert this label somewhere.

The Item command indicates an item under the most recent tab — you can have as many items under a tab as you like, or none at all. This also takes a string that will be used as the label for the item, and will be inserted any time you select that item from the menu.

Here is an example of the syntax:

:Custom
: Title "Animals"
:  Item "Dog"
:  Item "Cat"
: Title "Rocks"
: Title "Plants"
:  Item "Grass"
:  ...
:EndCustm

In this case, the custom toolbar will display | F1 Animals | F2 Rocks | F3 Plants | … |. Pressing F1 would bring up the Animals menu with items 1:Dog and 2:Cat. Then, pressing 1 or ENTER would insert Dog after the cursor. Pressing F2 would insert Rocks under the cursor since that tab has no items.

The custom toolbar can be accessed in any window. To switch to the custom toolbar or back, press 2nd CUSTOM (or use the CustmOn and CustmOff commands).

The calculator comes with a default custom menu, which is overwritten whenever you create one of your own. To restore it, select F6 - Clean Up from the home screen toolbar, and select 3:Restore custom default. This also lets you see an example of Custom..EndCustm syntax.

A related command is Toolbar..EndTBar. It also displays a custom menu, but can only be used in a program, and the entries of the menu jump to other parts of the program.

Error Conditions

450 - Invalid in a function or current expression happens when Custom..EndCustm is used in a function.

460 - Invalid in {{Custom}}..{{EndCustm}} block happens when anything other than Title or Item appears in the block.

590 - Invalid syntax block happens when the syntax is somehow wrong, e.g. if there are more than 8 tabs.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:custom


The Cycle Command

cycle.png

Command Summary

Prematurely ends a cycle of a loop.

Command Syntax

:Cycle

Menu Location

Starting in the program editor:

  • Press F2 to enter the Control menu.
  • Press 8 to enter the Transfers submenu.
  • Press 3 to select Cycle.

Calculator Compatibility

This command works on all calculators.

Token Size

4 bytes

The Cycle command ends the current cycle of a For..EndFor, Loop..EndLoop, or While..EndWhile loop, as though the corresponding End were there. It doesn't exit the loop forever; if the loop would have repeated, it goes back to the beginning. However, if the loop is ready to end (if the counter is equal to the end value, for a For loop, or if the condition is false, for a While loop), it exits the loop and continues after the EndFor or EndWhile command.

An example of Cycle in a For loop:

:For num,1,100
: If isPrime(num)
:  Cycle
: Disp num
:EndFor

This loop prints all the composite numbers between 1 and 100. Here's how it works: for every number, it first checks whether or not it's prime. If it is, the program goes back to the beginning of the loop with the next number. On the other hand, if the number is composite, the program continues to the Disp command, then hits EndFor and goes back to the beginning of the loop as well.

If the Cycle instruction is inside multiple loops, one nested in the other, it works with the innermost loop.

Error Conditions

560 - Invalid outside Loop..EndLoop, For..EndFor, or While..EndWhile blocks happens when Cycle is used outside a loop.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:cycle


The CyclePic command

cyclepic.png

Command Summary

Displays picture variables in a cycle for a given amount of time per picture.

Command Syntax

CyclePic picNameString, number of pictures [[,wait][,cycles][,direction]]

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

This command displays several picture variables in a cycle, with each picture getting an optional wait time, number of cycles, and the direction to display the pictures in. For instance, if you have saved 5 pictures: pic1, pic2, pic3, pic4, pic5, then you could do this to display them all: CyclePic "pic", 5, 3, 2, -1. This would display all 5 pictures for 3 seconds each, for 2 cycles, and backward, meaning it would display picture 5 first. Unfortunately, there is no way to use the command on pictures that are stored in a folder. For instance, if you had the previous case, but every picture is stored in a folder called PICTURES, there is no way to cycle them without moving them out of the folder.

:CyclePic "ham", 3, 1.5, 6, 1

The above code would display pictures "ham1", "ham2", and "ham3" in that order for 1.5 seconds each, and for 6 cycles.

Advanced Uses

This command can be used to create a slideshow-style program, or it can be used to display a sprite so it looks like it is moving. Note that you cannot use this function if the pictures are not in the MAIN file folder.

Error Conditions

230 - Dimension happens when the filepath listed is not in the main directory.

960 - Undefined variable happens when the picture variables specified do not exist..

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:cyclepic


The d() Command

d.png

Command Summary

Takes a symbolic derivative of an expression.

Command Syntax

d(expression,variable[,order])

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press B to enter the Calculus submenu.
  • Press 1 to select d(.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

NOTE: Due to the limitations of the wiki markup language, the d() command on this page does not appear as it would on the calculator. See Wiki Markup Limitations for more information.

The d() command takes the derivative of an expression with respect to a given variable. All other variables are treated as constant.

Optionally, you can give it a third argument (an integer), and take the derivative that many times. If the argument is negative, it will actually integrate.

:d(x^2,x)
           2*x
:d(x^5,x,4)
           120*x
:d(x^2+y^2+2*x*y,x)
           2*x+2*y

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:d


The dayOfWk command

dayofwk.png

Command Summary

Returns an integer from 1-7 that shows what day of week it is for a specific date.

Command Syntax

dayOfWk(year, month, day)

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command requires a calculator with AMS version 2.07 or higher (it will also work on any TI-89 Titanium or Voyage 200 calculator)

The dayOfWk command returns an integer from 1 through 7 which shows what day of the week it was on a certain date. The Ti-89 Titanium manual says that this function may not give accurate results for years prior to 1583 (pre-Gregorian calendar).

Integer value: Day of the week:
1 Sunday
2 Monday
3 Tuesday
4 Wednesday
5 Thursday
6 Friday
7 Saturday
:dayOfWk(1948,9,6)
:      2
:dayOfWk(1600,1,15)
:      7

The above examples find that September 6th,1948 was a Monday and that January 15th, 1600 was a Saturday. It also works with future dates, in case you want to use that in a program.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:dayofwk


The dayOfWk( Command
DAYOFWK.PNG

Command Summary

Returns an integer from 1 to 7, each representing a day of the week, given a date.

Command Syntax

dayOfWk(year,month,day)

Menu Location

Press:

  1. [2ND] + [0] for the CATALOG
  2. [X-1] to jump to the letter D
  3. [ENTER] to insert the command

Calculator Compatibility

TI-84+/SE

Token Size

2 bytes

dayOfWk(year,month,day) returns an integer from 1 to 7, each representing a separate day of the week. 1 represents Sunday, 2 represents Monday, and so on, with 7 representing Saturday. The date format is different than the normal American format (month/day/year), so be careful to put the arguments in the right order. You can remember this by thinking of the descending lengths of time in each of the arguments.

:dayOfWk(2007,12,30)

The above code returns 1, because the 30th of December, 2007, is a Sunday.

Error Conditions

  • ERR:DOMAIN is thrown if any of the arguments are non-integers, or the date does not exist, such as the 42nd of February. However, the year does not matter (a date that takes place in the year 10000 is valid). However, there are exceptions, even if some dates do exist, this error may still occur. If you attempt to calculate the previous day of a week such as the previous day, the error may still occur.

Related Commands

See Also

  • Day of Week — routine to calculate the day of the week

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/dayofwk


The dbd( Command
DBD.GIF

Command Summary

Calculates the number of days between two days.

Command Syntax

dbd(date1, date2)

Date format — one of:

  • DDMM.YY
  • MM.DDYY

Menu Location

On the TI-83, press:

  1. 2nd FINANCE to access the finance menu.
  2. ALPHA D to select dbd(, or use arrows and ENTER.

On the TI-83+ or higher, press:

  1. APPS to access the applications menu.
  2. ENTER to select Finance…
  3. ALPHA D to select dbd(, or use arrows and ENTER.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The dbd( command calculates the number of days between two dates. Each date is encoded as a single number in one of two formats (two formats can be mixed in the same command):

  • day, month, year — DDMM.YY (e.g. April 26, 1989 would be 2604.89)
  • month, day, year — MM.DDYY (e.g. April 26, 1989 would be 04.2689 or just 4.2689)

Because this is just a number like any other, leading zeroes and trailing zeroes after the decimal can be dropped. For example, January 1, 2000 does not have to be formatted as 0101.00 but can be simply 101.

Since there are only two digits for the year, obviously only a century's worth of dates can be handled. The calculator assumes this range to be from January 1, 1950 to December 31, 2049.

If the second date comes before the first, dbd( will return a negative number of days, so the range of possible results is from -36524 to 36524.

Finally, dbd( will also work for list inputs in the usual manner: a single date will be compared against every date in a list, and two lists of dates will be paired up.

dbd(612.07,2512.07
    19
dbd(1.0207,1.0107
    -1
dbd(1.0107,{2.0107,3.0107,4.0107})
    {31 59 90}

Advanced Uses

The dbd( command can be used to calculate the day of week without using the dayOfWk( command, which is only available on the TI-84+ or higher.

Error Conditions

  • ERR:DOMAIN is thrown if a date is improperly formatted.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/dbd


The DEC Answer Command
DECPIC.gif

Command Summary

Mode command that sets Answers to DEC.

Command Syntax

DEC Answer

Menu Location

Press:

  1. MODE
  2. DOWN until you see Answers
  3. ENTER on DEC

Alternatively, access the catalog.

Calculator Compatibility

TI-84 2.53MP only

Token Size

2 bytes

The DEC Answer command is a mode command that changes the Answers mode to DEC. DEC mode is very similar to the AUTO mode in which the calculator will display all answers in decimal form unless the returned number is an integer. Fractions will only be displayed with use of the ►Frac command.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/dec-answer


The ►Dec Command
DEC.GIF

Command Summary

Displays the decimal form of a fraction.

Command Syntax

<fraction>►Dec

Menu Location

While editing a program, press:

  1. MATH to enter the MATH menu
  2. 2 or use the arrow keys to select

Calculator Compatibility

TI-83/84/+/SE/CE

Token Size

1 byte

This command is generally useless. Its supposed use is to convert numbers into decimal form, but any typed fractions are displayed as decimals anyway.

1/3
     .3333333333
1/3►Dec
     .3333333333

In 2.53 MP or higher, typed fractions are displayed in fraction form. Therefore, the ►Dec command is useful in this case.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/dec


The Define Command

define.png

Command Summary

Stores a value in a variable.

Command Syntax

Define variable=value

Menu Location

Starting in the program editor:

  • Press F4 to enter the Var menu.
  • Press 1 or Enter to select Define.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

The Define command sets the value of a variable. At its simplest, it's an alternative to : Define x=5 is equivalent to 5→x. However, Define is also useful for defining functions or programs using Func..EndFunc or Prgm..EndPrgm respectively, which can't do:

:Define key()=Func
: Local k
: Loop
:  getKey()→k
:  If k≠0
:   Return k
: EndLoop
:EndFunc

Advanced Uses

Using Define to create functions or programs is very useful when inside a program. If your program uses its own subroutines to perform simple tasks (such as the key-reading program above), you can define these subroutines inside the program itself, keeping everything in one file (it might be good to make them Local or use DelVar to delete them afterwards). Subroutines are useful for organizing a large program.

Error Conditions

190 - Circular definition happens when defining a variable (other than a recursive function or program) in terms of itself.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:define


The Degree Command
DEGREE.GIF

Command Summary

Puts the calculator in Degree mode.

Command Syntax

Degree

Menu Location

While editing a program, press:

  1. MODE to access the mode menu.
  2. Use arrows and ENTER to select Degree.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The Degree command puts the calculator into Degree mode, where the inputs and/or outputs to trig functions are assumed to be degree angles.

Angles measured in degrees range from 0 to 360, with 0 being an empty angle, 90 being a right angle, 180 being a straight angle, and 360 being a full angle all the way around a circle.

To convert from a radian angle to a degree angle, multiply by 180/π. To go the other way, and get a radian angle from a degree angle, multiply by π/180.

The following commands are affected by whether the calculator is in Radian or Degree mode:

The input is differently interpreted:

The output is differently expressed:

However, some commands are notably unaffected by angle mode, even though they involve angles, and this may cause confusion. This happens with the SinReg command, which assumes that the calculator is in Radian mode even when it's not. As a result, the regression model it generates will graph incorrectly in Degree mode.

Also, complex numbers in polar form are an endless source of confusion. The angle( command, as well as the polar display format, are affected by angle mode. However, complex exponentials (see the e^( command), defined as $e^{i\theta}=\cos\theta+i\sin\theta$, are evaluated as though in Radian mode, regardless of the angle mode. This gives mysterious results like the following:

Degree:re^θi
        Done
e^(πi)
        1e^(180i)
Ans=e^(180i)
        0 (false)

Overall, it's better to put your calculator in Radian mode when dealing with polar form of complex numbers, especially since no mathematician would ever use degrees for the purpose anyway.

Optimization

It's sometimes beneficial to use the ° symbol instead of switching to Degree mode. The ° symbol will make sure a number is interpreted as a degree angle, even in Radian mode, so that, for example:

Radian
        Done
sin(90)
        -.8011526357
sin(90°)
        1

This is smaller when only one trig calculation needs to be done. Also, it doesn't change the user's settings, which are good to preserve whenever possible.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/degree-mode


The DelVar Command
DELVAR.GIF

Command Summary

Deletes a variable from memory.

Command Syntax

DelVar variable

Menu Location

While editing a program, press:

  1. PRGM to enter the PRGM menu
  2. ALPHA TAN to choose DelVar, or use arrows

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The DelVar command deletes the contents of a variable (and thus the variable itself) from memory. You can use the DelVar command with any variable: reals, lists, matrices, strings, pictures, etc. However, you cannot use DelVar on specific elements of a matrix or string; it will actually throw a ERR:SYNTAX error. (It also does not work on programs, unfortunately.)

If the DelVar command is used with a real variable, the variable is not only deleted from memory but automatically set to zero the next time it is used. This is equivalent to using store () to manually set the variable yourself. Because the DelVar command is two bytes instead of one, there is no size difference between the two.

:0→A
same as
:DelVar A

While there is no size difference between the two, DelVar does have some problems that go along with using it. If used in a For loop to delete the counter variable or used to delete the variable and/or value in the IS>( or DS<( commands before using them, it will cause an ERR:UNDEFINED error.

This is a result of the way that the interpreter in TI-Basic is designed, so there is nothing you can do about it. You just need to be cognizant of it when using DelVar in a For( loop or together with IS>( or DS<(.

Advanced Uses

When you are done using variables, you should delete them at the end of the program with the DelVar command to cleanup. Each variable takes up a set amount of space (for example, a real variable is 15 bytes), and the more variables you can delete the more free memory is available. Free memory helps your programs run faster and allows you to pack more things on your calculator.

Because the DelVar command doesn't update the Ans variable, you can use DelVar and the current value in Ans will still be preserved for later use.

Optimizations

The DelVar command does not need a line break or colon (which indicates a new line of code) following the variable name. This allows you to make chains of variables (organized in whatever order you want), and it saves a byte for each line break or colon removed.

:DelVar A
:DelVar B
can be
:DelVar ADelVar B

Besides making chains of variables, the DelVar command also allows you to take the command from the next line and put it immediately after the DelVar command.

:DelVar A
:Disp "Hello
can be
:DelVar ADisp "Hello

There are, however, two cases in which the following statement will be ignored, so you should add a newline:

DelVar also does not count as a line with respect to IS>(, DS<(, and single-line If statements.

:If B
:Then
:DelVar A
:Disp "Hello
:End
can be
:If B
:DelVar ADisp "Hello

Command Timings

The speed of the DelVar command depends on the circumstance where it is used. When the variable already exists, DelVar is slower because it has to deallocate the variable from the RAM. DelVar is also significantly slower for zeroing real variables when compared to using to set the variable to 0. The speed difference becomes apparent when the value is reset many times but is not a major factor if only used sparingly.

Error Conditions

  • ERR:SYNTAX is thrown when trying to delete a system variable (e.g. DelVar Xmin) or a program, even though this is syntactically correct.
  • ERR:UNDEFINED is thrown if you delete the loop variable while inside the loop, or delete the variable used in IS>( or DS<(.
  • ERR:ARCHIVED is thrown if you use DelVar on an archived variable.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/delvar


The DelVar Command

delvar.png

Command Summary

Deletes a variable or variables.

Command Syntax

DelVar var1[,var2,…]

Menu Location

Starting in the program editor:

  • Press F4 to enter the Var menu.
  • Press 2 to select DelVar.

Calculator Compatibility

This command works on all calculators.

Token Size

3 bytes

The DelVar command deletes variables from existence, making them undefined again. This is a good way of cleaning up at the end of a program, or of making sure that a variable is undefined before you use it in a symbolic expression.

For DelVar to work, the variable must not be archived or locked. It also doesn't work on any program that's currently running, or on system variables.

There are two commands which might be a better alternative to DelVar, however. NewProb deletes all 26 one-letter variables at once; however, it also clears things like the graph screen that you might want to see preserved. Declaring a variable as Local at the beginning of a program prevents you from needing to delete it afterward, and it also makes sure you don't overwrite any existing variables.

Newer calculators have a DelType command to delete all variables of a certain type (provided they're not locked or archived). This is risky: you'll almost certainly delete too much. It's better to use DelVar, even if you have to list a hundred variables to do it.

Advanced Uses

Assembly programs might allow you to "hide" programs (or other variables) from the variable menu. This is actually done by marking the variable in question as "in use", the way a currently-running program is marked. As a result, you won't be able to delete a hidden variable, and trying to will give the "Variable or Flash application in use" error.

Error Conditions

140 - Argument must be a variable name happens when trying to delete something that isn't a valid variable name.

450 - Invalid in a function or current expression happens when DelVar is used in a function.

870 - Reserved name or system variable happens when trying to delete a system variable.

970 - Variable or Flash application in use happens when trying to delete a currently running program.

980 - Variable is locked, protected, or archived happens when trying to delete a locked or archived variable.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:delvar


The DependAsk Command
DEPENDASK.GIF

Command Summary

Disables automatic calculations in the table.

Command Syntax

DependAsk

Menu Location

Press:

  1. 2nd TBLSET to access the table settings menu.
  2. Use arrows and ENTER to select Ask from the Depend: line.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

When the DependAsk setting (opposed to the DependAuto setting) is turned on, values in the table are not automatically calculated. To calculate the value of an equation, you have to select the column corresponding to that equation in the row corresponding to the value at which to calculate it, and press ENTER. For example, to calculate Y1 at X=0, select the X=0 column, scroll right to Y1, and press ENTER.

The DependAsk setting might be useful when dealing with a difficult-to-calculate function, for which you wouldn't want to have to calculate values that aren't really necessary.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/dependask


The DependAuto Command
DEPENDAUTO.GIF

Command Summary

Enables automatic calculations in the table.

Command Syntax

DependAuto

Menu Location

Press:

  1. 2nd TBLSET to access the table settings menu.
  2. Use arrows and ENTER to select Auto from the Depend: line.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

When the DependAuto setting (opposed to the DependAsk setting) is turned on, values in the table are automatically calculated. With IndpntAuto, that means the table is automatically filled out completely; with IndpntAsk, that means that as soon as you enter a value for the independent variable, all the values of the dependent variables are calculated. This is usually the setting you want to use.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/dependauto


The det( Command
DET.GIF

Command Summary

Calculates the determinant of a square matrix.

Command Syntax

det(matrix)

Menu Location

Press:

  1. MATRX (83) or 2nd MATRX (83+ or higher) to access the matrix menu
  2. LEFT to access the MATH submenu
  3. ENTER to select det(.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The det( command calculates the determinant of a square matrix. If its argument is not a square matrix, ERR:INVALID DIM will be thrown.

Advanced Uses

If [A] is an N×N matrix, then the roots of det([A]-X identity(N)) are the eigenvalues of [A].

Formulas

For 2×2 matrices, the determinant is simply

(1)
\begin{align} \det\left( \begin{bmatrix} a & b\\c & d \end{bmatrix} \right) = \begin{vmatrix} a & b\\c & d \end{vmatrix} = ad-bc \end{align}

For larger matrices, the determinant can be computed using the Laplace expansion, which allows you to express the determinant of an n×n matrix in terms of the determinants of (n-1)×(n-1) matrices. However, since the Laplace expansion takes $O\left( n! \right)$ operations, the method usually used in calculators is Gaussian elimination, which only needs $O\left( n^3 \right)$ operations.

The matrix is first decomposed into a unit lower-triangular matrix and an upper-triangular matrix using elementary row operations:

(2)
\begin{pmatrix} {1}&{}&{}\\ {\vdots}&{\ddots}&{}\\ {\times}&{\cdots}&{1}\end{pmatrix} \begin{pmatrix}{\times}&{\cdots}&{\times}\\ {}&{\ddots}&{\vdots}\\ {}&{}&{\times} \end{pmatrix}

The determinant is then calculated as the product of the diagonal elements of the upper-triangular matrix.

Error Conditions

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/det


The DiagnosticOff Command
DIAGNOSTICOFF.GIF

Command Summary

Changes settings so that the correlation variables, r and r2, are not displayed when calculating a regression

Command Syntax

DiagnosticOff

Menu Location

Press:

  1. 2ND CATALOG to access the command catalog
  2. D to skip to commands starting with D
  3. Scroll down and select DiagnosticOff

(The DiagnosticOff command can't be found outside the catalog)

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

After the DiagnosticOff command is executed, all regression commands found in the STAT>CALC menu, as well as LinRegTTest, will not display the correlation statistics r and r2 (or just R2 in some cases). This is already turned off by default, although there is no disadvantage whatsoever to turning it on. To reverse this command, execute the DiagnosticOn command.

The statistic r, known as the correlation coefficient, measures the strength and direction of any linear relationship in the data (therefore if your regression model isn't linear, it may not exist, unless the calculator performed a transformation on the data). If r is close to 1, then the relationship is strong and positive (that is, the variables increase and decrease together). If r is close to -1, then the relationship is strong and negative (that is, as one variable increases, the other decreases). If r is close to 0, there is no linear relationship.

The statistic r2 or R2 is equal to the square of the above value (when it exists) and is also a measure of the strength of a relationship. Specifically, it represents the proportion of variance in the dependent variable that is accounted for by the regression model. If this value is close to 1, there is a strong relationship; if it's close to 0, there is either no relationship or the regression model doesn't fit the data.

Advanced

Although these statistics are a good indication of whether a regression curve is good or not, they are not infallible. For example, the initial portion of data that actually correlates exponentially may well appear linear and have a high correlation coefficient with a linear fit.

Another good way to check a regression curve is to look at the plot of the residuals vs. the x-values. If the regression curve is a good fit, then this plot should appear random in going from positive to negative. However, should you see a distinct pattern - say, if you tried a linear fit but the residual plot looks vaguely parabolic - you know you should try a different regression curve.

You should also consider what your regression line implies about the nature of the data and vice versa. For example, if you're comparing the height of release of a ball to the time it takes to fall, a natural assumption is that the regression curve should pass through (0,0), and a curve that doesn't do that may be incorrect. However, take this advice with a grain of salt: if your curve fits the data points you put in but not such natural-assumption points, that may simply mean that the curve works on a limited domain. Or, it may mean your assumptions are wrong.

Command Timings

Although the correlation statistics are not displayed with DiagnosticOff, they are calculated in either case. This means that DiagnosticOn and DiagnosticOff will not change how fast regressions are calculated.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/diagnosticoff


The DiagnosticOn Command
DIAGNOSTICON.GIF

Command Summary

Changes settings so that the correlation variables, r and r² (or R²), are displayed when calculating a regression

Command Syntax

DiagnosticOn

Menu Location

Press:

  1. 2ND CATALOG to access the command catalog
  2. D to skip to commands starting with D
  3. Scroll down and select DiagnosticOn

(The DiagnosticOn command can't be found outside the catalog)

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

After the DiagnosticOn command is executed, all regression commands found in the STAT>CALC menu, as well as LinRegTTest, will display the correlation statistics r and r² (or R2 for regressions that are not linear). This is turned off by default, but there is no disadvantage whatsoever to turning it on. To reverse this command, execute the DiagnosticOff command.

The statistic r, known as the Pearson correlation coefficient, measures the strength and direction of any linear relationship in the data. If r is close to 1, then the relationship is strong and positive (that is, the variables increase and decrease together). If r is close to -1, then the relationship is strong and negative (that is, as one variable increases, the other decreases). If r is close to 0, there is no linear relationship.

The statistic r² or R², known as the coefficient of determination, is equal to the square of the above value (when it exists) and is also a measure of the strength of a relationship. Specifically, it represents the proportion of variance in the dependent variable that is accounted for by the regression model. If this value is close to 1, there is a strong relationship; if it's close to 0, there is either no relationship or the regression model is not appropriate for the data.

Advanced

Although these statistics are a good indication of whether a regression curve is good or not, they are not infallible. For example, the initial portion of data that actually correlates exponentially may well appear linear and have a high correlation coefficient with a linear fit.

Another good way to check a regression curve is to look at the plot of the residuals vs. the x-values. If the regression curve is a good fit, then this plot should appear random in going from positive to negative. However, should you see a distinct pattern - say, if you tried a linear fit but the residual plot looks vaguely parabolic - you know you should try a different regression curve.

You should also consider what your regression line implies about the nature of the data and vice versa. For example, if you're comparing the height of release of a ball to the time it takes to fall, a natural assumption is that the regression curve should pass through (0,0), and a curve that doesn't do that may be incorrect. However, take this advice with a grain of salt: if your curve fits the data points you put in but not such natural-assumption points, that may simply mean that the curve works on a limited domain. Or, it may mean your assumptions are wrong.

Command Timings

Although the correlation statistics are displayed with DiagnosticOn, they are calculated in either case. This means that DiagnosticOn and DiagnosticOff will not change how fast regressions are calculated.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/diagnosticon


The Dialog Command

dialog.png

Command Summary

Displays a dialog box for input or output.

Command Syntax

:Dialog
(dialog elements)
:EndDlog

Menu Location

Starting in the program editor:

  • Press F3 to enter the I/O menu.
  • Press 1 to enter the Dialog submenu.
  • Press 5 to paste Dialog..EndDlog.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes for Dialog;
2 bytes for EndDlog.

A Dialog..EndDlog block is used to display a dialog box that can be used for input, output, or both. There are several commands that can be used inside Dialog..EndDlog to determine its content:

  • At most one Title instruction (to add a title).
  • Text (to add a line of text).
  • Request (to add a text entry box).
  • DropDown (to add a drop-down menu).

Except for the Title instruction, you can mix and match any number of these (as many as will fit on the screen), and their order will determine the order they are displayed. Finally, two "buttons" labeled Enter=OK and ESC=CANCEL will be displayed at the bottom of the dialog box.

Here is a typical dialog box to input a variable name:

:Dialog
: Title "Load file"
: Request "File name", name
: Text "(include folder name if not ""main"")"
:EndDlog

Advanced Uses

The system variable "ok" will detect if Enter or ESC was used to exit the dialog: it will have a value of 1 if Enter was used, and 0 for ESC.

This is particularly important when you're looking for input. If ESC is used, then the variables used in Request or DropDown will not be changed from what they were before (if they were undefined, they will remain undefined). It's probably a good idea to detect that sort of thing.

Error Conditions

230 - Dimension happens when the dialog would be too wide or too tall to fit on the screen.

470 - Invalid in Dialog..EndDlog block happens when instructions other than Title, Text, Request, DropDown are used.

590 - Invalid syntax block happens when something miscellaneous goes wrong, e.g. there is more than one Title.

730 - Missing start or end of block syntax happens when the Dialog is missing its EndDlog, or vice versa.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:dialog


The dim() Command

dim.png

Command Summary

Returns the size of a list, matrix, or string.

Command Syntax

dim(list-matrix-or-string)

Menu Location

  • Press 2nd MATH to enter the MATH menu.
  • Press D to enter the String submenu.
  • Press 3 to select dim(.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The dim() command returns the size of a list, matrix, or string:

  • The number of elements for a list.
  • The number of characters for a string.
  • A list of {number of rows or columns} for a matrix.

This command is critical to using any of these objects, for instance, if you want to write a For..EndFor loop to look at every element.

However, unlike the TI-83 series version, you can't use the dim() command to change the size of anything. Use mid() to get a smaller list or string (subMat() for a matrix), or use newList() and newMat() to create a list or matrix of a specific size.

:dim({1,2,3,4,5}
           5
:dim("TI-Basic Developer")
           18
:dim([1,2,3;4,5,6])
           {2  3}

Optimization

For matrices, using rowDim() and colDim() is usually better in all practical situations, and you don't have to remember which number goes first.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:dim


The dim( Command
DIM.GIF

Command Summary

Returns the size of a list or matrix. Can also be used to change the size.

Command Syntax

dim(list

dim(matrix

length→dim(list

{rows,columns→dim(matrix

Menu Location

Press:

  1. 2nd LIST to access the list menu
  2. RIGHT to access the OPS submenu
  3. 3 to choose dim(, or use arrows

Alternatively, press:

  1. MATRIX (83) or 2nd MATRIX (83+ or higher) to access the matrix menu
  2. RIGHT to access the MATH submenu
  3. 3 to choose dim(, or use arrows

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The dim( command is used to find the size of an existing list or matrix. It takes only one argument - the list or matrix you want the size of. For a list, it returns the number of elements; for a matrix, it returns a two-element list of the number of rows and the number of columns.

:dim(L1
    5
:dim([A]
    {2,3}

The dim( command can also be used to change the size of a list or matrix; this is perhaps its most important use. To do this, just store the desired size to the list or matrix (the dim( command is the only one you can store in as though it were a variable).

:7→dim(L1
:{2,2→dim([A]

For a list, if this increases the size, zero elements will be added to the end of the list; if this decreases the size, elements will be removed starting from the end.

For a matrix, if this increases the number of rows or columns, new rows or columns filled with zeros will be added to the bottom and right respectively. If this decreases the number of rows and columns, those rows and columns will be removed starting from the bottom (for rows) and right (for columns).

If a list or matrix doesn't exist before its size is changed, the dim( command will actually create it with the correct size. All the elements, in this case, will be set to 0.

Advanced Uses

In the case of lists, the dim( command is used in adding an element to the end of a list. Although augment( can be used for the same task, dim( is faster - but takes more memory. For example, to add the element 5 to the end of L1:

:5→L1(1+dim(L1

It's also possible, using the dim( command, to set the size of a list to 0. In this case, the list exists, but doesn't take up any memory, and cannot be used in expressions (similar to the output of ClrList). This is not really useful.

Optimization

When creating a list or matrix using dim(, all the elements are preset to 0; this can be used in place of the Fill( command to set a list or matrix to a bunch of zeros in a program. Since we don't usually know for sure that the list or matrix doesn't exist, we must first delete it with DelVar.

:{5,5→dim([A]
:Fill(0,[A]
can be
:DelVar [A]{5,5→dim([A]

Error Conditions

  • ERR:INVALID DIM is thrown if you try to make a list or matrix bigger than 999 or 99x99 elements respectively, or if you try to create a matrix that isn't 2-dimensional.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/dim


The Disp Command
DISP_ANIMATED.GIF

Command Summary

Displays an expression, a string, or several expressions and strings on the home screen.

Command Syntax

Disp [argument1,argument2,…]

Menu Location

While editing a program, press:

  1. PRGM to enter the PRGM menu
  2. RIGHT to enter the I/O menu
  3. 3 to select Disp (or use arrows to select)

Calculator Compatibility

TI-83/84/+/SE/CSE/CE

Token Size

1 byte

The first, and easiest, way to display text is using the Disp command. You can display whatever combination of text and values that you want. Text is displayed on the left side of the screen, while numbers, variables and expressions are displayed on the right side. Text can be moved over to the right by padding it with spaces, but there is no equivalent for numbers, variables, and expressions.

When displaying a matrix or a list, and the matrix or list is too large to display in its entirety, an ellipsis (…) is displayed at the boundaries of the screen. The matrix or list, unfortunately, cannot be scrolled so the rest of it can be seen (use the Pause command instead).

With the small screen size, you have to keep formatting in mind when displaying text. Because the text does not wrap to the next line if it is longer than sixteen characters, the text gets cut off and an ellipsis is displayed at the end of the line. When the text you want to display is longer than sixteen characters, you should break the text up and display each part with its own Disp command.

:Disp "Just Saying Hello
Break the text up
:Disp "Just Saying
:Disp "Hello

The Disp command displays text line by line, giving each argument its own blank line. If the screen is clear, the arguments are displayed beginning at the first line. But if there is text on the first line, the arguments are displayed beginning at the first available blank line. When all the lines have text on them including the last, the screen will automatically scroll up until every line is blank.

This means that, while a Disp command can technically display an unlimited amount of lines of text, you should not display more than seven consecutive lines of text at any one time (because of the screen height). If there are too many arguments, the arguments that were displayed will be pushed up out of sight, to allow the other arguments to be displayed. This is usually not desired, but it can be used to create some cool scrolling effects by messing with the text that you display.

The result is that you can never display text on the last line of the screen using the Disp command; you need to use the Output( command. (Using Output( does not have any affect on Disp and its text.) Also, if you have more than seven lines of text to display, you will need to place the Pause command after every seven lines to prevent the screen from scrolling. These two scenarios come up fairly often, so it is good to know how to deal with them.

PROGRAM:DISP
:ClrHome
:Disp A,B,C,D,E,F,G
:Pause
:Disp A,B,C,D,E,F,G
:Output(8,16,H

Like other text display commands, you can display each function and command as text. However, this is not without problems as each function and command is counted as one character. The two characters that you can't display are quotation marks (") and the store command (→). However, you can mimic these respectively by using two apostrophes (''), and two subtract signs and a greater than sign (—>).

Advanced Uses

You can use the Disp command by itself, which simply displays the home screen.

:Disp

When you use an empty string with no text (i.e., two quotes side by side — ""), a blank line is displayed.

:Disp ""

Optimization

When you have a list of Disp commands (and each one has its own argument), you can just use the first Disp command and combine the rest of the other Disp commands with it. You remove the Disp commands and combine the arguments, separating each argument with a comma. The arguments can be composed of whatever combination of text, numbers, variables, or expressions is desired.

The advantages of combining Disp commands are that it makes scrolling through code faster, and it is smaller when just displaying numbers, variables, or expressions. The disadvantages are that it can hinder readability (make the code harder to read) when you have lots of varied arguments, and it is easier to accidentally erase a Disp command with multiple arguments.

:Disp A
:Disp B
Combine the Disp commands
:Disp A,B

If you have a string of numbers that you are displaying, you do not need to put quotes around the numbers. This causes the numbers to be displayed on the right side of the screen, and they cease being a string. You may want to keep the numbers in a string, though, if they have any leading zeros. Because the numbers are no longer in a string, the leading zeros are truncated (taken off).

:Disp "2345
Remove the Quotes
:Disp 2345

Error Conditions

  • ERR:INVALID occurs if this statement is used outside a program.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/disp


The DispGraph Command
DISPGRAPH.GIF

Command Summary

Displays the graph screen.

Command Syntax

DispGraph

Menu Location

While editing a program, press:

  1. PRGM to access the program menu.
  2. RIGHT to access the I/O submenu.
  3. 4 to select DispGraph, or use arrows and ENTER.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The DispGraph command displays the graph screen, along with everything drawn or graphed on it.

In many cases, this doesn't need to be done explicitly: commands from the 2nd DRAW menu, as well as many other graph screen commands, will display the graph screen automatically when they are used. Mainly, it's used for displaying the graphs of equations or plots in a program — you would define the variable in question, then use DispGraph to graph it. For example:

:"sin(X)"→Y1
:DispGraph

Advanced Uses

DispGraph can also be used to update the graph screen, even if it's already being displayed. For example, changing the value of a plot or equation variable doesn't update the graph immediately. Consider this program:

:0→I
:"Isin(X)"→Y1
:DispGraph
:For(I,1,10)
:End

At first, it graphs the equation Y=Isin(X) with I=0. After this, I is cycled from 1 to 10. However, though the parameter I changes, the graph screen isn't updated, and only the initial graph of Y=0sin(X) and final graph of Y=10sin(X) are displayed. If, on the other hand, we change the program:

:0→I
:"Isin(X)"→Y1
:DispGraph
:For(I,1,10)
:DispGraph
:End

Now the DispGraph inside the loop ensures that the graph screen is updated every time, and the program will correctly display all eleven graphs.

Error Conditions

  • ERR:INVALID occurs if this statement is used outside a program.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/dispgraph


The DispTable Command
DISPTABLE.GIF

Command Summary

Displays the table screen.

Command Syntax

DispTable

Menu Location

While editing a program, press:

  1. PRGM to access the program menu
  2. RIGHT to select the I/O submenu
  3. 5 to select DispTable, or use arrows and ENTER

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The DispTable comand displays the table screen you normally see by pressing 2nd TABLE, from a running program. The user will see the table screen with a "paused" run indicator, and will be able to use arrows to scroll through it. Pressing ENTER will exit the screen and continue the program.

Advanced Uses

The user can't select any cells in the table to be evaluated if they're not, already. So it's best to select the IndpntAuto and DependAuto options from the 2nd TBLSET menu before using this command. IndpntAsk can also work, however, as long as you store to TblInput first.

Error Conditions

  • ERR:INVALID occurs if this statement is used outside a program.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/disptable


The ►DMS Command
DMS.GIF

Command Summary

Formats a displayed number as a degree-minute-second angle.

Command Syntax

value►DMS

Menu Location

Press:

  1. 2nd ANGLE to access the angle menu.
  2. 4 to select ►DMS, or use arrows and ENTER.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The ►DMS command can be used when displaying a real number on the home screen, or with the Disp and Pause commands. It will then format the number as an angle with degree, minute, and second parts.

30►DMS
    30°0'0"
100/9°►DMS
    11°6'40"

It will also work when displaying a number by putting it on the last line of a program by itself. It does not work with Output(, Text(, or any other more complicated display commands.

Although ►DMS is meant as a way to format angles in Degree mode, it doesn't depend on the angle mode chosen, only on the number itself. Note that entering a number as degree°minute'second" will also work, in any mode, and it will not be converted to radians in Radian mode.

Rounding to Nearest Second

If you'd prefer to not have seconds with decimal places, you can round your answer to the nearest second with the following formula:

round(Ans*3600,0)/3600►DMS

Or a slightly shorter version:

round(Ans36,2)/36►DMS

Tip: If you find yourself needing this formula regularly, put it into a Y= graphing-function as:

Y1=round(X36,2)/36

And then you can call it from your home screen via:

Y1(123.45678►DMS

Error Conditions

  • ERR:SYNTAX is thrown if the command is used somewhere other than the allowed display commands.
  • ERR:DATA TYPE is thrown if the value is complex, or if given a list or matrix as argument.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/dms


The Dot Command
DOT.GIF

Command Summary

Sets all equations to use the dotted-line graphing style, and makes it the default setting.

Command Syntax

Dot

Menu Location

Press:

  1. MODE to access the mode menu.
  2. Use arrows to select Dot.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The Dot command sets all equations to use the disconnected "dotted-line" graph style: it calculates and draws points on the graph, but doesn't connect them. In addition, this graph style is made the default, so that when a variable is deleted it will revert to this graph style. The other possible setting for this option is Connected.

Compare this to the GraphStyle( command, which puts a single equation into a specified graph style.

The Connected and Dot commands don't depend on graphing mode, and will always affect all functions, even in other graphing modes. The exception to this is that sequence mode's default is always the dotted-line style, even when Connected mode is set. The Connected command will still change their graphing style, it just won't change the default they revert to.

In addition to graphing equations, this setting also affects the output of DrawF, DrawInv, and Tangent(.

Advanced Uses

Functions graphed using the dotted-line graph style are very strongly affected by the Xres setting (which determines how many points on a graph are chosen to be graphed). If Xres is a high setting (which means many pixels are skipped), functions in dotted-line mode will be made up of fewer points (in connected mode, this will also be the case, but because the points are connected this isn't as noticeable). You should probably set Xres to 1 if you're going to be using the dotted-line graph style — even 2 is pushing it.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/dot


The DrawF Command
DRAWF.GIF

Command Summary

Draws an expression in terms of X.

Command Syntax

DrawF expression

Menu Location

Press:

  1. 2nd PRGM to access the draw menu.
  2. 6 to select DrawF, or use arrows and ENTER.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The DrawF commands draws a single expression on the graph screen in terms of X using Func graphing mode, regardless of what graphing mode the calculator is actually in. For example, DrawF X² will draw a parabola in the shape of a U on the screen. Of course, how it is displayed all depends on the window dimensions of the graph screen; you should use a friendly window to ensure it shows up as you intend.

Advanced Uses

DrawF will update X and Y for each coordinate drawn (like Tangent( and DrawInv), and exit with the last coordinate still stored.

When evaluating the expression using DrawF, the calculator will ignore the following errors: ERR:DATA TYPE, ERR:DIVIDE BY 0, ERR:DOMAIN, ERR:INCREMENT, ERR:NONREAL ANS, ERR:OVERFLOW, and ERR:SINGULAR MAT. If one of these errors occurs, the data point will be omitted.

For this reason, DrawF can sometimes behave in an unexpected fashion: for example, it doesn't throw an error for list or matrix expressions (it won't graph anything, either).

You can use DrawF to draw an expression instead of having to store an expression to a Y# variable and then displaying it. At the same time, if you plan on manipulating the expression (either changing the value or changing the expression itself), it would be better to simply use the Y# variable.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/drawf


The DrawInv Command
DRAWINV.GIF

Command Summary

Draws the inverse of a curve in terms of X.

Command Syntax

DrawInv curve

Menu Location

Press:

  1. 2nd DRAW to access the draw menu.
  2. 8 to select DrawInv, or use arrows and ENTER.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The DrawInv command draws the inverse of a curve in terms of X. Its single argument is an expression in terms of X.

For example, DrawInv X² will draw the inverse of the equation Y=X2. The inverse reverses the variables X and Y, so that the curve X=Y2 will be graphed. In this case, the inverse of the function has a simple form: Y=√(X) and Y=-√(X); most functions, however, do not have an inverse expressible as Y= equation, making this command particularly useful.

You can also think of this as graphing the expression but with X representing the vertical direction, and Y representing the horizontal.

DrawInv requires the calculator to be in Func mode, and is affected by the Connected/Dot setting.

Advanced Uses

DrawInv will update X and Y for each coordinate drawn (like Tangent( and DrawF), and exit with the last coordinate still stored.

When evaluating the expression using DrawInv, the calculator will ignore the following errors: ERR:DATA TYPE, ERR:DIVIDE BY 0, ERR:DOMAIN, ERR:INCREMENT, ERR:NONREAL ANS, ERR:OVERFLOW, and ERR:SINGULAR MAT. If one of these errors occurs, the data point will be omitted.

For this reason, DrawInv can sometimes behave in an unexpected fashion: for example, it doesn't throw an error for list or matrix expressions (it won't graph anything, either).

Error Conditions

  • ERR:MODE is thrown if the calculator is not in Func mode when using DrawInv.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/drawinv


The DS<( Command
DS_ANIMATED.gif

Command Summary

Decrements a variable by 1 and skips the next command if the variable is less than the value.

Command Syntax

DS<(variable,value)
command

Menu Location

While editing a program, press:

  1. PRGM to enter the PRGM menu
  2. ALPHA APPS (or 'B') to choose DS<(, or use arrows

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The decrement and skip if less than command — DS<( — is a specialized conditional command. It is equivalent to an If conditional, except the next command will be skipped when the condition is true and it has a variable update built-in. However, it is not used very often (if anything, it is often misused as a looping command) because of its obscure name and somewhat limited application.

The DS<( command takes two arguments:

  • A variable, which is limited only to one of the real variables (A-Z or θ).
  • A value, which can be any expression which evaluates to a real number.

When DS<( is executed it subtracts one from the variable (decrements it by one), and compares it to the value. The next command will be skipped if the variable is less than the value, while the next command will be executed if the variable is greater than or equal to the value.

The command DS<(A,B is equivalent to the following code:

:A-1→A
:If A≥B

Here are the two main cases where the DS<( command is used:

:5→A
:DS<(A,6
:Disp "Skipped
  • Initializes A to 5 and then compares to the value
  • 5<6 is true so the display message won't be displayed
:3→B
:DS<(B,2
:Disp "Not Skipped
  • Initializes B to 3 and then compares to the value
  • 3<2 is false so the display message will be displayed

Note: In addition to both of these cases, there is also the case where the variable and the value are equal to each other. This case is shown below under the 'Advanced Uses' section because it has some added background that goes with it.

Advanced Uses

When you want the skipping feature of the DS<( command to always occur, you just have to use the same variable for both the variable and value arguments of the command:

:DS<(B,B

An undefined error will occur if the variable and/or value doesn't exist before the DS<( command is used, which happens when the DelVar command is used. Consequently, you should not use DelVar with DS<(.

A similar code can be used as a substitute for B-1→B if you don't want to change Ans:

:DS<(B,B:

Note that due to the colon after the line, there will be no statement skipped, so you don't have to worry about that.

Optimization

If a program needs to decrement a positive variable, DS<( is one byte smaller than than decrementing a variable normally.

:A-1→A
can be
:DS<(A,0

The one caution about this is that if the variable is less than the value (in this case, '0'), the next command will be skipped. If you don't want the skipping functionality, then it is necessary to make sure that the value is never greater than the variable. Also, DS<( is slower than its more often used counterpart.

Related to the example code given, DS<( should always have a command following after it (i.e. it's not the last command in a program) because it will return an error otherwise. If you have no particular code choice, an empty line will suffice.

code that will run
:DS<(A,0
:
more code that will run

Command Timings

Using DS<( to decrement a variable is approximately 25% slower than using code like X-1→X. However, it is faster to use DS<( than to construct an If statement to do the same thing.

Note, however, that a quirk in the For( command (see its Optimization section) will slow down the DS<( command significantly if a closing parenthesis is not used for the For( statement.

Error Conditions

  • ERR:INVALID occurs if this statement is used outside a program.
  • ERR:SYNTAX is thrown if there is no next line to skip.
  • ERR:UNDEFINED is thrown if the variable to be decremented is not defined.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/ds


The e^( Command
EPOWER.GIF

Command Summary

Raises the constant e to the value power.

Command Syntax

e^(value)

Menu Location

Press [2nd] [ex] to paste e^(.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The e^( command raises the constant e to a power. Since it's possible to just type out e, ^, and (, the reason for having a separate function isn't immediately obvious but in fact most of the time you need to use e, it's to raise it to a power.

The trigonometric and hyperbolic functions can be expressed, and in fact are usually defined, in terms of e^(.

e^( accepts numbers and lists (but unfortunately not matrices) as arguments. It also works, and is often used for, complex numbers (in fact, one of the standard forms of complex numbers on TI-83 series calculators is re^θi, which uses the e^( function)

e^(2)
        7.389056099
e^(πi)
        -1
e^({-1,0,1})
        {.3678794412 1 2.718281828}

Formulas

The e^( is usually defined by an infinite series:

(1)
\begin{align} e^x=\sum_{n=0}^\infty{\frac{x^n}{n!}} \end{align}

This is then used to define exponentiation in general (for all real and even complex numbers), rather than using some sort of definition of exponents that involves multiplying a number by itself many times (which only works for integers).

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/e-exponent


The e Command
E.PNG

Command Summary

The mathematical constant e.

Command Syntax

e

Menu Location

Press 2nd e to paste e.

Calculator Compatibility

TI-83/84/+/SE/CSE/CE

Token Size

2 bytes

e is a constant on the TI-83 series calculators. The constant holds the approximate value of Euler's number, fairly important in calculus and other higher-level mathematics.

The approximate value, to as many digits as stored in the calculator, is 2.718281828459…

The main use of e is as the base of the exponential function e^( (which is also a separate function on the calculator), and its inverse, the natural logarithm ln(. From these functions, others such as the trigonometric functions (e.g. sin() and the hyperbolic functions (e.g. sinh() can be defined. In re^θi mode, e is used in an alternate form of expressing complex numbers.

Important as the number e is, nine times out of ten you won't need the constant itself when using your calculator, but rather the e^( and ln( functions.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/e-value


The E Command
E.GIF

Command Summary

The E symbol is used for entering numbers in scientific notation.

Command Syntax

mantissa E exponent

Menu Location

Press [2nd][EE] to paste the E command.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The E symbol is used for entering numbers in scientific notation: it's short for *10^. This means that in many cases, its function is identical to that of the 10^( command (aside from the parenthesis). However, the exponent of E is limited to constant integer values ‾99 to 99.

The E symbol is used in display by the calculator for large numbers, or when in Sci (scientific) or Eng (engineering) mode.

Unlike the exponent of E, the mantissa (a special term for the A in A*10^B, in scientific notation) isn't limited in variable type: it can be a constant, a real or complex variable or expression, a list, a matrix, or even omitted entirely (and then it will be assumed to equal 1). The reason for this versatility is simple: internally, only the exponent is taken to be an actual argument for this command. The rest of the calculation is done through implied multiplication.

5E3
………………5000
E‾5
……………….00001

Advanced Uses

E99 and -E99 are often used for negative and positive infinity because the TI-83 series of calculators doesn't have an infinity symbol. Commands that often need to use infinity include solve(, fnInt(, normalcdf( (and the other distributions), and many others. The error introduced in this way is usually irrelevant, because it's less than the minimum calculator precision, anyway: E99 is mindbogglingly huge.

Optimization

Don't add the mantissa when it's 1:

1E5
should be
E5

In addition, E2 or E3 can be used as shorthand ways of writing 100 and 1000 respectively. This could be continued, in theory, for higher powers of 10, but those aren't necessary as often.

Command Timings

E is much faster than using the 10^( command or typing out 10^. The drawback, of course, is that it's limited to constant values.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/e-ten


The ►Eff( Command
EFF.GIF

Command Summary

Converts a nominal interest rate to an effective interest rate.

Command Syntax

►Eff(interest rate,compounding periods)

Menu Location

On the TI-83, press:

  1. 2nd FINANCE to access the finance menu.
  2. ALPHA C to select ►Eff(.

On the TI-83+ or higher, press:

  1. APPS to access the applications menu.
  2. ENTER or 1 to select Finance…
  3. ALPHA C to select ►Eff(.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The ►Eff( command converts from a nominal interest rate to an effective interest rate. In other words, it converts an interest rate that does not take into account compounding periods into one that does. The two arguments are 1) the interest rate and 2) the number of compounding periods.

For example, take an interest rate of 7.5% per year, compounded monthly. You can use ►Eff( to find out the actual percent of interest per year:

►Eff(7.5,12)
    7.663259886

Formulas

The formula for converting from a nominal rate to an effective rate is:

(1)
\begin{align} \operatorname{Eff}=100\left(\left(1+\frac{\operatorname{Nom}}{100 \operatorname{CP}}\right)^{\operatorname{CP}}-1\right) \end{align}

Here, Eff is the effective rate, Nom is the nominal rate, and CP is the number of compounding periods.

Error Conditions

  • ERR:DOMAIN is thrown if the number of compounding periods is not positive, or if the nominal rate is -100% or lower (an exception's made for the nominal rate if there is only one compounding period, since ►Eff(X,1)=X)

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/eff


The End Command
FOR_ANIMATED.gif

Command Summary

Indicates the end of a block of statements.

Command Syntax

If condition
Then
statement(s)
End

While condition
statement(s)
End

Repeat condition
statement(s)
End

For(variable,start,end[,step])
statement(s)
End

Menu Location

While editing a program, press:

  1. PRGM to enter the PRGM menu
  2. 7 to choose End, or use arrows

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The End command is used together with the different control structures, including the If conditional, While loop, Repeat loop, and For( loop, to indicate the end of the code block for the respective control structure. In the case of the If conditional, you also need to add a Then command, which is used to indicate the beginning of the control structure.

Advanced Uses

You can prematurely end a control structure by using a single If conditional and then having End be its executed command. Because the calculator stores the positions of the End commands, it will take this End command to be the End command of the control structure.

:If <condition>
:End

One of the most important features of the End command is putting multiple control structures inside of each other (known as nesting). While you typically nest If conditionals inside of loops, you can actually nest any control structure inside of any other control structure — this even works when using the same control structure, such as a While loop inside of another While loop.

When nesting control structures, you need to remember to put the appropriate number of End commands to close the appropriate structure. The easiest way to keep track of lots of nested control structures is to code the first part, add an End immediately after the beginning, and then hit 2nd DEL on the line with the End, then hit ENTER a lot of times.

Error Conditions

  • ERR:INVALID occurs if this statement is used outside a program.
  • ERR:SYNTAX occurs if this statement is used before a logic block has been initiated.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/end


The Eng Command
ENG.GIF

Command Summary

Puts the calculator in engineering notation mode.

Command Syntax

Eng

Menu Location

While editing a program, press:

  1. MODE to access the mode menu.
  2. Use arrows and ENTER to select Eng.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The Eng command puts the calculator in engineering notation mode. This is a variation on scientific notation in which the exponent is restricted to be a multiple of 3 (and the mantissa can range between 1 and 1000, not including 1000 itself)

Eng
        Done
12345
        12.345e3
{1,2,3}
        {1e0 2e0 3e0}

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/eng


The Equ►String( Command
EQUSTRING.GIF

Command Summary

Stores the contents of an equation variable to a string.

Command Syntax

Equ►String(equation,string

Menu Location

This command is found only in the catalog. Press:

  1. 2nd CATALOG to access the catalog
  2. F to skip to commands starting with F
  3. Scroll up to Equ►String( and select it.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

This command stores the contents of an equation variable (such as Y1 or X1T) to a string (one of Str0, Str1, … Str9). This can be used when you want to display the equation as text (either using the Text( command on the graph screen, or the Output( or Disp commands on the home screen). For example:

:Equ►String(Y1,Str1
:Text(0,0,"Y1(X)=",Str1

Apart from cases in which the user has already stored to the equation variable prior to running the program, about the only situation in which you would use Equ►String( is for the output of a regression.

Advanced

You can use Equ►String( (outside a program) to get the or " symbols in a string:

  1. Type them on the home screen and press [ENTER]
  2. Select 2:Quit when the ERR:SYNTAX comes up.
  3. Press [Y=] to go to the equation editor.
  4. Press [2nd] [ENTRY] to recall the symbols to Y1
  5. Now, use Equ►String(Y1,Str1) to store the symbols to a string.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/equ-string


The ExecLib Command
OPENLIB.png

Command Summary

Calls a library routine from an application opened with OpenLib(

Command Syntax

ExecLib

Menu Location

This command can be found in the Prgm Editor CTL menu, press:

  1. Press "PRGM" while in the Program Editor.
  2. Go to the last command and press "Enter".

Calculator Compatibility

TI-84+/SE

Token Size

2 bytes

Together with OpenLib(, ExecLib is used on the TI-84 Plus and TI-84 Plus SE for running routines from a Flash App library. This only works, of course, with libraries that have been specifically written for this purpose. The only such library so far is usb8x, for advanced interfacing with the USB port.

Since ExecLib doesn't have any arguments, it would normally be able to run only one library routine. To get around this, usb8x uses a list passed in Ans as arguments to the command. This is most likely how any future libraries will do it as well.

The following program, which displays the version of usb8x, is an example of how to use OpenLib( and ExecLib:

:OpenLib(USBDRV8X
:{6
:ExecLib
:Ans(2)+.01Ans(3

Download usb8x here. You may also be interested in MSD8x which is a GUI for usb8x.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/execlib


The Exit Command

exit.png

Command Summary

Exits a loop.

Command Syntax

:Exit

Menu Location

Starting in the program editor:

  • Press F2 to enter the Control menu.
  • Press 8 to enter the Transfers submenu.
  • Press 5 to select Exit.

Calculator Compatibility

This command works on all calculators.

Token Size

4 bytes

The Exit command immediately exits from a For..EndFor, Loop..EndLoop, or While..EndWhile loop. The program continues running from the instruction after the EndFor, EndLoop, or EndWhile.

Exit is especially useful for Loop..EndLoop, because the loop won't ever end if you don't give it a reason to. For example:

:Loop
: Input "Number 1-100",num
: If 1≤num and num≤100
:  Exit
: Disp "Number out of range!"
:EndLoop

Often, a Loop..EndLoop block with an Exit inside it isn't a very good idea, because it can be replaced by a While..EndWhile block. However, in the example above, there is a difference: the condition for exiting the loop is not checked at the beginning. A While..EndWhile loop that did the same thing would have to initialize the num variable first.

If there are multiple loops, one nested inside the other, the Exit command only exits out of the innermost one.

The Exit command can also be used to exit a sub-routine (very helpful when using subroutines on a 'skeleton' during development)

Optimization

Although Goto can also be used to exit out of a loop, the Exit command is faster: it knows where the end of the loop is, but a Goto command has to search through the entire program to find its label.

However, the Goto command is more versatile, since it can jump anywhere in the program, not just immediately after the loop. In particular, Goto can be used to exit multiple loops at once.

Error Conditions

560 - Invalid outside Loop..EndLoop, For..EndFor, or While..EndWhile blocks happens when the Exit command is not inside a loop.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:exit


The expr() Command

expr.png

Command Summary

Runs code stored inside a string.

Command Syntax

expr(string)

Menu Location

  • Press MATH to enter the MATH popup menu.
  • Press D to enter the Strings submenu.
  • Press 2 to select expr(.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

The expr() command runs code stored inside a string: for instance, expr("5→x") has the same effect as 5→x. The main use of expr() is with user input: the input you get from some commands comes in a string, and you might use expr() to convert it back to a number.

The other advantage of using expr() is that you can paste together code as the program is running, to run something you couldn't possibly have put in the program ahead of time. For instance, you might paste together a Dialog..EndDlog block whose elements might be different every time you run the program.

:expr("5→x")
           5
:expr("25")
          25

The expr() command is somewhat limited in what it is allowed to do. For instance, if a string contains a variable name, expr() of that string returns the value of that variable; to refer to the variable itself, use the # (indirection) operator.

Another limitation is that expr() cannot contain commands that aren't allowed on the home screen, even if you're running it from a function or program. For example, Local will cause an error in expr().

Finally, in some respects expr() is actually running in its own program. It will still be able to access local variables from outside the expr(), but Lbl and Goto are limited — you can't jump out of expr() with them, nor can you jump in.

Advanced Uses

It's best to use expr() sparingly. Characters inside a string are ignored during tokenization, so they will take up more space than actual commands, and there will be a short delay before the code inside expr() can run.

This also causes problems with language localization. Normally, once a command is tokenized, it will work in any language. However, with expr(), code is tokenized on the spot, so it will depend on the language being the same. If your program was written using English language localization, it will not work for someone who's working in German, Spanish, or French.

Error Conditions

550 - Invalid outside function or program happens when the string contains commands that need to be inside a function or a program to work.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:expr


The expr( Command
EXPR.GIF

Command Summary

Returns the value of a string that contains an expression.

Command Syntax

expr(string)

Menu Location

This command is found only in the Catalog. Press:

  1. 2ND CATALOG to enter the catalog
  2. F to go to commands starting with F
  3. Scroll up a bit to expr(.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The expr( command is used to evaluate an expression that's stored in a string (an expression is merely anything that returns a value - of any type). Expressions are occasionally stored to strings, rather than evaluated outright, so that their value has the capacity to change when the variables stored inside them change. The expr( command's result depends on the kind of expression that's in the string you pass it — it may return a number, a list, a matrix, or even another string.

As a special case of an expression, the expr( command can also be used to convert a string like "123" to the number 123. Going in the reverse direction (123 to "123") is more complicated.

The expr( command has limitations. Here are the situations in which expr( will not work:

  • When the code in the string does not return an answer, and thus is not an expression: e.g. expr("Line(0,0,1,1" or expr("prgmHELLO" is invalid
  • When the expression in the string contains an expr( command itself, e.g. expr("expr(Str1" — this will throw an ERR:ILLEGAL NEST error.
  • In place of a variable (rather than an expression), e.g. 5→expr("X" isn't a substitute for 5→X because expr("X" evaluates to the value of X and not to X itself.

Advanced Usage with Lists

expr( is often used in conjunction with the Input command to prompt the user to enter a list. Although the Input command can already handle lists, it requires the user to enter the opening bracket that signifies a list. With expr(, this can be avoided.

If you want the user to enter a list separated by commas, instead of:

Input L₁

Use this:

Input Str1
expr("{"+Str1→L₁

This will automatically put the curly bracket in so the user does not have to.

Just be aware that you cannot access individual list items directly after the expr() function, unlike how you can with Ans. The following code will multiply the entire list by 2 rather than return the second item:

expr("{1,2}")(2)

Instead, to access the second item in the list you could split this across two lines and use Ans:

expr("{1,2}")
Ans(2)

Optimization

Evaluating an expression inside a string is more complicated than evaluating a normal expression; you should therefore try to take as much out of an expr( statement as possible to speed up your code. For example:

expr("sum({"+Str1

can be:

sum(expr("{"+Str1

Error Conditions

  • ERR:ILLEGAL NEST is thrown when the string to be evaluated contains an expr( itself.
  • ERR:INVALID is thrown when trying to evaluate the empty string.
  • ERR:SYNTAX is thrown when trying to evaluate a command that doesn't return a value.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/expr


The ExpReg Command
EXPREG.GIF

Command Summary

Calculates the best fit exponential curve through a set of points.

Command Syntax

ExpReg [x-list, y-list, [frequency], [equation]

Menu Location

Press:

  1. STAT to access the statistics menu
  2. LEFT to access the CALC submenu
  3. 0 to select ExpReg, or use arrows

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

ExpReg tries to fit an exponential curve (y=a*bx) through a set of points. To use it, you must first store the points to two lists: one of the x-coordinates and one of the y-coordinates ordered so that the Nth element of one list matches up with the Nth element of the other list. L₁ and L₂ are the default lists to use, and the List Editor (STAT > Edit…) is a useful window for entering the points.

The calculator does this regression by taking the natural log ln( of the y-coordinates (this isn't stored anywhere) and then doing a linear regression. The result, ln(y)=ln(a)+x*ln(b), is transformed into y=eln(a)(eln(b))x, which is an exponential curve. This algorithm shows that if any y-coordinates are negative or 0, the calculator will instantly quit with ERR:DOMAIN.

In its simplest form, ExpReg takes no arguments, and fits an exponential curve through the points in L₁ and L₂:

:{9,13,21,30,31,31,34→L₁
:{260,320,420,530,560,550,590→L₂
:LnReg

On the home screen, or as the last line of a program, this will display the equation of the curve: you'll be shown the format, y=a*b^x, and the values of a and b. It will also be stored in the RegEQ variable, but you won't be able to use this variable in a program - accessing it just pastes the equation wherever your cursor was. Finally, the statistical variables a, b, r, and r² will be set as well. These latter two variables will be displayed only if "Diagnostic Mode" is turned on (see DiagnosticOn and DiagnosticOff).

You don't have to do the regression on L₁ and L₂, but if you don't you'll have to enter the names of the lists after the command. For example:

:{9,13,21,30,31,31,34→FAT
:{260,320,420,530,560,550,590→CALS
:ExpReg ∟FAT,∟CALS

You can attach frequencies to points, for when a point occurs more than once, by supplying an additional argument - the frequency list. This list does not have to contain integer frequencies. If you add a frequency list, you must supply the names of the x-list and y-list as well, even when they're L₁ and L₂.

Finally, you can enter an equation variable (such as Y₁) after the command, so that the curve's equation is stored in this variable automatically. This doesn't require you to supply the names of the lists, but if you do, the equation variable must come last. You can use polar, parametric, or sequential variables as well, but since the equation will be in terms of X anyway, this doesn't make much sense.

An example of ExpReg with all the optional arguments:

:{9,13,21,30,31,31,34→FAT
:{260,320,420,530,560,550,590→CALS
:{2,1,1,1,2,1,1→FREQ
:ExpReg ∟FAT,∟CALS,∟FREQ,Y1

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/expreg


The ExprOff Command
EXPROFF.GIF

Command Summary

The number of the equation or plot being traced is displayed in the top right corner.

Command Syntax

ExprOff

Menu Location

Press:

  1. 2nd FORMAT to access the graph format menu
  2. Use arrows and ENTER to select ExprOff

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The ExprOff command enables a "short" form of displaying the equation or plot being traced. That is, only the number of the equation or plot will be displayed, in the top right corner of the screen. When tracing a plot, the number will be prefixed with a P to distinguish it from an equation.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/exproff


The ExprOn Command
EXPRON.GIF

Command Summary

The equation or plot being traced is displayed in long form at the top of the screen.

Command Syntax

ExprOn

Menu Location

Press:

  1. 2nd FORMAT to access the graph format menu
  2. Use arrows and ENTER to select ExprOn

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The ExprOn command enables a "long" form of displaying the equation or plot being traced.

In this mode, when tracing an equation, the equation's name and its formula are written in small font at the top of the screen. For example, when tracing Y1 which is equal to 2X, "Y1=2X" will be displayed.

When tracing a plot, the plot number is written, followed by the list or lists that it describes. For example, when tracing Plot1, which is a scatter plot of ∟X and ∟Y, "P1:X,Y" will be displayed.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/expron


The Fcdf( Command
FCDF.GIF

Command Summary

Calculates the F-distribution probability betwen lower and upper for specified numerator and denominator degrees of freedom.

Command Syntax

Fcdf(lower, upper, numerator df, denominator df

Menu Location

Press:

  1. 2ND DISTR to access the distribution menu
  2. 9 to select Fcdf(, or use arrows.

Press 0 instead of 9 on a TI-84+/SE with OS 2.30 or higher.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

Fcdf( is the F-distribution cumulative density function. If some random variable follows this distribution, you can use this command to find the probability that this variable will fall in the interval you supply.

The arguments lower and upper express the interval you're interested in. The arguments numerator df and denominator df, often written d1 and d2, specify the F-distribution, written as F(d1,d2).

Advanced

Often, you want to find a "tail probability" - a special case for which the interval has no lower or no upper bound. For example, "what is the probability x is greater than 2?". The TI-83+ has no special symbol for infinity, but you can use E99 to get a very large number that will work equally well in this case (E is the decimal exponent obtained by pressing [2nd] [EE]). Use E99 for positive infinity, and -E99 for negative infinity.

Formulas

As with other continuous distributions, Fcdf( can be expressed in terms of the probability density function:

(1)
\begin{align} \operatorname{Fcdf}(a,b,d_1,d_2) = \int_a^b \operatorname{Fpdf}(x,d_1,d_2) \, dx \end{align}

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/fcdf


The ►F◄►D Command
FD2.gif

Command Summary

Converts a number between fraction form and decimal form.

Command Syntax

number►F◄►D

Menu Location

Press:

  1. MATH
  2. RIGHT to NUM
  3. ALPHA B

Alternatively, access the catalog.

Calculator Compatibility

TI-84 2.53MP only

Token Size

2 bytes

The ►F◄►D command is used to convert a number from fraction form to decimal form, or vice versa. Regardless of what form the given number is, this command is meant to automatically determine the form so that it returns the other. It is in essence a combination of the ►Frac and ►Dec commands, applying ►Frac if the input is in decimal form and ►Dec if it is a fraction.

7.5►F◄ ►D
        15/2
Ans►F◄ ►D
        7.5

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/f-d


The Fill( Command
FILL.GIF

Command Summary

Fills a list or matrix with one number.

Command Syntax

Fill(value,matrix)

Menu Location

Press:

  1. 2nd LIST to access the list menu.
  2. RIGHT to access the OPS submenu.
  3. 4 to select Fill(, or use arrows.

Alternatively, press:

  1. MATRX (83) or 2nd MATRX (83+ or higher) to access the matrix menu.
  2. RIGHT to access the MATH submenu.
  3. 4 to select Fill(, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The Fill( command takes an existing list or matrix variable and sets all its elements to a single number. It doesn't return anything and only works on already defined variables.

{5}→dim(L1)
Fill(2,L1)
L1
    {2 2 2 2 2}

{3,4}→dim([A])
Fill(1,[A])
[A]
    [[1 1 1 1]
     [1 1 1 1]
     [1 1 1 1]]

Fill( is very fast: on a twenty-element real list, it takes only about 3.5 ms, much less than any vectorized list operation.

When Fill( is called on a list, the datatype of the list becomes the datatype of the number. That is, Fill(1,L₁) makes L₁ a real list, and Fill(i,L₁) makes L₁ a complex list.

Optimization

When creating a new list or matrix you want to fill with zeroes, it's better to delete it then create it with dim(, which will set all entries to 0, than to set its dimensions with dim( (which may not clear what was there before) then use Fill(.

Errors

On a TI-84+CSE, using Fill(List,List) will cause a RAM clear. For example: Fill({1,2,3},{1,2,3} will cause a RAM Clear. This does not apply on any other models, as they only give you argument and data type errors.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/fill


The Fix Command
FIX.GIF

Command Summary

Puts the calculator in fixed-point display mode, displaying value digits after the decimal.

Command Syntax

Fix value

Menu Location

While editing a program, press:

  1. MODE to access the mode menu.
  2. Use arrows to select a number 0-9 from the 2nd line.

This will paste Fix number. Outside a program, it will simply put the calculator in the appropriate mode.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The Fix command puts the calculator in fixed-point display mode: all numbers will be displayed with a fixed number of digits (0-9) after the decimal, depending on the the number following the Fix command.

For example, after running the command Fix 3:

  • 1 will be displayed as 1.000
  • 3.14156 will be displayed as 3.142 (rounded to 3 decimal places)

This could be useful if you're trying to display potentially fractional numbers in a limited amount of space.

Use the Float command to undo the Fix command and only display decimal places when needed.

Unfortunately there is no direct command in TI-Basic to retrieve the current Fix setting (i.e., the number of decimal places currently set for display).

A note on more technical aspects: first, if more digits are available than are displayed, the calculator will round off the displayed number (but not its stored value), so 3.97 will be displayed as 4 in Fix 1 mode. Second, the Fix command can't force more than 10 significant digits to be displayed, so something like 123456789.1 will only display one decimal digit even in Fix 9 mode.

Finally, note that the Float and Fix commands only change the way numbers are displayed—they are saved in the same way in each case. Even if you're in Fix 0 mode, the calculations are not done using integers, and in general, the calculations are still done using floating-point numbers no matter the number mode. The one exception is with regressions: if you store a regression to an equation in Fix N mode, it will truncate the numbers involved before storing them to the equation, and as a result, the equation will be different.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/fix


The Float Command
FLOAT.GIF

Command Summary

Puts the calculator in floating decimal display mode.

Command Syntax

Float

Menu Location

Press:

  1. MODE to access the mode menu.
  2. Use arrows and ENTER to select Float.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The Float command makes the calculator display numbers with a "floating decimal point" — only as many digits after the decimal as needed are displayed (so whole numbers, for example, are shown without any decimal points). This is the default mode, and usually the most useful.

A technicality of displaying real numbers on the calculator: A maximum of 14 significant digits are stored in a number, but only 10 of them are actually displayed (or used for comparisons) — the rest are used for additional precision. This means that if a number is displayed as a whole number, it isn't necessarily whole. For example, 1234567890.7 will be displayed as 1234567891 (rounded to 10 significant digits), and 1.0000000003 will be displayed as 1.

This makes sense from many perspectives: if you get a result of 1.0000000003 after a calculation, odds are that this should be 1, and isn't just because of a precision error. Because the extra digits are there, though, even if they're not displayed, such a number will still be invalid for functions such as Pxl-On( or sub( that want integer arguments, and this sort of error is hard to track down.

Finally, note that the Float and Fix commands only change the way numbers are displayed: they are saved in the same way in each case. Even if you're in Fix 0 mode, the calculations are not done using integers, and in general the calculations are still done using floating-point numbers no matter the number mode. The one exception is with regressions: if you store a regression to an equation in Fix N mode, it will truncate the numbers involved before storing them to the equation, and as a result, the equation will be different.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/float


The floor() Command

floor.png

Command Summary

Returns the floor of a number.

Command Syntax

floor(value)

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press 1 to enter the Number submenu.
  • Press 6 to select floor(.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The floor() command rounds a number down to the nearest integer less than or equal to the number. For instance, floor(π) returns 3, while floor(-π) returns -4.

The command is an alias for int(): they do the exact same thing. The calculator prefers using floor() (in fact, int() will be converted to floor() in symbolic expressions); int() is left over from earlier calculator models. Other rounding commands include:

  • ceiling() — like floor(), but always rounds up (to the next higher integer).
  • iPart() — truncates a number to just its integer part (or, if you prefer, rounds a number toward 0).
  • round() — rounds to a specific place value, not just to an integer, but round(x,0) will round x to the nearest integer, up or down.

floor() can also be applied to complex numbers, lists, and matrices, rounding everything that there is to round in each of them.

:floor(3)
           3
:floor({-π,π})
           {-4  3}

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:floor


The fMax( Command
FMAX.GIF

Command Summary

Calculates the local maximum of a function.

Command Syntax

fMax(f(var),var,lo,hi[,tol])

Menu Location

While editing a program, press:

  1. MATH to open the math menu
  2. 7 or use arrow keys to select

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

fMax(f(var),var,lo,hi[,tol]) finds the value of var between lo and hi at which the maximum of f(var) occurs. tol controls the accuracy of the maximum value computed. The default value of tol is 10-5.

fMax( only works for real numbers and expressions. Brent's method for optimization is used for approximating the maximum value.

fMax(sin(X)cos(X),X,0,3)
        .7853995667

Keep in mind that the result is the value of var, and not the value of f(var). In this example, .7853995667 is not the highest possible value of sin(X)cos(X), but rather the X-value at which sin(X)cos(X) is the highest.

Error Conditions

  • ERR:BOUND is thrown if the lower bound is greater than the upper bound.
  • ERR:DOMAIN is thrown if tol is 0.
  • ERR:TOL NOT MET is thrown if the tolerance is too small for this specific function.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/fmax


The fMin( Command
FMIN.GIF

Command Summary

Calculates the local minimum of a function.

Command Syntax

fMin(f(var),var,lo,hi[,tol])

Menu Location

While editing a program, press:

  1. MATH to open the math menu
  2. 6 or use arrow keys to select

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

fMin(f(var),var,lo,hi[,tol]) finds the value of var between lo and hi at which the minimum of f(var) occurs. tol controls the accuracy of the minimum value computed. The default value of tol is 10-5.

fMin( only works for real numbers and expressions. Brent's method for optimization is used for approximating the minimum value.

fMin(cos(sin(X)+Xcos(X)),X,0,2)
        1.076873875

Keep in mind that the result is the value of var, and not the value of f(var). In this example, 1.076873875 is not the lowest possible value of cos(sin(X)+Xcos(X)), but rather the X-value at which cos(sin(X)+Xcos(X)) is the lowest.

Advanced Uses

fMin( is sometimes useful in finding so-called "multiple roots" of a function. If the graph of your function appears "flat" near the root, fMin( might be able to find the value of the root more accurately than solve(.

Error Conditions

  • ERR:BOUND is thrown if the lower bound is greater than the upper bound.
  • ERR:DOMAIN is thrown if tol is 0.
  • ERR:TOL NOT MET is thrown if the tolerance is too small for this specific function.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/fmin


The fnInt( Command
FNINT.GIF

Command Summary

Approximately computes a definite integral.

Command Syntax

fnInt(f(var),var,a,b[,tol])

Menu Location

Press

  1. Press MATH to access the math menu.
  2. 9 to select fnInt(, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

fnInt(f(var),var,a,b[,tol]) computes an approximation to the definite integral of f with respect to var from a to b. tol controls the accuracy of the integral computed. The default value of tol is 10-5. fnInt( returns exact results for functions that are polynomials of small degree.

fnInt( only works for real numbers and expressions. The Gauss-Kronrod method is used for approximating the integral.

Tip: Sometimes, to get an answer of acceptable accuracy out of fnInt(, substitution of variables and analytic manipulation may be needed.

fnInt(1/X,X,1,2)
        .6931471806
fnInt(ln(X),X,0,1) <a difficult example>
        -.999998347
fnInt(ln(X),X,0,1,e-11)
        -1

Error Conditions

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/fnint


The FnOff Command
FNOFF.GIF

Command Summary

Turns off equations in the Y= editor (all of them, or only the ones specified)

Command Syntax

FnOff [integer] [,integer]

Menu Location

Press:

  1. VARS to access the variables menu.
  2. RIGHT to access the Y-VARS submenu.
  3. 4 to select On/Off…, or use arrows and ENTER.
  4. 2 to select FnOff, or use arrows and enter.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The FnOff command is used to turn off equations in the current graphing mode. When you turn off an equation, it's still defined, but isn't graphed; you can reverse this with the FnOn command. To turn functions on and off manually, put your cursor over the = symbol in the equation editor, and press enter.

When FnOff is used by itself, it will turn off all defined equations in the current graphing mode. You can also specify which equations to turn off, by writing their numbers after FnOff: for example, FnOff 1 will turn off the first equation, and FnOff 2,3,4,5 will off turn the second, third, fourth, and fifth. The numbers you give FnOff have to be valid equation numbers in the graphing mode. When turning equations on and off in sequence mode, use 1 for u, 2 for v, and 3 for w.

The most common use for FnOn and FnOff is to disable functions when running a program, so that they won't interfere with what you're doing on the graph screen, then enable them again when you're done.

Error Conditions

  • ERR:DOMAIN is thrown if an equation number isn't valid in the current graphing mode, or at all.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/fnoff


The FnOn Command
FNON.GIF

Command Summary

Turns on equations in the Y= editor (all of them, or only the ones specified)

Command Syntax

FnOn numbers//

Menu Location

Press:

  1. VARS to access the variables menu.
  2. RIGHT to access the Y-VARS submenu.
  3. 4 to select On/Off…, or use arrows and ENTER.
  4. ENTER to select FnOn.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The FnOn command is used to turn on equations in the current graphing mode. When you define an equation, it's turned on by default, but the FnOff command can turn an equation off (in which case, it's still defined, but isn't graphed). To turn functions on and off manually, put your cursor over the = symbol in the equation editor, and press enter.

When FnOn is used by itself, it will turn on all defined equations in the current graphing mode. You can also specify which equations to turn on, by writing their numbers after FnOn: for example, FnOn 1 will turn off the first equation, and FnOn 2,3,4,5 will turn the second, third, fourth, and fifth. The numbers you give FnOn have to be valid equation numbers in the graphing mode. When turning equations on and off in sequence mode, use 1 for u, 2 for v, and 3 for w.

The most common use for FnOn and FnOff is to disable functions when running a program, so that they won't interfere with what you're doing on the graph screen, then enable them again when you're done.

Error Conditions

  • ERR:DOMAIN is thrown if an equation number isn't valid in the current graphing mode, or at all.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/fnon


The For( Command
FOR_ANIMATED.gif

Command Summary

Executes some commands many times, with a variable increasing from start to end by step, with the default value step=1.

Command Syntax

For(variable,start,end[,step])
statement(s)
End

Menu Location

While editing a program press:

  1. PRGM to enter the PRGM menu
  2. 4 to choose For(, or use arrows
  3. 7 to choose End, or use arrows

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

A For( loop is generally used to do something a specific number of times or to go through each one of a bunch of things (such as elements of a list, or the pixels of your screen). Of all the loops, it's the most complicated. The syntax:

For(variable,start,end[,step]
statement(s)
End

What the loop does:

  1. Stores start to variable.
  2. If variable is greater than end (or less than, if step is negative), then the For( loop ends immediately.
  3. Runs the statement(s).
  4. Adds step to variable and returns to Step 2.

If no value for step is given, step is assumed to be 1.

In other words: a For( loop repeats its contents once for every value of variable between start and end.

This is perhaps best explained with an example. The following code will display the numbers 1 to 10, in order:

:For(A,1,10)
:Disp A
:End

Now, all of this could be done with a Repeat or While command and some manipulation, except that this is faster because it's a single command. Still, why have a separate command for something that seems so specific and arbitrary? Well, it's because For( has so many uses!

  • Do something to each element of a list, matrix, or string.
  • Draw several similar objects on the graph screen.
  • Create animations.
  • Easily add the possibility of levels to many games.
  • Any number of other things…

An advanced note: each time the program enters a For( loop, the calculator uses 43 bytes of memory to keep track of this. This memory is given back to you as soon as the program reaches End. This isn't really a problem unless you're low on RAM, or have a lot of nested For( statements. However, if you use Goto to jump out of a For( loop, you lose those bytes for as long as the program is running—and if you keep doing this, you might easily run out of memory, resulting in ERR:MEMORY.

Advanced Uses

Sometimes you want to exit out of a For( loop when it hasn't finished. You can do this by storing the end value to the variable you used in the For( loop. For example:

:For(A,1,100)
<some code>
:If <condition for exiting out>
:100→A
:End

For( can also be used to create a delay:

//delays for about 0.5 second (83+) or 0.2 second (83+SE/84+/SE/CSE)
:For(A,1,200)
:End

If X is end, the delay will be about X/1000 seconds for the TI-83/83+, and X/400 for other calculators.

Unlike delays that use rand, a For( loop delay can execute an animation or other code during the delay.


For( loops can be nested to execute code once for every combination of values of several variables. For example:

:For(A,1,50)
:For(B,1,50)
:(some code)
:End
:End

This will run (some code) 2500 times—once for every combination of a value of A from 1 to 50 and a value of B from 1 to 50.

There's a standard way to exclude repetitions if the order of the variables doesn't matter (for example, if A=30, B=40 is the same situation as A=40, B=30 in the example above). In this case, the beginning of the loop should be changed to:

:For(A,1,50)
:For(B,1,A)

On the CSE, a list index can be used as the variable in a For( loop. When this is done, the loop will operate and exit normally, but the list will not be affected. For instance, this program

:{1,2,3→L₁
:For(L₁(1),2,5
:Disp "X
:End
:Disp L₁

will output:
X
X
X
X
  {1,2,3}

For( loops can also be used to exceed the normal overflow limit of $10^{100}$ for variables and computations. For example, utilizing the optional step argument,

:For(A,9E99,9E99,9E99
:End

the value of A will be 1.8E100, which is otherwise impossible to assign to a variable by normal means. One could then use A as the step value for a For( command,

:For(A,A,A,A
:End

which doubles the value of A (so 1.8E100 becomes 3.6E100). This process can be repeated until the "true" overflow limit is reached at $10^{128}$ (since the calculator stores the exponent as a signed 8-bit integer, ranging from -128 to 127).

Optimization

The seq( command, or simple math, can often be used in place of the For( command when dealing with lists. For example:

:For(A,1,dim(L1
:cos(A)→L1(A
:End
//can be
:seq(cos(A),A,1,dim(L1→L1

and

:For(A,1,dim(L1
:1+L1(A→L1(A
:End
//can be
:1+L1→L1

One rather strange optimization when using For( loops is actually leaving on the ending parenthesis of the For( loop in certain cases. If you don't do this, the following cases will be processed much slower when they are the first line of code in the loop:

  • IS>( and DS<( (no matter if the following command is skipped or not).
  • A lone If without an accompanying Then, but only when the condition is false (If with a true condition is unchanged).

If the condition of the If command can be false (as in most actual cases), you should add a closing parenthesis because the difference is so great.

An example use of this optimization:

:For(I,1,1200
:If 0
:1
:End

//should be
:For(I,1,1200)
:If 0
:1
:End

Command Timings

Using a For( loop when it fits your purpose is much faster than adapting a While or Repeat loop to do so. Conclusion: For( loops are good!

Error Conditions

  • ERR:INCREMENT is thrown if the increment of the For( loop is 0.
  • ERR:INVALID occurs if this statement is used outside a program.
  • ERR:UNDEFINED is thrown if you DelVar the loop variable while inside the loop.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/for


The For Command

for.png

Command Summary

Repeats a block of code some number of times.

Command Syntax

:For counter, start, end, step
(block of code)
:EndFor

Menu Location

Starting in the program editor:

  • Press F2 to enter the Control menu.
  • Press 4 to paste For..EndFor.

Calculator Compatibility

This command works on all calculators.

Token Size

3 bytes for the For command;
4 bytes for EndFor.

A For..EndFor block is used to repeat the code inside the block some number of times. To specify the number of times to repeat this code, a counter variable is specified, along with a starting value and an ending value. The variable will be set to the starting value, then increased until it gets to the ending value, running the code inside the block each time. For example:

:For count, 1, 5
: Disp count
:EndFor
           1
           2
           3
           4
           5

You can also give a step size by which to increase the counter (the default is 1). In the above example, if the first line were changed to ":For count, 1, 5, 2" then the block would only run with count=1, then with count=3, then with count=5. You can even make the step size negative and decrease the counter from a maximum to a minimum (e.g. "For count, 5, 1, -1").

For loops are most useful when you want to look at every element of a list or matrix individually. For example, the following code will "do something" (depending on what you replaced the comment with) to every element of "list" in order:

:For i, 1, dim(list)
: © do something with list[i]
:EndFor

To look at every element of a matrix, you'd have to use two For loops, one inside the other:
:For i, 1, rowDim(matrix)
: For j, 1, colDim(matrix)
:  © do something with matrix[i, j]
: EndFor
:EndFor

Advanced Uses

The counter variable can be manipulated inside the For loop to produce different results. For example, the following code will count from 1 to 10 but skip 3:

:For i, 1, 10
: If i=3
:  i+1→i
: Disp i
:EndFor

What happens is that when the code runs for the third time, with i=3, the If statement increases i to 4. From there, the For loop thinks it's business as usual, and the next cycle will be done with i=5, then i=6, and so on.

Another way to manipulate the progress of a For loop is with the Cycle and Exit commands (which apply to all loops). You can also use the Goto command to jump out of a For loop, but this is considered poor programming in most cases.

Optimization

In many cases, the For loop is not the best choice when working with lists — sometimes, the operation can be done on the whole list at the same time, which is both smaller and faster. For example:

:For i, 1, dim(list)
: list[i]+1→list[i]
:EndFor

can be

:list+1→list

When using For to create a list from scratch, the seq() command is a smaller and faster alternative. For example:

:For i, 1, 10
: i^2→list[i]
:EndFor

can be

:seq(i^2, i, 1, 10)→list

Error Conditions

260 - Domain error happens when the step size is 0.

730 - Missing start or end of block syntax happens when the For is missing an EndFor, or vice versa.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:for


The format() Command

format.png

Command Summary

Converts a number to a string with specified formatting.

Command Syntax

format(number[,options])

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press D to enter the Strings submenu.
  • Press 9 to select format(.

Calculator Compatibility

This command works on all calculators.

Token Size

3 bytes

NOTE: Due to the limitations of the wiki markup language, the E command on this page does not appear as it would on the calculator. See Wiki Markup Limitations for more information.

The format() command is a more advanced version of string() specifically intended to convert numbers (usually, floating-point numbers) to strings. It can override settings like Display Digits and Exponential Format, and instead lets the user input these options and more in a string. Since it converts even integer input to floating-point, it also doesn't depend on the Base setting.

The format string can have the following values (not case-sensitive):

  • F[number] overrides Display Digits to fixed-point with [number] digits after the decimal; [number] can be omitted to use the default, which is 12; it must be between 0 and 12.
  • S[number] does this and also overrides Exponential Format to scientific.
  • E[number] does this and also overrides Exponential Format to engineering.
  • G[number][character] does this and also separates the digits to the left of the decimal into groups of three, with [character] as the separator. The default for [character], if it is omitted, is a comma. If you make the separator a period, then the decimal point will become a comma.

To all of these, you can also append R[character] to replace the decimal point with [character]. Only 'symbols' are allowed for [character], which is a bit vague: numbers and letters are not allowed, nor are some international characters.

:format(π,"F")
           "3.14159265359"
:format(2^25,"S6")
           "3.355443e7"
:format(2^25,"E6")
           "33.55443e6"
:format(2^25,"G0")
           "33,554,432."
:format(2^25,"G0 R ")
           "33 554 432 "

If the format string is empty, or if the argument is omitted entirely, format() will convert the number to a decimal, but otherwise will work just like string()

Error Conditions

260 - Domain error happens when the format string is improperly formatted.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:format


The fPart( Command
FPART.GIF

Command Summary

Returns the fractional part of a value.

Command Syntax

fPart(value)

Menu Location

Press:

  1. MATH to access the math menu.
  2. RIGHT to access the NUM submenu.
  3. 4 to select fPart(, or use arrows.

Calculator Compatibility

TI-83/84/+/SE/CE

Token Size

1 byte

fPart(value) returns the fractional part of value, be it a variable, list, or matrix.

fPart(5.32)
             .32
fPart(4/5)
              .8
fPart(‾5.32)
             ‾.32
fPart(‾4/5)
              ‾.8

fPart is sometimes used with it's corresponding partner iPart. While iPart trims off the part before the decimal point, fPart trims off the part after it.

Watch Out For Precision Issues

1/3*3→X   // X is expected to be 1
X         // Displays 1, but is actually 0.99999999999999 in memory
iPart(X)  // Displays 0
fPart(X)  // Displays 1, but is actually 0.99999999999999 in memory

Somewhat unintuitively, the code above displays the results 1, 0 and 1. This is due to the calculator storing values to 14 digits of precision, but rounding the value to 10 digits to fit on the home screen. Because of this, fPart() can appear to return values of 1 or -1.

Tip: If you enter a value in the list editor screen, you will be able to see all 14 digits of precision. This can help you troubleshoot issues like these.

One workaround is to round the numbers prior to calling iPart() or fPart(), if you don't mind the slight loss in precision from 14 significant digits to 9 decimal places:

1/3*3→X
iPart(round(X,9))   // Displays the expected result 1
fPart(round(X,9))   // Displays the expected result 0

(The parameter 9 is not technically required here since 9 is the default, but is shown for clarity and in case you want to customize the level of precision.)

Advanced Uses

Modulus

fPart( is an easy way to find A mod B (the positive remainder when A is divided by B).

B(A<0)+iPart(BfPart(A/B))

If A is guaranteed to be positive, the following shorter code can be used, omitting B(A<0):

iPart(BfPart(A/B))

Detect Whole Numbers

The easiest way to check if a number is a whole number is not(fPart(X:

If not(fPart(X:Then
  // X is an integer
Else
  // X is not an integer
End

This can be used, for example, to check if a number is divisible by another: if X is divisible by N, then X/N is a whole number. This is useful for finding the factors of a number.

Compression

fPart(, along with int( or iPart(, can be used for integer compression.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/fpart


The Fpdf( Command
FPDF.GIF

Command Summary

Evaluates the F-distribution probability density function at a point.

Command Syntax

Fpdf(x, numerator df, denominator df)

Menu Location

Press:

  1. 2ND DISTR to access the distribution menu
  2. 8 to select Fpdf(, or use arrows.

Press 9 instead of 8 on a TI-84+/SE with OS 2.30 or higher.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

Fpdf( is the F-distribution probability density function.

Since the F-distribution is continuous, the value of Fpdf( doesn't represent an actual probability - in fact, one of the only uses for this command is to draw a graph of the distribution. You could also use it for various calculus purposes, such as finding inflection points.

The command takes 3 arguments: x is the point at which to evaluate the function (when graphing, use X for this argument), numerator df and denominator df are the numerator degrees of freedom and denominator degrees of freedom respectively (these specify a single Fpdf( curve out of an infinite family).

The F-distribution is used mainly in significance tests of variance.

Formulas

The value of the Fpdf( is given by

(1)
\begin{align} \operatorname{Fpdf}(x,d_1,d_2) = \frac{\left( \frac{d_1x}{d_1x+d_2} \right)^{d_1/2} \left(1-\frac{d_1x}{d_1x+d_2}\right)^{d_2/2}}{x \operatorname{B}(d_1/2,d_2/2)} \end{align}

where B(x,y) is the Beta function.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/fpdf


The ►Frac Command
FRAC.GIF

Command Summary

Displays the fractional value of a number

Command Syntax

Decimal►Frac

Menu Location

While editing a program, press:

  1. MATH to open the math menu
  2. ENTER or 1 to select.

Calculator Compatibility

TI-83/84/+/SE/CE

Token Size

1 byte

►Frac attempts to display the input in fraction form. It only works on the home screen outside a program, or with the Disp and Pause commands in a program. It takes up to 12 decimal places of a non-terminating decimal to find the corresponding fraction. The decimal input is returned if ►Frac fails to find the fraction form.

For a more versatile algorithm for finding fractions, see the Decimal to Fraction routine.

.333►Frac
        .333
.333333333333►Frac
         1/3

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/frac


The Full Command
FULL.GIF

Command Summary

Sets the screen mode to FULL.

Command Syntax

Full

Menu Location

In the BASIC editor,

  1. Press [MODE]
  2. Press [DOWN] seven times
  3. Press [ENTER] to insert Full

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The Full command cancels the effects of either Horiz or G-T.

Full is usually used either at the beginning and/or ending of a program. It is used at the beginning to ensure that the screen mode is Full, the standard setting. It is used at the end if the screen mode was changed in the middle of the program (as clean up).

:Full

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/full


The Func Command
FUNC.GIF

Command Summary

Enables function graphing mode.

Command Syntax

Func

Menu Location

While editing a program, press:

  1. MODE to access the mode menu.
  2. Use arrows to select Func.

Calculator Compatibility

TI-83/84/+/SE/CE

Token Size

1 byte

The Func command enables the default function graphing mode. This command is usually unnecessary in a program, but if you want to graph a Y= equation, you'd want to make sure the calculator is in function mode first.

In function mode, you can graph equations where y (the vertical coordinate) is a function of x (the horizontal coordinate). This mode is most commonly discussed in algebra and single-variable calculus courses. Many curves, such as a parabola, have simple expressions when written in the form y=f(x).

However, in function mode, many expressions cannot be graphed at all. For example, a circle can't be easily graphed in function mode, since for some x-values, there are two y-values. Using two functions, you can achieve a circle, but it will still require a friendly graphing window to display perfectly.

Many calculator features are specifically targeted at function mode graphing. For example, two graphing styles (see GraphStyle() can be only used with function mode. The DrawF and DrawInv commands draw functions as if in graphing mode.

Advanced Uses

The window variables that apply to function mode are:

  • Xmin — Determines the minimum X-value shown on the screen.
  • Xmax — Determines the maximum X-value shown on the screen.
  • Xscl — Determines the horizontal space between marks on the X-axis in AxesOn mode or dots in GridOn mode.
  • Ymin — Determines the minimum Y-value shown on the screen.
  • Ymax — Determines the maximum Y-value shown on the screen.
  • Yscl — Determines the vertical space between marks on the Y-axis in AxesOn mode or dots in GridOn mode.
  • Xres — Determines the pixel distance between points used for graphing. This is a value 1-8: 1 for best quality, 8 for best speed.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/func


The G Command

gradian.png

Command Summary

Converts an angle to gradians, if necessary.

Command Syntax

angle G

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press 2 to enter the Angle submenu.
  • Press C to select G.

Calculator Compatibility

This command requires a TI-89 Titanium or Voyage 200 calculator with AMS version 3.10 or higher.

Token Size

1 byte

NOTE: Due to the limitations of the wiki markup language, the G command on this page does not appear as it would on the calculator. See Wiki Markup Limitations for more information.

The G symbol used after an angle makes sure the angle is interpreted as being in gradians (an obscure angle measure in which a full circle is equal to 400 gradians); this functionality is present only on TI-89 Titanium or Voyage 200 calculators with AMS version 3.10. If the calculator is already in gradian mode, xG is equal to x; in degree mode, xG is equal to 9*x/10; and in radian mode, xG is equal to π*x/200.

If you're using gradian angle measures extensively in a program, it's a better idea to use setMode() to switch to gradian mode and not worry about this. However, there are two reasons you might want to use G:

  • If you need an angle in gradians only once or twice, don't bother changing the mode setting.
  • In a function, you're forced to use G, since setMode() isn't valid in a function.

In gradian mode (no conversion is necessary, so no conversion is done):

:cos(100)
           1
:cos(100^G)
           1
:100^G
           100

In degree mode:

:cos(100)
           cos(100)
:cos(100^G)
           1
:100^G
           90

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:gradian


The GarbageCollect Command
GARBAGECOLLECT.GIF

Command Summary

Clears up 'garbage' that comes from unarchiving or deleting archived files.

Command Syntax

GarbageCollect

Menu Location

This command can only be found in the catalog. Press:

  1. 2nd CATALOG to access the command catalog
  2. G to skip to commands starting with G
  3. ENTER to select GarbageCollect

Calculator Compatibility

TI-83+/84+/SE
(not available on the regular TI-83)

Token Size

2 bytes

A bit of a preamble: unlike RAM, which is the easy-to-access memory, Flash ROM (the archive), used for long-term storage on the 83+ and higher, can't be written to easily. Skipping over technicalities, what's written in the archive once is semi-permanent, and can't be written to again unless an entire 64KB sector of memory is erased.

As a result, when you delete a variable from archive, the calculator doesn't delete it immediately (there may be other, good variables in the same block that would get erased as well), it just marks it as deleted. Similarly, when you unarchive a variable, its data is copied to RAM and the original is marked as deleted.

Naturally, this can't be done forever: sooner or later you'll run out of space in the archive because all of it is taken up by these "garbage variables". At this point, the calculator does something known as "garbage collecting". It copies the actually-used variables in each sector to a backup sector (set aside just for this purpose), then erases it; the process is repeated for the other sectors. Additionally, the variables are rearranged so that they aren't spread out all over the place; this makes it more likely that a spot will be found for large variables.

While "garbage collecting" will be done automatically when it's absolutely necessary, this may be a time-consuming process at that stage. Instead, you can call the GarbageCollect command yourself periodically (how often depends on your calculator habits, but generally once a month or so could work) to keep the Flash ROM in a semi-neat state, and then it will be a fairly quick process.

During garbage collection, a menu will appear that asks you "Garbage Collect?", giving you the options No and Yes. If you didn't select the GarbageCollect command yourself, it's highly recommended to select Yes. If you did select it, you probably want to garbage collect, so you should also select Yes. At that point, the message "Garbage collecting…" will be displayed for some time, and then the process will end.

Advanced Uses

To avoid garbage collecting often, reduce the amount of times you archive and unarchive variables. There's also the consideration that too many writes to the Flash ROM (which are directly related to the number of GarbageCollects you do) can, in theory, wear it out. This probably would take much longer than anyone's used a TI-83+ calculator so far, though, and in all probability you don't really have to worry about this.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/garbagecollect


The gcd( Command
GCD.GIF

Command Summary

Finds the greatest common divisor of two values.

Command Syntax

gcd(value1, value2)

Menu Location

Press:

  1. MATH to access the math menu.
  2. RIGHT to access the NUM submenu.
  3. 9 to select gcd(, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The gcd( command returns the greatest common divisor (GCD) of two nonnegative integers. It also works on lists.

gcd(8,6)
     2
gcd({9,12},6)
     {3 6}
gcd({14,12},{6,8})
     {2 4}

Advanced Uses

A gcd( command can be nested inside another gcd( command to compare up to four numbers.

Error Conditions

  • ERR:DIM MISMATCH is thrown if the arguments are two lists that don't have the same number of elements.
  • ERR:DOMAIN is thrown if the arguments aren't positive integers (or lists of positive integers) less than 1E12.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/gcd


The geometcdf( Command
GEOMETCDF.GIF

Command Summary

Calculates the cumulative geometric probability for a single value

Command Syntax

geometcdf(probability, trials)

Menu Location

Press:

  1. 2ND DISTR to access the distribution menu
  2. ALPHA E to select geometcdf(, or use arrows.

Press ALPHA F instead of ALPHA E on a TI-84+/SE with OS 2.30 or higher.

Calculator Compatibility

TI-83/84/+/SE/CSE/+CE

Token Size

2 bytes

This command is used to calculate cumulative geometric probability. In plainer language, it solves a specific type of often-encountered probability problem, that occurs under the following conditions:

  1. A specific event has only two outcomes, which we will call "success" and "failure"
  2. The event is going to keep happening until a success occurs
  3. Success or failure is determined randomly with the same probability of success each time the event occurs
  4. We're interested in the probability that it takes at most a specific amount of trials to get a success.

For example, consider a basketball player that always makes a shot with 1/4 probability. He will keep throwing the ball until he makes a shot. What is the probability that it takes him no more than 4 shots?

  1. The event here is throwing the ball. A "success", obviously, is making the shot, and a "failure" is missing.
  2. The event is going to happen until he makes the shot: a success.
  3. The probability of a success - making a shot - is 1/4
  4. We're interested in the probability that it takes at most 4 trials to get a success

The syntax here is geometcdf(probability, trials). In this case:

:geometcdf(1/4,4

This will give about .684 when you run it, so there's a .684 probability that he'll make a shot within 4 throws.

Note the relationship between geometpdf( and geometcdf(. Since geometpdf( is the probability it will take exactly N trials, we can write that geometcdf(1/4,4) = geometpdf(1/4,1) + geometpdf(1/4,2) + geometpdf(1/4,3) + geometpdf(1/4,4).

Formulas

Going off of the relationship between geometpdf( and geometcdf(, we can write a formula for geometcdf( in terms of geometpdf(:

(1)
\begin{align} \operatorname{geometcdf}(p,n) = \sum_{i=1}^{n} \operatorname{geometpdf}(p,i) = \sum_{i=1}^{n} p\,(1-p)^{i-1} \end{align}

(If you're unfamiliar with sigma notation, $\sum_{i=1}^{n}$ just means "add up the following for all values of i from 1 to n")

However, we can take a shortcut to arrive at a much simpler expression for geometcdf(. Consider the opposite probability to the one we're interested in, the probability that it will not take "at most N trials", that is, the probability that it will take more than N trials. This means that the first N trials are failures. So geometcdf(p,N) = (1 - "probability that the first N trials are failures"), or:

(2)
\begin{align} \operatorname{geometcdf}(p,n) = 1-(1-p)^n \end{align}

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/geometcdf


The geometpdf( Command
GEOMETPDF.GIF

Command Summary

Calculates the geometric probability for a single value

Command Syntax

geometpdf(probability, trials)

Menu Location

Press:

  1. 2ND DISTR to access the distribution menu
  2. ALPHA D to select geometpdf(, or use arrows.

Press ALPHA E instead of ALPHA D on a TI-84+/SE with OS 2.30 or higher.

Calculator Compatibility

TI-83/84/+/SE/CSE/CE

Token Size

2 bytes

This command is used to calculate geometric probability. In plainer language, it solves a specific type of often-encountered probability problem, that occurs under the following conditions:

  1. A specific event has only two outcomes, which we will call "success" and "failure"
  2. The event is going to keep happening until a success occurs
  3. Success or failure is determined randomly with the same probability of success each time the event occurs
  4. We're interested in the probability that it takes a specific amount of trials to get a success.

For example, consider a basketball player that always makes a shot with 1/3 probability. He will keep throwing the ball until he makes a shot. What is the probability that it takes him 3 shots?

  1. The event here is throwing the ball. A "success", obviously, is making the shot, and a "failure" is missing.
  2. The event is going to happen until he makes the shot: a success.
  3. The probability of a success - making a shot - is 1/3
  4. We're interested in the probability that it takes 3 trials to get a success

The syntax here is geometpdf(probability, trials). In this case:

:geometpdf(1/3,3

This will give about .148 when you run it, so there's a .148 probability that it will take him 3 shots until he makes one (he'll make it on the 3rd try).

Formulas

The value of geometpdf( is given by the formula

(1)
\begin{align} \operatorname{geometpdf}(p,n) = p(1-p)^{n-1} \end{align}

This formula can be intuitively understood: the probability that the first success is the nth trial is the probability of getting a success - $p$ - times the probability of missing it the first n-1 times - $(1-p)^{n-1}$.

For the trivial value of n=0, however, the above formula gives the incorrect value of 1. It should actually be 0, since the first success can never be the 0th trial. However, since you're not likely to ever be interested in this probability, this drawback doesn't really matter.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/geometpdf


The Get( Command
GET.GIF

Command Summary

Gets a variable's value from a connected calculator or CBL device.

Command Syntax

Get(variable)

Menu Location

While editing a program, press:

  1. PRGM to access the program menu.
  2. RIGHT to access the I/O menu.
  3. ALPHA A to select Get(.

Calculator Compatibility

TI-83/84/+/SE/CSE/CE*

Token Size

1 byte

*OS 5.1.5 or later

The Get( command is meant for use with the CBL (Calculator Based Laboratory) device, or other compatible devices. When the calculator is connected by a link cable to such a device, Get(variable) will read data from the device and store it to variable. Usually, this data is a list, and so you want to Get(L₁) or some other list variable.

Advanced Uses

In fact, the Get( command can also be used for linking two calculators, in which case it functions precisely like GetCalc(. This is probably for compatibility with the TI-82, which used Get( rather than GetCalc( for linking two calculators. However, since this isn't a documented feature (in fact, your TI-83+ manual will insist that Get( cannot be used in this way), it isn't guaranteed to work with future calculator versions.

Optimization

Nevertheless, using Get( instead of GetCalc( will make your program smaller, and probably preserve functionality.

Norland Robot

The Get( command is usually used after a Send command to confirm its transmission like this: Get(var). The variable in the parentheses is where the time of the robot's movement is stored. You can display the time moved with a Disp command.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/get


The GetCalc( Command
GETCALC.GIF

Command Summary

Gets a variable from another calculator.

Command Syntax

GetCalc(variable)

(84+ and 84+SE only)
GetCalc(variable,portflag)

Menu Location

While editing a program, press:

  1. PRGM to enter the PRGM menu
  2. RIGHT to enter the I/O menu
  3. 9 to choose GetCalc(, or use arrows

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The GetCalc( command allows you to make multiplayer games, where two calculators communicate with each other across a link cable that is connected between them. The GetCalc( command can only receive one variable from another calculator, and the variable can be any variable (a real, list, matrix, string, etc.). The calculator doesn't exchange variable values when the variable is received, but instead replace the variable of the same name on the receiving calculator.

For the GetCalc( command to work correctly, the sending calculator must be in a preemptible state and it cannot be executing an assembly program. (The sending calculator is the one which is not executing the GetCalc( command.) The two main commands that you should use to ensure this are Pause and Menu(; however, any command that is waiting for user input will also work perfectly fine (such as Prompt and Input).

The GetCalc( command behaves a little differently in the older TI-83 models. If the sending calculator is idle with the Pause or Menu( command, it will automatically "press enter" when the receiving calculator executes GetCalc(. This can be frustrating when in a menu, because it prevents the user's opportunity to make a selection.

However, this can make real-time gaming more possible if used in conjunction with the Pause command. When the receiving calculator receives the variable, it could then execute the Pause command, while the sending calculator automatically exits the power-saving state and could then perform the GetCalc( command. All models after the TI-83 do not automatically exit their power-saving states.

Advanced Uses

The TI-84+ and TI-84+SE will use the USB port if it is connected to a USB cable, otherwise they will use the I/O port. However, you can specify which port you want to use by putting a number after the variable as GetCalc('s second argument: zero to use the USB port if connected to a USB cable, one to use the USB port without checking to see if it's connected, and two to use the I/O port.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/getcalc


The getConfg() Command

getconfg.png

Command Summary

Returns a list of calculator configuration info.

Command Syntax

getConfg()

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

Token Size

3 bytes

The getConfg() command returns a list of useful and not-so-useful information about the calculator. Every other entry in the list is a description of the next entry, so it's not too hard to figure out which entry you need if necessary.

The values returned by getConfg() are:

List position Value List position Value
1 "Product Name" 2 "Advanced Mathematics Software"
3 "OS Version" 4 "version #, date"
5 "Product ID" 6 string unique to calculator model
7 "ID #" 8 string unique to specific calculator
9 "Screen Width" 10 160 or 240
11 "Screen Height" 12 100 or 128
13 "Window Width" 14 varies (see Note 1.)
15 "Window Height" 16 varies (see Note 1.)
17 "RAM Size" 18 depends on model
19 "Free RAM" 20 varies (see Note 2.)
21 "Archive Size" 22 depends on model
23 "Free Archive" 24 varies

Notes:

  1. The window width and window height depend on calculator model and on the split screen setting. They're also off by varying amounts. It's best to use one of the other settings to determine calculator type (widescreen or standard), and getMode() to determine split screen status if necessary.
  2. Even with all variables deleted, Free RAM will be considerably less than RAM Size, due to operating system variables taking up that much of it.

There are several interesting applications for getConfg(). One is compatibility with other calculator models:

  • If you want to make graphics compatible, use Screen Width or Screen Height to check if you're on a widescreen calculator.
  • If you want to use an advanced OS feature, check the OS Version.
  • If you use lots of features of your calculator model and think it won't work on any other, check Product ID and exit if it doesn't match your own.

Another application: if your program is very memory-intensive, you might want to make sure that there is enough free RAM to fit all the variables you will need. The same is, in theory, true for the archive, but having little archive memory available is rare.

Using the ID #, you might detect when the program has been transferred to a different calculator, and react accordingly (e.g. re-initialize certain variables). A more subtle application: supplying a number calculated from the ID # as the random number seed will ensure that your program always behaves in the same way for the same calculator, but will be different on different calculators — this might be completely inappropriate in some cases, but an interesting gimmick in others!

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:getconfg


The getDate() command

getDate.png

Command Summary

Returns the current date set on the calculator and returns it in list format.

Command Syntax

getDate()

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command requires a calculator with AMS version 2.07 or higher (it will also work on any TI-89 Titanium or Voyage 200 calculator)

Token Size

3 bytes

The getDate() command checks the date that the calculator is set to, and then returns it in a list format. The list will always be in the format {year, month, day}. To change this list to another format, you can use the closely related getDtStr() option, which just returns the date in a string format, not as a list. The setDtFmt() command does not work on this command, but it will change the format that the calculator returns the getDtStr() command as.

For example, if the calculator's date was set to March 14th, 2011, the getDate() command would return the following:

:getDate()
:     {2011 3 14}

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:getdate


The getDate Command
GETDATE.PNG

Command Summary

Returns a list with the current date that the clock has on the TI-84+/SE/CE.

Command Syntax

getDate→Variable

Menu Location

This command can only be found in the catalog. Press:

  1. 2nd CATALOG to enter the command catalog
  2. G to skip to commands starting with G
  3. Scroll down to getDate and select it

Calculator Compatibility

TI-84+/SE/CE

Token Size

2 bytes

The getDate command returns the current date that the clock has on the TI-84+/SE/CE calculators in list format — {year, month, day}. You can store this list to a variable for later use, or manipulate it the same way you do with other lists. Of course, this command only works if the date has actually been set, so you should use the setDate( command before using it.

An interesting note about this command is that you cannot index getDate directly to get individual elements; if you try, each element of the clock is instead multiplied by the number. You may, however, call the command and thus store it in Ans, then retrieve individual elements.

SCREEN02.BMP

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/getdate


The getDtFmt() Command

getdtfmt.png

Command Summary

Returns the current default date format.

Command Syntax

getDtFmt()

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command requires a calculator with AMS version 2.07 or higher (it will also work on any TI-89 Titanium or Voyage 200 calculator)

Token Size

3 bytes

The getDtFmt() returns the number of the current default date format for getDtStr() (that is, the format that getDtStr() with no parameters will use). This same format is also used to display the time in the corner of the Apps Desktop.

The eight formats are as follows (dd, mm, and yy are the date, month, and year respectively, in two digits)

Format Number Date Format
1 "mm/dd/yy"
2 "dd/mm/yy"
3 "mm.dd.yy"
4 "dd.mm.yy"
5 "yy.mm.dd"
6 "mm-dd-yy"
7 "dd-mm-yy"
8 "yy-mm-dd"

In a program, it's usually unnecessary to use getDtFmt(). Most of the time, you'll just use getDtStr() with a format already specified; in the rare exceptions where you need to use getDtStr() a lot with the same format, you'd use setDtFmt() to pick the format you want, save the result, and use it to restore the date format at the end of the program.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:getdtfmt


The getDtFmt Command
GETDTFMT.PNG

Command Summary

Returns the date format of the clock on the TI-84+/SE/CE.

Command Syntax

getDtFmt→Variable

Menu Location

This command can only be found in the catalog. Press:

  1. 2nd CATALOG to enter the command catalog
  2. g to skip to commands starting with G
  3. Scroll down to getDtFmt( and select it

Calculator Compatibility

TI-84+/SE/CE

Token Size

2 bytes

The getDtFmt( command returns the current date format of the clock on the TI-84+/SE/CE calculators as an integer. There are three different date formats available: 1 (M/D/Y), 2 (D/M/Y), and 3 (Y/M/D). You can store this value to a variable for later use. Of course, this command only works if the date format has actually been set, so you should use the setDtFmt( command before using it.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/getdtfmt


The getDtStr() Command

getdtstr.png

Command Summary

Returns the current date in a string.

Command Syntax

getDtStr([format])

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command requires a calculator with AMS version 2.07 or higher (it will also work on any TI-89 Titanium or Voyage 200 calculator)

Token Size

3 bytes

The getDtStr() command returns the current date in a string. The date can be in one of eight formats, numbered from 1 to 8. This format can be given to getDtStr() directly: for instance, getDtStr(5) will return the date in the fifth format. Or, you can set a default format with the setDtFmt() command, and getDtStr() will use that format when it's not given a specific format to use.

The eight formats are as follows (dd, mm, and yy are the date, month, and year respectively, in two digits)

Format Number Result of getDtStr()
1 "mm/dd/yy"
2 "dd/mm/yy"
3 "mm.dd.yy"
4 "dd.mm.yy"
5 "yy.mm.dd"
6 "mm-dd-yy"
7 "dd-mm-yy"
8 "yy-mm-dd"

Formats 5 and 8 are useful in that if you store dates in either of those format, sorting the strings will sort the dates in chronological order.

Error Conditions

40 - Argument error happens when the date format given is not an integer 1-8.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:getdtstr


The getDtStr( Command
GETDTSTR.PNG

Command Summary

Returns the current date of the clock on the TI-84+/SE/CE as a string.

Command Syntax

getDtStr(value)→variable

Menu Location

This command can only be found in the catalog. Press:

  1. 2nd CATALOG to enter the command catalog
  2. g to skip to commands starting with G
  3. Scroll down to getDtStr( and select it

Calculator Compatibility

TI-84+/SE/CE

Token Size

2 bytes

The getDtStr( command returns the current date of the clock on the TI-84+/SE/CE calculators as a string based on the date format that is specified. There are three different date formats available: 1 (M/D/Y), 2 (D/M/Y), or 3 (Y/M/D). You can store this value to a string variable for later use, or manipulate it the same way you do with other strings. Of course, this command only works if the date format has actually been set, so you should use the setDtFmt( command before using it.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/getdtstr


The getKey() Command

getkey.png

Command Summary

Returns the last keypress.

Command Syntax

getKey()

Menu Location

Starting from the program editor:

  • Press F3 to enter the I/O menu.
  • Press 7 to paste getKey().

Calculator Compatibility

This command works on all calculators.

Token Size

3 bytes

The getKey() command returns the key code of the last keypress. If no key was pressed since the program, function, or expression started running, or since the last getKey() command, getKey() returns 0. It's important to note that once getKey() is used, the keypress is forgotten — even if it's used in the same line! So most of the time you want to store the result of getkey to a variable to use it.

The keypresses that getKey() deals with factor in modifier keys, such as 2nd or alpha. Because of this, it will not respond to the modifier keys pressed by themselves.

This example code using getKey() is commonly used in programs that wait for the user to press a key:

:0→key
:While key=0
: getKey()→key
:EndWhile

Advanced Uses

Although the key codes are given in a table on this website, and are listed in your manual, it may be more convenient to write a short function to return key codes for you:

:keycode()
:Func
:Local k
:0→k
:While k=0
: getKey()→k
:EndWhile
:k
:EndFunc

If you run the function keycode(), it will wait for you to press a key. When you press it, it will return the key code. This function may also be a convenient subroutine in a program that requires waiting for a key in several different places.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:getkey


The getKey Command
GETKEY_ANIMATED.gif

Command Summary

Returns the numerical code of the last key pressed, or 0 if no key is pressed.

Command Syntax

getKey[→Variable]

Menu Location

While editing a program, press:

  1. PRGM to enter the PRGM menu
  2. RIGHT to enter the I/O menu
  3. 7 to choose getKey or use arrows

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The getKey command returns the value of the last key pressed since the last time getKey was executed. Reading key presses with getKey allows a program to transfer control to the user, and you can combine getKey with other commands to create menus, movement, or whatever else you want.

Every key has a number assigned to it, except for ON (which is used for breaking out of programs). The numbering system consists of a row and column: the rows go from one to ten, starting at the top; and the columns go from one to six, starting from the left. You just put the row and column together to get the key's number — for example, the ENTER key is located in row 10, column 5, making its value 105. The arrow keys look like they would be numbered separately from the other keys, but they actually follow this pattern as well. See the key codes page for a picture of the key codes on the calculator.

The value of getKey is cleared every time you read from it, until a new key is pressed. For this reason, except in very rare cases, you do not want to use the value of getKey in an expression directly, but store it to a variable first. It is also common to use getKey inside of a Repeat loop, so that the program can wait for the user to press a key.

:Repeat Ans
:getKey
:End
:Ans→K

Advanced Uses

You can put getKey in the condition of a loop, to make the loop repeat until any key or a particular key is pressed by the user. The same thing can be done with conditionals as well. This is useful if you don't want to store getKey to a variable, but you still want to have the user press a key. This works because of the way 'true' and 'false' get interpreted in TI-Basic.

:Repeat max(getKey={24,25,26,34
:End

Unlike the other keys, the arrow and DEL keys can actually be held down, which will cause the key to keep being repeated until it is unpressed. This functionality is very useful in games where the user needs to repeatedly press a key to move or shoot, although it does completely disable the other keys from being able to be pressed (which is important in multiplayer games, where everybody must share the keys).


Sometimes your program may do something for several seconds without user input (say, playing an animation), then pause and wait for a key to be pressed. The problem is that if a key is pressed during the animation, the next getKey will return the value of that key, and any loop set up to wait for a key press will exit immediately. The solution is to run a "dummy" getKey just before the loop begins — its value won't be used for anything, and it will reset the value of getKey to 0. This can also be used to clear keypresses meant for loading programs from inside a shell.

Error Conditions

  • ERR:INVALID occurs if this statement is used outside a program.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/getkey


The getMode() Command

getmode.png

Command Summary

Checks the current mode settings.

Command Syntax

getMode(setting)

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

The getMode() command checks any one current mode setting. Just give it the name of the mode setting to check, as a string, and it will give you the current value. For example:

:getMode("Angle")
           "RADIAN"
:getMode("Complex Format")
           "REAL"

The name of the setting is not case-sensitive, but is very typo-sensitive.

In practice, getMode() is almost entirely superseded by setMode() — usually, you don't care about a setting unless you want to change it if it's wrong. In particular, it is silly to do the following:

:If getMode("Angle")≠"RADIAN"
:  setMode("Angle","RADIAN")

In this case, just the setMode() command instruction by itself would have been fine, since changing the mode from radian to radian would've done nothing anyway.

It is also silly to do the following:

:getMode("Angle")→oldmode
:setMode("Angle","RADIAN")
...
:setMode("Angle",oldmode)

It is a noble impulse to try to preserve the old setting and restore it later. However, the same is accomplished more elegantly with (note the { } brackets):
:setMode({"Angle","RADIAN"})→oldmode
...
:setMode(oldmode)

Optimization

Every string like "Angle" or "FLOAT 12" can be replaced by a numerical equivalent (one that is, for some reason, still given as a string, e.g. "3" or "26"). Using these is shorter, and it has the benefit of being international.

See the Table of Mode Settings to look up these numbers, as well as read about what the various mode settings do.

Error Conditions

260 - Domain error happens when a mode setting or value doesn't exist, at least not with this spelling.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:getmode


The getNum() Command

getnum.png

Command Summary

Returns the numerator of a fraction or given expression

Command Syntax

getNum(expression1)

Menu Location

[MATH][9][B][1]

Calculator Compatibility

This command works on all calculators.

Token Size

X byte(s)

The getNum() command return the value of a given expression (an expression being a number or an algebraic expression).

getNum(3/5)
   3
getNum((x+1)/(x-1))
   x+1

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:getnum


The getTime Command
GETTIME.PNG

Command Summary

Returns a list with the current time that the clock has on the TI-84+/SE/CE.

Command Syntax

getTime→Variable

Menu Location

This command can only be found in the catalog. Press:

  1. 2nd CATALOG to enter the command catalog
  2. g to skip to commands starting with G
  3. Scroll down to getTime and select it

Calculator Compatibility

TI-84+/SE/CE

Token Size

2 bytes

The getTime command returns the current time that the clock has on the TI-84+/SE/CE calculators in list format — {hour, minute, second}. You can store this list to a variable for later use, or manipulate it the same way you do with other lists. Of course, this command only works if the time has actually been set, so you should use the setTime( command before using it.

An interesting note about this command is that you cannot index individual elements directly; if you try, each element of the clock is multiplied by the index. You can, however, call the demand and thus store the result in Ans, and then retrieve the individual elements.

SCREEN01.JPG

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/gettime


The getTmFmt Command
GETTMFMT.PNG

Command Summary

Returns the time format of the clock on the TI-84+/SE/CE.

Command Syntax

getTmFmt→Variable

Menu Location

This command can only be found in the catalog. Press:

  1. 2nd CATALOG to enter the command catalog
  2. g to skip to commands starting with G
  3. Scroll down to getTmFmt( and select it

Calculator Compatibility

TI-84+/SE/CE

Token Size

2 bytes

The getTmFmt( command returns the current time format of the clock on the TI-84+/SE/CE calculators as an integer. There are two different time formats available: 12 (12 hour) and 24 (24 hours). You can store this value to a variable for later use. Of course, this command only works if the time format has actually been set, so you should use the setTmFmt( command before using it.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/gettmfmt


The getTmStr( Command
GETTMSTR.PNG

Command Summary

Returns the current time of the clock on the TI-84+/SE as a string.

Command Syntax

getTmStr(value)→variable

Menu Location

This command can only be found in the catalog. Press:

  1. 2nd CATALOG to enter the command catalog
  2. g to skip to commands starting with G
  3. Scroll down to getTmStr( and select it

Calculator Compatibility

TI-84+/SE

Token Size

2 bytes

The getTmStr( command returns the current time of the clock on the TI-84+/SE calculators as a string based on the time format that is specified. There are two different time formats available: 12 (12 hour) or 24 (24 hour). You can store this value to a string variable for later use, or manipulate it the same way you do with other strings. Of course, this command only works if the time format has actually been set, so you should use the setTmFmt( command before using it.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/gettmstr


The getType() Command

gettype.png

Command Summary

Returns the variable type of a variable

Command Syntax

getType(variable)

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

The getType() command returns the type of a variable — number, string, function, etc. The output is a short string encoding the type of the variable.

:5→x
:getType(x)
           "NUM"
:{1,2,3}→x
:getType(x)
           "LIST"
:DelVar x
:getType(x)
           "NONE"

The specific values that getType() can return are:

  • "DATA" for a data variable
  • "EXPR" for a symbolic expression
  • "FUNC" for a function
  • "LIST" for a list
  • "MAT" for a matrix
  • "NONE" for an undefined variable
  • "NUM" for a number
  • "OTH" for an unknown variable type (usually assembly-related)
  • "PIC" for a picture
  • "PRGM" for a program
  • "STR" for a string
  • "TEXT" for a text file

Keep in mind that getType() cannot test the type of an expression, only a variable — so getType("Hello!") for example is invalid.

Advanced Uses

If possible, avoid comparing the result of getType() to an actual string. The risk here is that when the calculator is switched to a different language, the output of getType() changes language too. This is only a minor consideration. But if you already have a variable of the right type lying around, and you want to test an unknown variable, compare their getTypes(). For example:

:{1,2,3}→knownlst
:If getType(unknown)="LST"

can be

:{1,2,3}→knownlst
:If getType(unknown)=getType(knownlst)

This is occasionally, but not always, a size optimization as well, if the known variable has a short name.


Since getType() returns a result even for undefined variables, it can be used as a replacement for isVar(), which unlike getType() isn't present on all 68k calculator models.

Error Conditions

140 - Argument must be a variable name happens when the argument is not a variable name.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:gettype


The Goto Command
GOTO_ANIMATED.gif

Command Summary

Jumps to the Lbl instruction with the specified name, and continues running the program from there.

Command Syntax

Goto name

Lbl name

Menu Location

While editing a program, press:

  1. PRGM to enter the PRGM menu.
  2. 0 to choose Goto, or use arrows.
  3. 9 to choose Lbl, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The Goto command is used together with the Lbl command to jump (or branch) to another place in a program. When the calculator executes a Goto command, it stores the label name in memory, and then searches from the beginning of the program for the Lbl command with the supplied name. If it finds it, it continues running the program from that point; otherwise, if the label does not exist, it throws an ERR: LABEL error.

Label names can be either one or two characters long, and the only characters you're allowed to use are letters (including θ) and numbers 0 to 9; this means 37+37*37=1406 possible combinations. Of course, you should use all of the single character names first, before using the two character names. While you can technically have the same label name multiple times in a program, it is rather pointless since the calculator always goes to the first occurrence of the label.

You can position a Lbl command one or more lines before a Goto command to create a kind of loop structure. However, you have to provide the break-out code, since it isn't built-in. An If conditional is easiest, but if there is no code that ends the branching, then program execution will continue indefinitely, until you manually exit it (by pressing the ON key).

:Lbl A
:...
:If <exit condition>
:Goto A  // this line is skipped

Although the Goto command may seem like a good alternative to loops, it should be avoided whenever possible, which is especially important when you are first planning a program. This is because it has several serious drawbacks associated with it:

  • It is quite slow, and gets slower the further the Lbl is in your program.
  • It makes reading code (your own, or someone else's) much more confusing.
  • In most cases, If, For(, While, or Repeat can be used instead, saving space and improving speed.
  • Using a Goto to exit any block of code requiring an End command causes a memory leak, which will not be usable until the program finishes running or executes a Return command, and which will slow down your program down. See below for ways to fix this.

The Goto command isn't all bad, however, and is actually useful when a loop isn't practical and when something only happens once or twice (see below for examples). Just remember that you should never use Goto to repeat a block of code several times. Use For(, Repeat, or While instead.

Fixing Memory Leaks

One of the simplest memory leaks that occurs is using branching to exit out of a loop when a certain condition of an If conditional is true. If the loop is an infinite loop (i.e., Repeat 0 or While 1), you should take the condition from the If conditional and place it as the condition of the loop. This allows you to remove the branching, since it is now unnecessary.

:Repeat 0
:getKey→B
:If B:Goto A
:End:Lbl A
Make Loop Condition
:Repeat B
:getKey→B
:End

Of course, the only reason that this memory leak fix is possible is because of the If conditional (since the If conditional doesn't need a closing End command). When dealing with a complex If conditional, you will have to rework the conditionals so the branching has its own If conditional. Depending on how many commands there are in the conditionals, you might be able to just use an If conditional or you might need to use an If-Then conditional.

:If B:Then
:Disp "Hello
:Goto A
:End
Separate Into Conditionals
:If B:Disp "Hello
:If B:Goto A

This memory leak fix will work most of the time, but it isn't applicable when one of the values of the variables in the condition is changed by one of the commands inside the condition. The way to get around this is by using another variable for the If conditional that the branching uses. You initialize the variable to zero, assign the variable whatever value you want in the conditional, and then check to see if the variable is equal to that value in the branching conditional.

:If A=1:Then
:3→A:4→B
:Goto A
:End
Use Another Variable
:Delvar CIf A=1:Then
:3→A:4→B:π→C
:End
:If C=π
:Goto A

Advanced Uses

If your program requires cleanup after it finishes, but it can exit from several different places, use Goto and place a Lbl at that point. This saves memory over repeating the cleanup code every time you exit. The usual considerations about Goto don't apply here: since you're exiting the program, all memory leaks will be gone anyway, and speed isn't much of an issue for something that only gets done once.

The code looks something like this:

:If K=45:Goto Q  //user pressed CLEAR
:...
:If L:Goto Q  // game over
:...
:Lbl Q
:DelVar L1ClrHome

A common situation in programs is when a decision has to be made about where the program execution should go next. The obvious approach would be to use the value of a variable as the label name (i.e., something like Goto A, with A being a variable), but that doesn't work because the calculator doesn't interpret the label as a variable. So, the next best approach is to use If conditionals with the different values of the variable:

:If not(A:Goto 0
:If A=1:Goto 1
:If A=2:Goto 2

Another possible use for Goto is in program protection to break a program with an error without letting the user see where it happened. If the label that you want to Goto doesn't exist, you'll get a ERR: LABEL error, which doesn't provide a 2:Goto option. So, all you have to do is Goto a label that you know doesn't exist.
An alternative method would be to lock the program from being able to be edited. (which you currently cannot do on-calc without a shell) This gives you the possibility to throw whatever error you want! For example, if the user entered something invalid, you can add a blank line with a closing parenthesis, and a syntax error will be thrown, without the 2:Goto option! If you do go this route, be sure to only lock it when you are done editing. It is also good practice to include a text file with the source, as well.

Error Conditions

  • ERR:INVALID occurs if this statement is used outside a program.
  • ERR:LABEL is thrown if the corresponding label doesn't exist.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/goto


The Goto Command

goto.png

Command Summary

Jumps to a label somewhere else in the program.

Command Syntax

:Goto label-name

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes

The Goto command jumps to a label (declared with the Lbl command) somewhere else in the program — either before or after the Goto, it doesn't matter. The label has to be in the same program as the Goto — you can't jump into another program. If there are several labels with the same name, the Goto command will only find the first.

Virtually everyone critiques the Goto command for being unnecessary and encouraging bad coding habits. The argument is that it makes code hard to read: if you see a 'Goto x' somewhere in the program, you have to search through the entire program to find out where to continue reading. And most of the things that Goto is used for can be done better using commands like If, While, Cycle, etc. TI seems to agree, because they didn't even bother putting Goto and Lbl in the program editor toolbar.

That being said, it is sometimes (very rarely) a good idea to use Goto. A good example is a situation when you need to exit several loops at once (this can't be done with the Exit command, which only exits one loop).

A note for TI-83 series programmers: the issue of memory leaks from improper use of the Goto command does not occur on 68k calculators. The 68k TI-Basic parser doesn't use a stack to keep track of loops and If blocks entered: instead, End statements have a link back to what it is they're matching. This means that nothing special happens if a Goto jumps out of a loop: the calculator doesn't even know it's inside a loop except at the end when it has to do the looping.

The 68k calculators have their own bit of unexpected Goto behavior: code like expr("Goto x") will not work. This is because the code that expr( runs is treated as though it were inside its own program, so you can't jump out of that program into the program that it's actually in.

Optimization

The Cycle and Exit commands perform tasks that you might otherwise use Goto for. By all means, use these command instead if you can: they work much faster, since they don't have to look through the entire program for the label (in fact, they don't have to look at all — they already know where to jump).

Error Conditions

500 - Invalid label happens when the label doesn't exist (in this program).

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:goto


The GraphStyle( Command
GRAPHSTYLE.GIF

Command Summary

Sets the graphing style of a graphing equation in the current mode.

Command Syntax

GraphStyle(equation #, style #)

Menu Location

While editing a program, press:

  1. PRGM to access the programming menu.
  2. ALPHA H to select GraphStyle(, or use arrows.

Calculator Compatibility

TI-83/84/+/SE/CE

Token Size

2 bytes

The GraphStyle( command allows you to set the graphing style of an equation (line, thick line, dotted line, etc.) from within a program.

Its first argument, equation #, is the number of the equation whose graphing style you want to change - this depends on the mode you're in. For example, if you wanted to change the graphing style of Y1, you would need to be in function mode and use the value 1 for this argument. If you wanted to change the graphing style of r4, you would need to be in polar mode and use the value 4.

The second argument is a number from 1 to 7, which translates to a graphing style as follows:

  • 1 - a normal line, usually the default graph style.
  • 2 - a thick line (three pixels wide).
  • 3 - a line, with everything above it shaded (only valid in function mode).
  • 4 - a line, with everything below it shaded (only valid in function mode).
  • 5 - a path: a line, with a ball moving along it as it is graphed (not valid in sequential mode).
  • 6 - animated: a ball moving along the graph (not valid in sequential mode).
  • 7 - a dotted line.

Compare this to the effect of Connected or Dot mode. When either of these modes is set, all equations, from all graphing modes, are reverted to line style or dotted line style respectively; furthermore, it becomes the default graph style and clearing an equation will revert it to this graph style. The GraphStyle( command simply overrides these modes temporarily.

Advanced

In shading modes (3 and 4), the shading style cycles as follows:

  • The first function graphed shades using vertical lines one pixel apart
  • The second function shades using horizontal lines one pixel apart
  • The third function shades using negatively sloping diagonal lines, two pixels apart.
  • The fourth function shades using positively sloping diagonal lines, two pixels apart.
  • After that, functions will cycle through these four styles in that order.

Error Conditions

  • ERR:DOMAIN if the equation # is not a valid equation number in this mode, or if style # is not an integer 1-7.
  • ERR:INVALID if the graphing style chosen is not valid for the current graphing mode.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/graphstyle


The GridOff Command
GRIDOFF.GIF

Command Summary

Disables the grid on the graph screen.

Command Syntax

GridOff

Menu Location

Press:

  1. 2nd FORMAT to access the graph format menu.
  2. Use arrows and ENTER to select GridOff.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The GridOff command disables the grid on the graph screen. This is the default setting. Use GridOn to enable the grid.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/gridoff


The GridOn Command
GRIDON.GIF

Command Summary

Enables the grid on the graph screen.

Command Syntax

GridOn

Menu Location

Press:

  1. 2nd FORMAT to access the graph format menu.
  2. Use arrows and ENTER to select GridOn.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The GridOn command enables a grid on the graph screen (you can disable it again with the GridOff command). How fine or coarse the grid is depends on the Xscl and Yscl variables. Drawing the grid just involves plotting points all the points of the form (A*Xscl, B*Yscl) that are in the graphing window. The grid is often used in games such as Dots & Boxes, Tic-Tac-Toe, and 2D puzzles.

On the TI-84+CSE and TI-84+CE, an additional argument may be used to set the color of the grid:

:GridOn GRAY

Like other drawing commands, the color may be replaced by its numerical value (ranging from 10 to 24).

Advanced Uses

GridOn can be used to shade the entire screen if Xscl and Yscl are small enough that the points on the grid are one pixel apart:

:ΔX→Xscl
:ΔY→Yscl
:GridOn

This is one of the shortest ways to shade the screen, although Shade( can be used for a (usually) even shorter way. However, using GridOn is also very slow: the fastest way involves the Horizontal or the Vertical commands in a For( loop (or the BackgroundOn command for color calculators).

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/gridon


The G-T Command
G-T.GIF

Command Summary

Sets the screen mode to G-T.

Command Syntax

G-T

Menu Location

In the program editor,

  1. Press [MODE] for the mode menu
  2. Press [DOWN] seven times (for the split screen commands)
  3. Press [RIGHT] twice to select G-T
  4. Press [ENTER] to insert it

This command can be used on the home screen, but must be selected from the catalog.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

G-T puts the calculator into "Graph-Table" mode: this mode shows the home screen at full size, but the graph screen and table will be displayed together, each taking up half the screen (divided vertically).

G-T is usually used at the beginning of a program to ensure that the screen mode is G-T , for programs such as math programs that want to demonstrate the thinking step-by-step.

:G-T

With OS version 2.30 (on the TI-84+ and TI-84+ SE calculators), G-T mode can be used with stat plots as well.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/g-t


The Horiz Command
HORIZ.gif

Command Summary

Sets the screen mode to Horiz.

Command Syntax

Horiz

Menu Location

In the program editor,

  1. Press [MODE]
  2. Press [DOWN] seven times
  3. Press [RIGHT]
  4. Press [ENTER] to insert Horiz

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

Horiz is usually at the beginning of a program. It is used at the beginning to ensure that the screen mode is Horiz, for programs such as Hangman that want to use Input but also have the graph screen shown. Note that if you use pixels, the y-coordinate can be no larger than 30, since that is the maximum pixel's range.

:Horiz

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/horiz


The Horizontal Command
HORIZONTAL.GIF

Command Summary

Draws a horizontal line on the graph screen.

Command Syntax

Horizontal Y

Menu Location

In the program editor:

  1. 2nd DRAW to enter the draw menu
  2. 3 to insert the Horizontal command, or use arrows and ENTER.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

Horizontal Y draws a vertical line from the left of the graph screen to the right at Y. Horizontal is usually only used to replace a line that stretches the entire length of the graph screen, along with its counterpart Vertical.

Horizontal is affected by the window settings, unlike the Pxl- commands.

:Horizontal 5

Advanced Uses

One of the fastest ways to make the entire screen black is by drawing horizontal lines from the bottom of the screen to the top.

:For(A,Ymin,Ymax,ΔY
:Horizontal A
:End

If working with TI 84+C version calculators, the Horizontal command takes an additional color argument, as shown below:

Horizontal 5,GRAY

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/horizontal


The i Command
I.PNG

Command Summary

The mathematical symbol i, short for √(-1).

Command Syntax

i

To enter a complex number:

real-part+imag-part i

Menu Location

Press 2nd i to paste i.

Calculator Compatibility

TI-83/84/+/SE/CSE/CE

Token Size

1 byte

The i symbol is short for √(-1), and is used for complex numbers in algebra and complex analysis. On the calculator, entering i will not cause an error, even in Real mode, but operations that result in a complex number (such as taking the square root of a negative number) will. If you're dealing with complex numbers, then, it's best to switch to a+bi or re^θi mode.

Advanced Uses

By using i in a calculation, the calculator switches to complex number mode to do it, even if in Real mode. So √(-1) will throw an ERR:NONREAL ANS, but √(0i-1) will not (even though it's the same number). This can be used to force calculations to be done using complex numbers regardless of the mode setting — usually by adding or subtracting 0i, although more clever ways can be found.

A good example of this technique is our Quadratic Formula routine.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/i


The identity( Command
IDENTITY.GIF

Command Summary

Creates an n by n identity matrix.

Command Syntax

identity(n)

Menu Location

Press:

  1. MATRX (on the 83) or 2ND MATRX (83+ or higher) to access the matrix menu.
  2. LEFT to access the MATH submenu.
  3. 5 to select identity(, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The identity( command generates an identity matrix: that is, a matrix [B] such that for any other matrix [A], [A]*[B]=[A] (if [A] is the right size to make the multiplication valid).

The identity matrix is square (that is, the row dimension equals the column dimension); all of its elements are 0 except for the elements along the main diagonal (the diagonal going from top left to bottom right).

The command itself takes one argument: the size of the matrix, used for both row and column size, that is, identity(n) creates an n by n matrix.

:dim([A]
:identity(Ans(2→[B]
:[A][B]=[A]  // should always return 1, meaning 'true'

Optimization

The identity( command can be used as a quick way to create an empty square matrix: 0identity(n) will create an n by n matrix containing only 0 as an element. This is faster and smaller than the dim( and Fill( commands used for the same purpose:

:{5,5→dim([A]
:Fill(0,[A]
can be
:0identity(5→[A]

Error Conditions

  • ERR:INVALID DIM occurs if the size is not an integer 1-99. In practice, however, identity(21) is already too large for the calculator to generate.
  • ERR:MEMORY occurs if the size of the created matrix exceeds memory limits. This limit is hard-fixed to 3611 bytes (the size of a 20x20 matrix), regardless of having sufficient RAM to hold a larger matrix.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/identity


The If Command
IF_ANIMATED.gif

Command Summary

Executes a line or block of code when an expression is nonzero.

Command Syntax

If condition
statement

If condition
Then
one or more statements
End

If condition
Then
statement(s) to run if condition is true
Else
statement(s) to run otherwise
End

Menu Location

While editing a program, press:

  1. PRGM to enter the PRGM menu
  2. ENTER or 1 to choose If

Calculator Compatibility

TI-83/84/+/SE/CSE/CE

Token Size

1 byte

The If command is crucial to most programs. It allows you to execute code if and only if an expression is not equal to zero. Advanced uses of the If command allow you to execute a different block of code if the check turns out to be false. The simplest form of the command is quite easy to understand:

:If (condition)
:statement

When the calculator gets to that point in your program, it will check to see if the condition is nonzero. Most expressions you will use with If are called conditional expressions; that is, they return 1 if the condition is true and 0 if it is false. Examples include 2+2=4, A=5, and pxl-Test(R,C). Therefore, when the condition is true, the expression evaluates to 1 and the statement is run. When the condition is false, the expression evaluates to 0, and the statement is skipped.

Using Then, Else, and End

When you want more than one line of code to depend on the same condition, use an If-Then block.

:If (condition)
:Then
code to execute if true
:End

An If-Then block also has an optional Else clause, which is used to execute different code when the condition is false.

:If (condition)
:Then
code to execute if true
:Else
code to execute if false
:End

Colon character

Note that it's not possible to squeeze two or more statements into a naked If statement by using the colon (:) character. In the example below Disp B will always be executed, regardless of A:

:If A
:Disp A:Disp B

The solution is to wrap multiple statements with a Then and End.

Advanced Uses

If statements can execute and skip other If statements. This leads to odd yet effective constructs like these:

:If A
:If B
//Executes if A is false or B is true
If A:Then
//Executes if A is true
If B:Else
//Executes if A is false or B is false
End

Memory Leaks

Each time the program enters an If-Then block, the calculator uses 35+(size of the condition) bytes of memory to keep track of the block. This memory is given back to you as soon as the program reaches an End statement. This isn't really a problem unless you're low on RAM, or have a lot of nested If-Then statements. However, if you use Goto to jump out of such a statement, you lose those bytes for as long as the program is running — and if you keep doing this, you might easily run out of memory, resulting in ERR:MEMORY.

Optimization

As far as the TI-BASIC interpreter is concerned, a value of 0 is false, and any other value is true. We can use a numerical expression rather than a conditional one in the condition of the If statement in a case like the following:

:If A≠0
:Disp "A IS NOT 0

can be
:If A
:Disp "A IS NOT 0

When code in a single-line If statement simply changes a variable, it can often be replaced with an equivalent piecewise expression, which will be smaller and faster.

:If A=B
:C+2→C

can be
:C+2(A=B→C

Code Timings

Single-line If statements are greatly slowed when they are the first line in For( loops without a closing parenthesis. For example,

Very slow
:For(I,1,2000
:If 0:
:End

19 times faster (!)
:For(I,1,2000)
:If 0:
:End

Error Conditions

  • ERR:DATA TYPE occurs if the parameter is complex, even if it's complex in a silly way like 0i.
  • ERR:INVALID occurs if this statement is used outside a program.
  • ERR:SYNTAX occurs if an If is the last statement in the program, or the last except for one empty line.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/if


The If Command

if.png

Command Summary

Sets a condition for a line or several lines to be executed.

Command Syntax

If condition
:statement


:If condition Then

:EndIf

Menu Location

Starting in the program editor:

  • Press F2 to enter the Control menu.
  • Press 1 to paste If.

Calculator Compatibility

This command works on all calculators.

Token Size

2 bytes for If or If..Then;
2 bytes for Else;
2 bytes for ElseIf..Then;
2 bytes for EndIf.

The If command is the most basic tool in programming. The idea is simple: it checks a condition, and then does something only if the condition is true.

If by itself

With the simplest use of If, the line after it will be skipped if the condition is false.

In the code below, if x really is 4, then the check x=4 is true, so the program will display "x equals 4". If x is not 4, then the check will be false, so Text "x equals 4" will be skipped. Nothing will be displayed.

:If x=4
: Text "x equals 4"

If..Then..EndIf

To have multiple lines of code depend on the same condition, use the If condition Then..EndIf syntax. Every line before the EndIf will be skipped if the condition is false.

In the following example, both true→xisfour and Text "x equals 4" depend on the condition x=4.

:If x=4 Then
: true→xisfour
: Text "x equals 4"
:EndIf

If..Then..Else..EndIf

Often, you want to do one thing if the condition is true, and another if the condition is false. The way to do this is to insert an Else into the If..EndIf block. Everything between If condition Then and Else is what happens when the condition is true. Everything between Else and EndIf is what happens when the condition is false.

Note: the Else command is also used inside Try..EndTry blocks.

In the following example, "x is 4" will be displayed if x=4, and "x is not 4" otherwise.

:If x=4 Then
: Text "x is 4"
:Else
: Text "x is not 4"
:EndIf

ElseIf..Then

Finally, you can use ElseIf condition Then, inside an If..EndIf block, to consider several conditions at the same time. The way this works is: first the basic If condition is checked. If it's true, then the code just after If runs. If that condition was false, but there's an ElseIf, the ElseIf's condition is checked. If it's true, then the code just after the ElseIf runs. If that condition was false too, the program goes on to check the next ElseIf (if there is one), and so forth. You can also include a final Else (optionally) which will only run if no condition is met.

For example:

:If x=4 Then
: Text "x is 4"
:ElseIf x=5 Then
: Text "x is 5"
:ElseIf x=6 Then
: Text "x is 6"
:Else
: Text "x is neither 4, 5, nor 6"
:EndIf

Conditions

What kind of conditions are possible? Any command that returns a logical value — true or false — is acceptable. This includes:

  • Relational operators: =, , >, , <, and
  • Logical operators: and, or, xor, not
  • Any advanced test command: pxlTest(), isPrime(), and others.
  • A variable that contains one of the values true or false, or a function that returns them.

Of course, these can also be combined: for example, isPrime(x) and x≠2 is a valid condition.

Optimization

Use If without a Then or EndIf for only one command; use Then and EndIf otherwise.

In addition, the when() command can often replace If.

Error Conditions

20 - A test did not resolve to TRUE or FALSE happens when the condition is indeterminate, or the wrong data type.

280 - Else and ElseIf invalid outside If..Then block happens when Else or ElseIf are used outside If..EndIf.

730 - Missing start or end of block syntax happens when the If-Thens and EndIfs don't match up correctly.

740 - Missing Then in the If..EndIf block happens when a Then is missing.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:if


The imag( Command
IMAG.GIF

Command Summary

Returns the imaginary part of a complex number.

Command Syntax

imag(value)

Menu Location

Press:

  1. MATH to access the math menu.
  2. RIGHT, RIGHT to access the CPX (complex) submenu.
  3. 3 to select imag(, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

imag(z) returns the imaginary part of the complex number z. If z is represented as x+iy where x and y are both real, imag(z) returns y. Also works on a list of complex numbers.

imag(3+4i)
     4

imag({3+4i,-2i,17})
     {4,-2,0}

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/imag


The IndpntAsk Command
INDPNTASK.GIF

Command Summary

Doesn't automatically fill in table values for the independent variable.

Command Syntax

IndpntAsk

Menu Location

Press:

  1. 2nd TBLSET to access the table settings menu.
  2. Use arrows and ENTER to select Ask in the Indpnt: line.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

With the IndpntAsk setting, the independent variable (X, T, θ, or n depending on graphing mode) will not be calculated automatically in the table. Instead, when looking at the table, you must select an entry in the independent variable column, press ENTER, and enter a value. The values entered will also be stored to the TblInput list.

(To access the table, press [2ND][TABLE], or use the DispTable command in a program)

The alternative, IndpntAuto, fills in several values starting at TblStart and increasing by ΔTbl, and makes the table scrollable (up and down).

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/indpntask


The IndpntAuto Command
INDPNTAUTO.GIF

Command Summary

Automatically fills in the table values for the independent variable.

Command Syntax

IndpntAuto

Menu Location

Press:

  1. 2nd TBLSET to access the table settings.
  2. Use arrows to select Auto in the Indpnt line to select IndpntAuto.

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The IndpntAuto setting sets the independent variable (X, T, θ, or n depending on graphing mode) to be filled in automatically in the table (which is accessible by pressing 2nd TABLE, or from a program with the DispTable command).

The values which will be filled in start at the value TblStart and increment by ΔTbl(which can be negative, but not 0). They will also be stored in the list TblInput. All these variables can be accessed through the VARS|6:Table… menu; TblStart and ΔTbl can also be edited in the [2ND][TBLSET] menu.

The other possibility for this setting is IndpntAsk - if that setting is turned on, you must scroll to the corresponding row in the independent variable column, and enter a value.

Error Conditions

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/indpntauto


The Input Command
INPUT_ANIMATED.gif

Command Summary

Prompts the user to enter a value and then stores the value to the variable.

Displays the graph screen and then the user can move around the cursor.

Command Syntax

Input

Input ["Text",]variable

Menu Location

While editing a program press:

  1. PRGM to enter the PRGM menu
  2. RIGHT to enter the I/O menu
  3. 1 to choose Input

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The Input command is the other way of getting user input on the home screen (getting user input on the graph screen is only possible with the getKey command). The Input command asks the user to enter a value for a variable (only one variable can be inputted at a time), waiting until the user enters a value and then presses ENTER. It does not display what variable the user is being asked for, but instead just displays a question mark (?).

Because just displaying a question mark on the screen does not really tell the user what to enter for input or what the input will be used for, the Input command has an optional text message that can be either text or a string variable that will be displayed alongside the input.

Only the first sixteen characters of the text message will be shown on the screen (because of the screen dimensions), so the text message should be kept as short as possible (a good goal is twelve characters or less). This is so the value the user inputs can fit on the same line as the text. In the case that the value is too long, it will wrap around to the next line.

PROGRAM:INPUT
:"Fruit
:Input "Best "+Ans,Str1
:Input "Worst "+Ans,Str2
:Disp "That's "+Ans+"astic!

Input can be used to display every variable just before it requests user input, but some of the variables have to be entered in a certain way. If the variable is a string or a Y= function, the user must put quotes ("") around the value or expression. The user must also put curly braces ({}) around lists with the list elements separated by commas, and square brackets ([]) around matrices with the matrix elements separated by commas and each row individually wrapped with square brackets.

Advanced Uses

When you just use the Input command by itself (without any arguments), the graph screen will be shown and the user can move the cursor around. Program execution will then pause until the user presses ENTER, at which time the coordinates of the cursor will be stored to the respective variables (R and θ for PolarGC format, otherwise X and Y).

If a text message is longer than twelve characters or you want to give the user plenty of space to enter a value, you can put a Disp command before the Input command. You break the text message up and display it in parts. The Input command will be displayed one line lower, though, because the Disp command automatically creates a new line.

:Disp "What is your"
:Input "Name",Str0

Normally you can't get a quote character into a string (because quotes are used to identify the beginning and end of the string), but the Input command actually allows the user to enter a quote character (") as part of a string. This works without problems, and the quote can even be accessed by the user afterwards.

Because a user-defined list variable doesn't need the prefixed character before it when referring to the list, you may be only asking the user to input a simple real variable but a list would also be allowed. There is nothing you can really do about this problem, except including the prefixed character when wanting a list inputted and trying to limit your use of Input and Prompt.

:Input A
should be
:Input ∟A

Optimizations

When you are just using the text message to tell the user what the variable being stored to is, you should use the Prompt command instead. And, if there is a list of Input commands following the same pattern, you can reduce them to just one Prompt command.

:Input "A",A
:Input "B",B
Replace with Prompt
:Prompt A,B

Error Conditions

  • ERR:INVALID occurs if this statement is used outside a program.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/input


The Input Command

input.png

Command Summary

Asks for a value to be typed in on the I/O screen.

Command Syntax

Input [prompt,]variable
Input

Menu Location

Starting in the program editor:

  • Press F3 to enter the I/O menu.
  • Press 3 to select Input.

Calculator Compatibility

This command works on all calculators.

Token Size

3 bytes

Input prompt, variable displays prompt (which should be a string) on a new line on the Program I/O screen, then waits for the user to type in an expression on the next line. Whatever is typed in is then stored to variable. You can leave out the prompt part to just have the prompt be a question mark.

Note that whatever is typed in will be interpreted very literally: you'll need { } brackets to enter a list, quotes to enter a string, and so on. If you do want to enter a string, InputStr is probably a better choice.

Prompt is a special case of Input: Prompt variable works just as Input does, with variable? (the variable name, and a question mark) as the prompt.

If there's an error (for example, a syntax error) in the line that got typed in, the calculator will display the appropriate error message, and ask for the line to be typed in again: the program will continue running as usual. The calculator can even be turned off while Input is running; when it's turned back on, it will continue waiting for input, and then the program will still continue running.

Advanced Uses

Another use of Input is without any parameters at all: Input by itself will display a cursor on the graph screen, and wait until a point is selected (the cursor can be moved left and right as usual, and a point is selected by pressing ENTER).

You can find out which point was selected by using the xc and yc system variables (xc is the x-coordinate, and yc is the y-coordinate). The Coordinates graph setting determines other behavior:

  • If it's set to RECT, the values of xc and yc will be displayed at the bottom of the screen when the point is being selected.
  • If it's set to POLAR, the polar coordinates will be stored to system variables rc and θc (in addition to the regular coordinates). The values of rc and θc will be displayed while the point is being selected.
  • If it's set to OFF, no coordinates will be displayed (although xc and yc will still contain the resulting coordinate).

If Input is located inside a Try..EndTry block, and the ON key is pressed, the "Break" error will be caught (one of the only times this happens). If you're a nice person, you can use this to add code to exit quietly (without an error message) when ON is pressed. If you're not a nice person, you can use this to create an infinite loop you can't use ON to break out of.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:input


The InputStr Command
InputStr68K.gif

Command Summary

Stores a string to a variable

Command Syntax

InputStr variable

Menu Location

In the program editor, press [F3][4]

Calculator Compatibility

TI 89(T)/92

Token Size

1 byte or 2 bytes

The InputStr command allows you to input a string to a variable. Since Input doesn't support the storing of strings into variables, you have to use this command to do that. Keep in mind that the inputted variable cannot be the name of a preexisting variable or flash application that is locked, protected, or archived. For example, if you had a program named "a" or "hello", the command wouldn't work because it is already in use.

InputStr A
//Here, you would a string to be stored to the variable A

InputStr hello
//This would store the string into the variable "hello".

Related Commands

Error Conditions

980 - Variable is locked, protected, or archived happens when the user attempted to redefine/modify an already defined variable.

Also See

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:inputstr


The inString() Command

instring.png

Command Summary

Finds a search string in another string.

Command Syntax

inString(string, search-string,[)

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press D to enter the Strings submenu.
  • Press 6 to select inString(.

Calculator Compatibility

This command works on all calculators.

Token Size

3 bytes

The inString() command searches for one string inside another, starting from the beginning and going forward. If it finds the string, it returns the position where it finds it. If it doesn't find the string, it returns 0. If the string is there multiple times, it will only find the first one.

Optionally, you can also give inString() a starting position. In that case, it won't find any occurrences of the strings earlier than that position.

:inString("Chop shops stock chops.","hops")
           7
:inString("Chop shops stock chops.","hops",8)
           20
:inString("Chop shops stock chops.","stocks")
           0

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:instring


The inString( Command
INSTRING.GIF

Command Summary

Finds the first occurrence of a search string in a larger string.

Command Syntax

inString(haystack, needle, starting point)

Menu Location

This command can only be found in the Catalog. Press:

  1. 2nd CATALOG to access the command catalog
  2. I to skip to command starting with I
  3. scroll down to find inString( and select it

Calculator Compatibility

TI-83/84/+/SE/CSE/CE

Token Size

2 bytes

The inString( command searches a string for occurrences of a smaller string (similar to the Find feature on a computer), and returns the first such occurrence.

The source string is the string you want to search through; the search string is the substring you want to find. inString( will return the index of the first letter of the first occurrence of the search string found, or 0 if the search string is not present. For example:

:inString("TI-BASIC","BASIC
    4
:inString("TI-BASIC","TI
    1
:inString("TI-BASIC","I
    2
:inString("TI-BASIC","ELEPHANT
    0

You can also provide the optional starting point argument, 1 by default, that will tell the command where it should start looking. If you provide a value higher than 1 here, the command will skip the beginning of the string. This can be used to find where the search string occurs past the first occurrence. For example:

:inString("TI-BASIC","I
    2
:inString("TI-BASIC","I",2
    2
:inString("TI-BASIC","I",3
    7

Advanced Uses

You can use inString( to convert a character to a number. For example:

:inString("ABCDEFGHIJKLMNOPQRSTUVWXYZ",Str1→N

Assuming Str1 is one character long and contains a capital letter, N will hold a value of 1-26 that corresponds to that letter. This value can then be stored in a real number, list, or matrix, where a character of a string couldn't be stored. To get the character value of the number, you can use the sub( command:
:sub("ABCDEFGHIJKLMNOPQRSTUVWXYZ",N,1→Str1

Using the starting point argument of inString(, you can write a routine to return all occurrences of the search string in the source string:

:0→dim(L1
:inString(Str0,Str1
:Repeat not(Ans
:Ans→L1(1+dim(L1
:inString(Str0,Str1,Ans+1
:End

If the search string is not found, this routine will return {0} in L₁. If it is found, the result will be a list of all the places the string was found.

Optimization

The inString( command can replace checking if a string is one of a number of values. Just put all the values in a string, one after the other, and try to find the string to be checked in the string of those values:

:If Str1="." or Str1=",
can be
:If inString(".,",Str1

Be careful, because if Str1 were ".," in the above example, this would also be treated like "." or ",". If this is a problem, you can separate the values you want to check for by a character you know can't be in the string:

:If Str1="HELLO" or Str1="HI
can be
:If inString("HELLO,HI",Str1

This approach assumes that a comma would never be in Str1, and words like "HELL" or "I" are also impossible. If words like these can appear in the input, the following works:
:If inString("HELLO,HI,",Str+",

(still assumes commas aren't in Str1)

Error Conditions

  • ERR:DOMAIN is thrown if starting point is not a positive integer (starting point may be longer than the length of the source string, though).

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/instring


The int() Command

int.png

Command Summary

Returns the floor of a number.

Command Syntax

int(value)

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The int() command rounds a number down to the nearest integer less than or equal to the number. For instance, int(π) returns 3, while int(-π) returns -4.

The command is an alias for floor(): they do the exact same thing. The calculator prefers using floor() (in fact, int() will be converted to floor() in symbolic expressions); int() is left over from earlier calculator models. Other rounding commands include:

  • ceiling() — like floor(), but always rounds up (to the next higher integer).
  • iPart() — truncates a number to just its integer part (or, if you prefer, rounds a number toward 0).
  • round() — rounds to a specific place value, not just to an integer, but round(x,0) will round x to the nearest integer, up or down.

int() can also be applied to complex numbers, lists, and matrices, rounding everything that there is to round in each of them.

:int(3)
           3
:int({-π,π})
           {-4  3}

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:int


The int( Command
INT.GIF

Command Summary

Rounds a value down to the nearest integer.

Command Syntax

int(value)

Menu Location

Press:

  1. MATH to access the math menu.
  2. RIGHT to access the NUM submenu.
  3. 5 to select int(, or use arrows.

Calculator Compatibility

TI-83/84/+/SE/CE

Token Size

1 byte

int(X) is the floor function. It returns the greatest integer less than or equal to X, and also works on complex numbers, lists and matrices.

int(5.32)
               5
int(4/5)
               0
int(‾5.32)
               ‾6
int(‾4/5)
               ‾1

The difference between iPart( and int( is subtle, and many people aren't even aware of it, but it exists. Whereas iPart( always truncates its parameters, simply removing the fractional part, int( always rounds down. This means that they return the same answers for positive numbers, but int( will return an answer 1 less than iPart( for (non-integer) negative numbers. For example, iPart(-5.32) is -5, while int(-5.32) is -6.

Most of the time, however, you're dealing with only positive numbers anyway. In this case, the decision to use iPart( or int( is mostly a matter of preference - some people use int( because it is shorter; some use iPart( when there is a corresponding fPart( taken. However, if speed is a consideration, one should check the Command Timings section.

Advanced Uses

int(, along with iPart( and fPart(, can be used for integer compression.

Command Timings

The following table compares the speeds of int( and iPart(. Each command was timed over 2000 iterations to find a noticeable difference.

Format Bars Pixels Total
iPart(1 10 1 81
iPart(1.643759 10 1 81
int(1 8 7 71
int(1.643759 10 2 82

Conclusion: int( scales with the length of its input while iPart( does not. For fewer than 6 decimals, int( will most often be faster; for 6 or more decimals, consider using iPart(.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/int


The intDiv() Command

intdiv.png

Command Summary

Returns the whole number part of a division.

Command Syntax

intDiv(dividend,divisor)

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The integer division command, intDiv(a,b) returns the whole number portion of a/b: this is equal to iPart(a/b). Although this operation is most useful for dividing whole numbers, this definition works for any number, whole or decimal, real or complex.

:intDiv(125,3)
           41
:intDiv(-125,3)
           -41
:intDiv(125,π)
           39

Advanced Uses

The intDiv() command also works for lists and matrices. Used with a list or matrix and a number, intDiv() is applied to the number paired with every element of the list or matrix. Used with two lists or two matrices, which must match in size, intDiv() is applied to matching elements of the list or matrix.


Use intDiv() and remain() for the quotient and remainder results of long division, respectively.

Optimization

Constructions like iPart(a/b) should be replaced with intDiv(a,b): this is smaller and faster.

Error Conditions

240 - Dimension mismatch happens when two list or matrix arguments don't match in size.

Division by zero does not throw an error; an undefined value is returned instead.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:intdiv


The invNorm( Command
INVNORM.GIF

Command Summary

Calculates the inverse of the cumulative normal distribution function.

Command Syntax

invNorm(probability[,μ, σ])

Menu Location

Press:

  1. 2ND DISTR to access the distribution menu
  2. 3 to select invNorm(, or use arrows.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

invNorm( is the inverse of the cumulative normal distribution function: given a probability, it will give you a z-score with that tail probability. The probability argument of invNorm( is between 0 and 1; 0 will give -1E99 instead of negative infinity, and 1 will give 1E99 instead of positive infinity

There are two ways to use invNorm(. With three arguments, the inverse of the cumulative normal distribution for a probability with specified mean and standard deviation is calculated. With one argument, the standard normal distribution is assumed (zero mean and unit standard deviation). For example:

for the standard normal distribution
:invNorm(.975

for the normal distribution with mean 10 and std. dev. 2.5
:invNorm(.975,10,2.5

Advanced

This is the only inverse of a probability distribution function available (at least on the TI-83/84/+/SE calculators), so it makes sense to use it as an approximation for other distributions. Since the normal distribution is a good approximation for a binomial distribution with many trials, we can use invNorm( as an approximation for the nonexistent "invBinom(". The following code gives the number of trials out of N that will succeed with probability X if the probability of any trial succeeding is P (rounded to the nearest whole number):

:int(.5+invNorm(X,NP,√(NP(1-P

You can also use invNorm() to approximate the inverse of a t-distribution. Since a normal distribution is a t-distribution with infinite degrees of freedom, this will be an overestimate for probabilities below 1/2, and an underestimate for probabilities above 1/2.

Formulas

Unlike the normalpdf( and normalcdf( commands, the invNorm( command does not have a closed-form formula. It can however be expressed in terms of the inverse error function:

(1)
\begin{align} \operatorname{invNorm}(p) = \sqrt{2}\,\operatorname{erf}^{-1}(2p-1) \end{align}

For the arbitrary normal distribution with mean μ and standard deviation σ:

(2)
\begin{align} \operatorname{invNorm}(p,\mu,\sigma)=\mu+\sigma\operatorname{invNorm}(p) \end{align}

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/invnorm


The invT( Command
invT.png

Command Summary

Calculates the inverse of the cumulative Student's t-distribution function with degrees of freedom ν.

Command Syntax

invT(probability, ν)

Menu Location

Press:

  1. 2ND DISTR to access the distribution menu
  2. 4 to select invT(, or use arrows.

Calculator Compatibility

TI-84+/SE (OS 2.30 or greater)

Token Size

2 bytes

invT( is the inverse of the cumulative Student t distribution function: given a probability p and a specified degrees of freedom v, it will return the number x such that tcdf(E-99,x,v) is equal to p

:invT(.95,24
    1.710882023

Advanced

invT( is meant for use with so-called "one-tailed' tests; for two-tailed tests, the proper expression to use (corresponding to the inverse of tcdf(-x,x,v)) is invT(.5(1+p),v)

Formulas

Unlike the tpdf( and tcdf( commands, the invT( command does not have a closed-form formula. However, it can be expressed in terms of the inverse incomplete beta function.

For one degree of freedom, invT( is expressible in terms of simpler functions:

(1)
\begin{align} \operatorname{invT}(p,1)=\tan\left(\pi\left(p-\frac1{2}\right)\right) \end{align}

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/invt


The iPart() Command

ipart.png

Command Summary

Returns the integer part of a number.

Command Syntax

iPart(value)

Menu Location

  • Press 2nd MATH to enter the MATH popup menu.
  • Press 1 to enter the Number submenu.
  • Press 4 to select iPart(.

Calculator Compatibility

This command works on all calculators.

Token Size

1 byte

The iPart() command returns the integer part of a number (removing all the digits after the decimal). Another way of thinking about it is it rounds a number towards 0: positive numbers get rounded down to an integer, and negative numbers get rounded up to an integer.

There are several other rounding commands available, which work in subtly different ways:

  • ceiling() always rounds up to the next higher integer.
  • floor() always rounds down to the next lower integer. int() does the same thing as floor().
  • round() rounds to any given place value, including to an integer; it rounds up or down, whichever is nearest.

However, iPart() is the only one that has a counterpart fPart() which returns the fractional part of a number. This follows the rule that iPart(x)+fPart(x) always equals x.

Using iPart() on the result of a division — iPart(x/y) — is useful so often that there's a specific command, intDiv(), for doing so.

iPart() can also be applied to complex numbers, lists, and matrices, rounding everything that there is to round in each of them.

:iPart(3)
           3
:iPart({-π,π})
           {-3  3}

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:ipart


The iPart( Command
IPART.GIF

Command Summary

Returns the integer part of a value.

Command Syntax

iPart(value)

Menu Location

Press:

  1. MATH to access the math menu.
  2. RIGHT to access the NUM submenu
  3. 3 to select iPart(, or use arrows.

Calculator Compatibility

TI-83/84/+/SE/CE

Token Size

1 byte

iPart(value) returns the integer part of value, and extends to complex numbers, lists, and matrices.

iPart(5.32)
               5
iPart(4/5)
               0
iPart(‾5.32)
               ‾5
iPart(‾4/5)
               0

iPart is sometimes used with it's corresponding partner fPart. While iPart trims off the part before the decimal point, fPart trims off the part after it.

The difference between iPart( and int( is subtle; while iPart( always truncates its parameters, simply removing the integer part, int( always rounds down. This means that they return the same answers for positive numbers, but int( will return an answer 1 less than iPart( for (non-integer) negative numbers. For example, iPart(-5.32) is -5, while int(-5.32) is -6.

In this case of positive values, though, the decision to use iPart( or int( is mostly a matter of preference - some people only use int( because it is shorter, some people use iPart( when there is a corresponding fPart( taken. However, see the Command Timings section.

Watch Out For Precision Issues

1/3*3→X   // X is expected to be 1
X         // Displays 1, but is actually 0.99999999999999 in memory
iPart(X)  // Displays 0
fPart(X)  // Displays 1, but is actually 0.99999999999999 in memory

Somewhat unintuitively, the code above displays the results 1, 0 and 1. This is due to the calculator storing values to 14 digits of precision, but rounding the value to 10 digits to fit on the home screen.

Tip: If you enter a value in the list editor screen, you will be able to see all 14 digits of precision. This can help you troubleshoot issues like these.

One workaround is to round the numbers prior to calling iPart() or fPart(), if you don't mind the slight loss in precision from 14 significant digits to 9 decimal places:

1/3*3→X
iPart(round(X,9))   // Displays the expected result 1
fPart(round(X,9))   // Displays the expected result 0

(The parameter 9 is not technically required here since 9 is the default, but is shown for clarity and in case you want to customize the level of precision.)

Advanced Uses

iPart(, along with fPart( and int(, can be used for integer compression.

Command Timings

The following table compares the speeds of int( and iPart(. Each command was timed over 2000 iterations to find a noticeable difference.

Format Bars Pixels Total
iPart(1 10 1 81
iPart(1.643759 10 1 81
int(1 8 7 71
int(1.643759 10 2 82

Conclusion: With 5 or fewer decimal places, you should consider using int( because of its speed, but with more decimals, iPart( remains constant to eventually beat out its counterpart.

Related Commands

See Also

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/ipart


The irr( Command
IRR.GIF

Command Summary

Calculates the Internal Rate of Return of an investment.

Command Syntax

irr(CF0,CFList,[freq])

Menu Location

On the TI-83, press:

  1. 2nd FINANCE to access the finance menu.
  2. 8 to select irr(, or use arrows and ENTER.

On the TI-83+ or higher, press:

  1. APPS to access the applications menu.
  2. 1 or ENTER to select Finance…
  3. 8 to select irr(, or use arrows and ENTER.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The irr( command finds the Internal Rate of Return of an investment, which is a measure of its efficiency. Its mathematical interpretation is the interest rate for which npv( will return 0 for the same cash flows.

irr( takes three arguments: an initial cash flow (CF0), a list of further cash flows (CFList), and an optional frequency list.

Advanced Uses

irr( can be used to find a root of a polynomial of any degree, give by a list of its coefficients:

1+.01irr(0,{list of coefficients})

However, this method is limited to finding roots greater than 0, and will throw an error (ERR:NO SIGN CHG or ERR:DIVIDE BY 0) if it can't find such roots. By reversing the list of coefficients and taking the reciprocal of the roots found, you could find roots less than 0, but this would still result in errors if such roots don't exist either.

Using solve( to find roots of polynomials is less efficient, but more reliable, since it doesn't throw an error unless there are no roots at all to be found.

Formulas

Solving for irr( requires solving a polynomial with degree equal to the total number of cash flows. As such, there is no general formula for calculating irr(, though numerical methods are possible for finding an approximate solution.

The polynomial associated with the calculation is:

(1)
\begin{align} \sum_{i=0}^{N}{C_i\left(1+\frac{\mathrm{Irr}}{100}\right)^{N-i}}=0 \end{align}

Here, Irr is the internal rate of return, N is the number of cash flows, and Ct is the t th cash flow.

To the calculator, only roots for which Irr>0 are considered to be viable.

Error Conditions

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/irr


The IS>( Command
IS_ANIMATED.gif

Command Summary

Increments a variable by 1 and skips the next command if the variable is greater than the value.

Command Syntax

IS>(variable,value)
command

Menu Location

While editing a program, press:

  1. PRGM to enter the PRGM menu
  2. A to choose IS>(, or use arrows

Calculator Compatibility

TI-83/84/+/SE

Token Size

1 byte

The increment and skip if greater than command — IS>( — is a specialized conditional command. It is equivalent to an If conditional, except the next command will be skipped when the condition is true and it has a variable update built-in. However, it is not used very often (if anything, it is often misused as a looping command) because of its obscure name and somewhat limited application.

The IS>( command takes two arguments:

  • A variable, which is limited only to one of the real variables (A-Z or θ).
  • A value, which can be any expression which evaluates to a real number.

When IS>( is executed it adds one to the variable (increments it by one), and compares it to the value. The next command will be skipped if the variable is greater than the value, while the next command will be executed if the variable is less than or equal to the value.

The command IS>(A,B is equivalent to the following code:

:A+1→A
:If A≤B

Here are the two main cases where the IS>( command is used:

:7→A
:IS>(A,6
:Disp "Skipped
  • Initializes A to 7 and then compares to the value
  • 7>6 is true so the display message won't be displayed
:1→B
:IS>(B,2
:Disp "Not Skipped
  • Initializes B to 1 and then compares to the value
  • 1>2 is false so the display message will be displayed

Note: In addition to both of these cases, there is also the case where the variable and the value are equal to each other. This case is shown below under the 'Advanced Uses' section because it has some added background that goes with it.

Advanced Uses

When you want the skipping feature of the IS>( command to always occur, you just have to use the same variable for both the variable and value arguments of the command:

:IS>(B,B

An undefined error will occur if the variable and/or value doesn't exist before the IS>( command is used, which happens when the DelVar command is used. Consequently, you should not use DelVar with IS>(.

Similar code can be used as a substitute for B+1→B if you don't want to change Ans:

:IS>(B,B:

Note that due to the colon after the line, there will be no statement skipped, so you don't have to worry about that.

Optimization

Because the IS>( command has the variable update built-in, it is smaller than manually incrementing a variable by one along with using an If conditional.

:A+1→A
can be
:IS>(A,0

The one caution about this is that if the variable is greater than the value (in this case, '0'), the next command will be skipped. If you don't want the skipping functionality, then you need to make sure that the value is never less than the variable. This is not always possible to do. Also, IS>( is slightly slower than its more normal counterpart.

Related to the example code given, IS>( should always have a command following after it (i.e., it's not the last command in a program) because it will return an error otherwise. If you have no particular code choice, just put an empty line or something meaningless.

Command Timings

Using IS>( to increment a variable is approximately 25% slower than using code like X+1→X. However, it is faster to use IS>( than to construct an If statement to do the same thing.

Note, however, that a quirk in the For( command (see its Optimizations section) will slow down the IS>( command significantly if a closing parenthesis is not used for the For( statement.

Error Conditions

  • ERR:INVALID occurs if this statement is used outside a program.
  • ERR:UNDEFINED is thrown if the variable to be incremented is not defined.
  • ERR:SYNTAX is thrown if there is no next line to skip, or if there is only one next line and it is empty.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/is


The isClkOn() Command

isclkon.png

Command Summary

Checks if the hardware clock is turned on.

Command Syntax

isClkOn()

Menu Location

This command can't be found in any menu besides the command catalog.

Calculator Compatibility

This command requires a calculator with AMS version 2.07 or higher (it will also work on any TI-89 Titanium or Voyage 200 calculator)

Token Size

3 bytes

The isClkOn() command checks if the calculator's clock (which is used by most time and date commands) is running or stopped. The result of isClkOn() is a truth value — true if the clock is on, and false if the clock is off — which makes it perfect for a condition in commands such as If:

:If isClkOn() Then
: Disp "Clock is running."
:Else
: Disp "Clock is stopped."
:EndIf

The isClkOn() command, though useful, isn't often called for. For instance, there's no need to check if the clock is on if you're planning to turn it on anyway:

:If not isClkOn()
: ClockOn

should just be

:ClockOn

One use for isClkOn() is in functions, which aren't allowed to change the global status of the calculator with commands like ClockOn or ClockOff. Instead, you might do the next best thing, and return an error message if the clock is turned off.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:isclkon


The isClockOn Command
ISCLOCKON.GIF

Command Summary

Returns whether the clock on the TI-84+/SE is on or off.

Command Syntax

isClockOn

Menu Location

This command can only be found in the catalog. Press:

  1. 2nd CATALOG to enter the command catalog
  2. i to skip to commands starting with I
  3. Scroll down to isClockOn and select it

Calculator Compatibility

TI-84+/SE

Token Size

2 bytes

The isClockOn command returns whether the clock on the TI-84+/SE calculators is on or off. The command will return 1 if the clock is enabled and 0 if it is not. You can store it to a variable for later use, or use it in conditionals and loops as part of the condition. For example, here is how you would check to see if the clock is on:

:If isClockOn
:Then
  (code if clock is on)
:Else
  (code if clock is off)
:End

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/isclockon


The Item Command

item.png

Command Summary

Adds an item to a Custom or ToolBar menu.

Command Syntax

Item text (with Custom)
Item text,label (with ToolBar)

Menu Location

Starting in the program editor:

  • Press F3 to enter the I/O menu.
  • Press 1 to enter the Dialog submenu.
  • Press 8 to select Item.

Calculator Compatibility

This command works on all calculators.

Token Size

3 bytes

The Item command is used in Custom..EndCustm and ToolBar..EndTBar blocks (both of which create toolbar menus) to add an option to one of the tabs. See these commands for more details on how to use it.

Inside a Custom..EndCustm menu, the correct syntax is Item text (text being a string). This will display text for the menu option, and also paste text every time the option is selected.

Inside a ToolBar..EndTBar menu, the correct syntax is Item text,label. This will, as in the previous case, display text for the menu option; when the option is selected, the program will resume running from Lbl label.

Error Conditions

130 - Argument must be a string happens when the option text isn't a string.

500 - Invalid label happens when the label doesn't exist (in this program), when the option is selected.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/68k:item


The LabelOff Command
LABELOFF.GIF

Command Summary

Disables labels on the X and Y coordinate axes.

Command Syntax

LabelOff

Menu Location

Press:

  1. 2nd FORMAT to access the format menu.
  2. Use arrows and ENTER to select LabelOff.

Calculator Compatibility

TI-83/84/+/SE

Token Size

2 bytes

The LabelOff setting disables labels on the X and Y coordinate axes. This is unnecessary if you've disabled the axes themselves, since the labels are only displayed when the axes are. To enable the labels, use the reverse setting LabelOn.

Related Commands

For the most up-to-date version of this command, see http://tibasicdev.wikidot.com/labeloff

page 1 of 212next »

Binary To Decimal

Routine Summary

Converts a binary (base 2) number to a decimal (base 10) number.

Inputs

Ans - The binary number that you want to convert expressed as a list, stored in Ans.

Outputs

Ans - The decimal representation of the binary number.

Variables Used

Ans, A

Calculator Compatibility

TI-83/84/+/SE

Author

imcoraline

:sum(seq(Ans(dim(Ans)-A)2^A,A,0,dim(Ans)-1

This routine takes a positive whole binary number (base 2), expressed as a list, and converts it to the equivalent decimal (base 10) representation. To express a binary number in a list, you simply put commas in between each digit, and then surround that with list brackets. For example, the binary number 101101 expressed a list would be {1,0,1,1,0,1}. To learn how to convert a binary number to a decimal number, vice versa, and even see how to convert to and from other bases besides binary and decimal, see the Binary and Hexadecimal page.

It also may be important to note that adding 0’s to the front of a binary number will not change the decimal equivalent. For example, both 01101012 and 1101012 are equivalent to 5310.

Error Conditions

  • ERR:DATA TYPE is thrown if the list has an imaginary number in it.
  • An error will not be thrown the list is not a binary number, or if any element in the list is negative or non-whole. Nonetheless, the conversion will not work correctly.

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/binary-to-decimal


Blinking Text

Routine Summary

Creates a blinking effect on the home screen.

Inputs

Str1 - the text to blink on the screen
A,B - the Output( coordinates for the text
N - the length of the text to be displayed

Outputs

None

Variables Used

Str1, N, A, B, Ans

Calculator Compatibility

TI-83/84/+/SE

Download

blink.zip

:length(Str1→N:1
:Repeat getKey
:If dim(rand(15
:Output(A,B,sub(Str1+" (N spaces) ",1+NAns,N
:not(Ans
:End

By leaving 1 by itself on one line, we store it to Ans, which will be easier to work with. Then, the Repeat getKey loop will keep blinking the text until a key — any key — is pressed.

Output(A,B,sub(Str1+" (N spaces) ",1+NAns,N will display either the text or the equivalent number of spaces on the screen at coordinates (A,B). If you want to blink the text "Hello", for example, then you would need to use five spaces. We negate Ans's value with not(, which acts as a flag to control the blinking.

If dim(rand(15 is a clever way of delaying the blinking, so that it doesn't blink too fast. rand(15 generates a list of 15 random numbers, which is a slightly time-consuming process. If dim( is just a way of wrapping this list so it doesn't change Ans. Since dim(rand(15 is always 15, the If statement will always be true, so we don't have to worry about the next line being skipped. By changing 15 to a lower or higher number, you can make the blinking go faster or slower, respectively.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/blinking-text


Custom Menu - Graph Screen
GraphMenu.png

Routine Summary

This routine is used for creating complex graphical menus. It can have hundreds of sub-menus, and works quite similarly to a menu on the home screen.

Inputs

Str1 - A list of menu options, each being of length L
L - The length of the sub-strings for the current menu
N - The number of options in the current menu
O - The menu identifier
S - The current item/row selected

Outputs

The variable(s) that the routine stores to at the end.
O - The menu identifier
S - The current item/row selected

Variables Used

Str1 - A list of menu options, each being of length L
L - The length of the sub-strings for the current menu
N - The number of options in the current menu
O - The menu identifier
S - The current item/row selected
K - A keystroke identifier
Xmin - Graph Settings
Xmax - Graph Settings
Ymin - Graph Settings
Ymax - Graph Settings
Theta - For Loop Counter
Z - For Loop Counter
GDB1 - Cleanup Variable

Calculator Compatibility

TI-83/84/+/SE

Author

Trenly

StoreGDB 1
Lbl M0
ClrDraw
AxesOff
GridOff
ClrHome
62→Ymax:0→Ymin
94→Xmax:0→Xmin
"1:Option 2:Option3:Option "→Str1
0→O:1→S:8→L:3→N
Lbl M
Text(0,0,"Custom Menu Beta 0.1"
Horizontal Ymax-7
For(θ,0,N-1
Text(8+7θ,0,sub(Str1,1+Lθ,L)
End
Horizontal Ymax-9-7N
For(θ,6,1,⁻1
For(Z,0,4
Pxl-Change(8+7S-θ,Z
End
End
Repeat sum(K={23,45,105
Repeat sum(K={23,45,105,34,25,72,73,74,82,83,84,92,93,94
getKey→K
End
If K=34(S<N) or K=25(S>1
Then
For(θ,6,1,⁻1
For(Z,0,4
Pxl-Change(8+7S-θ,Z
End
End
S+(K=34)-(K=25)→S
For(θ,1,6
For(Z,0,4
Pxl-Change(8+7S-θ,Z
End
End
End
If sum(K={72,73,74,82,83,84,92,93,94
Then
K-13int(K/13(2>abs(5-abs(5-abs(K-83
If Ans≤N and Ans>0
Then
Ans→S
105→K
End
End
End
ClrDraw
ClrHome
If (K=23)O:Goto M0
If (K=23)not(O:Goto E
If K=45:Goto E
If (O=0)(S=1:Goto M1
If (O=0)(S=2:Goto M2

--Add an if statement here for each option you have--
-- O defines which menu you are currently in --
-- S defines the option they selected --

Lbl E
ClrDraw
RecallGDB 1
ClrHome
Return

This menu is made for the graphscreen on monochrome calculators. It functions similarly to the Menu( command, in that it highlights the current menu option, and uses labels. To create your own menus, each menu needs a menu id, a string containing entries of the same length, the number of entries, the length of the entries, and the starting selection. What makes this code functional is that each menu option is referenced by a menu ID, and the number of the selection. Because of this, the same code can be used to display multiple menus.

In addition to the up and down arrows and enter, a user can use the numberpad to select an option. The clear key will exit the program from any menu, and the delete key will return to the main menu from inside any menu. If the delete key is used on the main menu, the program will end.

The main menu has an ID of 0 by default, and can be shown at any time using "Goto M0". Any sub-menus you wish to add should be in the following format. You will need to change O, L, and N for each menu. In the code below, O is set to 1. This is what gets referenced in the If statements in the main code. S is set to 1 since I want the first option to be selected when we load the menu. L is set to 22 in this example because each menu option is 22 characters long. You will notice there are spaces included to make sure each item is the same length. Finally, there are 6 options in this example, so N is set to 6. We then Goto M to display the menu

Lbl M1
"1:Kilograms◄ ►Lbs     2:Meters◄ ►Feet       3:ElectronVolt◄ ►Joule4:Joule◄ ►Calorie     5:Horsepower◄ ►Watt   6:Back                →Str1
1→O:1→S:22→L:6→N
Goto M

Error Conditions

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/custom-menu-graph-screen


Custom Menu Multi Page
wabbitemu.gif

Routine Summary

A custom menu with up to 9 switchable pages.

Inputs

Str1-Str9 - one string per page
A - Number of pages the menu includes

Outputs

B - the page they're on
X - the # choice they made

Variables Used

Ans, B, C, D, X, Str#

Calculator Compatibility

TI-83/84/+/SE

Author

Mr Dino

Download

MENUZ.zip

:1→B
:While 1
:If B=1:Str1
:If B=2:Str2
:If B=3:Str3
:If B=4:Str4
:If B=5:Str5
:If B=6:Str6
:If B=7:Str7
:If B=8:Str8
:If B=9:Str9
:ClrHome
:Output(1,1,Ans
:length(Ans)/16
:If fPart(Ans
:1+iPart(Ans
:Ans→D
:2→X
:Repeat C=24 or C=26
:Output(X,2,">
:Repeat Ans
:getKey→C
:End
:If Ans=21
:Then
:X-1→X
:Return
:End
:Output(X,2," " // space
:X-(Ans=25)+(Ans=34→X
:2(X>D)+D(X≤1)+X(X≤D and X>1→X
:max(1,min(A,B+(C=26)-(C=24→B
:End
:End

To use this code, store an integer to A 1-0 representing the number of pages that will be in your menu. It will use all strings Str1-StrA. Next, store the menu pages into the strings. They will be shown with 'Output(1,1,StrA)', so make sure that the menu looks right before using it. Make sure there are 16 characters in each line (starting with the title). Use spaces to make the words fit right, and you should probably test it to make sure it works. There should probably also be something in the title that signifies what page you're on. Finally, run the code as a subprogram.

Here's how it works:

B represents what page number it's on, so we start off by storing 1 to B to put us on page 1. Then we have a While 1 loop to manage page changes. Based on the value of B, it will put one of the strings into Ans. It will output Ans onto the home screen, then determine how many rows are in the menu and store that to D. And the user will always start out on option 1 - row 2 (because of the title screen).

Now we start the choice loop: We display the cursor, then wait for a keypress. If the use presses [2nd], we subtract 1 from X (for the offset from the title) and Return back to the parent program, with B as the page number and X as the choice number. But if not, it continues: The cursor is erased, X and B are changed according to the keypress, and if the use changed the page, it exits the choice loop and enters the page loop where it displays the new page and sets up for another choice loop.

Error Conditions

It won't work properly if A isn't an integer within the bounds 1-9 or if the strings don't represent the menu pages correctly.

Related Routines

There are several routines that are similar in functionality or are used in a similar context. Make a bulleted list of them, with links to the other routines' pages. It will often be the case that several routines all link to each other.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/custom-menu-multi-page


Day of Week

Routine Summary

Calculates the day of week of a date, without using dayOfWk( (because it's only available on the 84+ and 84+SE)

Inputs

D - The day
M - The month
Y - The year (1950 through 2049)

Outputs

Ans - 0-6 = the day of week (Sunday - Saturday)

Variables Used

D, M, Y, Ans

Calculator Compatibility

TI-83/84/+/SE

Download

weekday.zip

:round(7fPart(dbd(101.5,DE2+M+fPart(.01Y))/7

Using the dbd( command, we return the number of days between the given date and January 1, 1950, our base date. dbd('s argument, in this case, is of the form DDMM.YY, so we put the date we're given in that form with DE2+M+fPart(.01Y. Once we have the number of days between the two dates, we divide it by seven (as there are seven days in a week) to get the number of weeks.

However, we are not interested in the number of weeks between two dates, we are interested in how far into the week we are. That would be the fractional part of the number of weeks. For example, if there was fourteen days between two dates (the first date being a Sunday) and we divide that by seven, we would have the equation 14/7=2.00. The .00 means that the week hasn't yet begun (and so, the day is Sunday).

If there was 15 days between two dates, the equation would give 15/7=2.1428571. The .1428571 means that we are .1428571 into the week, and if we multiply that by seven, we get the equation .1428571*7=1. This means that we are one day into the week (and so, the day is Monday). So in our formula, after finding out the number of days between two dates, we find the fractional part of it, and multiply that by seven. Finally, round( gets rid of any minor rounding errors.

As the 1st of January, 1950 was a Sunday (which is the date we have inputed into the above routine), so the number of days into the week will always be relative to Sunday. That is, the output 0 through 6 is relative to the days Sunday through Saturday respectively. If you want 0 to be Monday instead, make the base date January 2 instead by changing 101.5 to 201.5.

This routine can handle dates from January 1, 1950 to December 31, 2049. For other dates, it will assume the year is in that range instead. There is also an alternative routine that handles dates in an unlimited range.

Display Day

Append the following code to display the day of the week:

:Disp sub("SUNDAY***MONDAY***TUESDAY**WEDNESDAYTHURSDAY*FRIDAY***SATURDAY*",9Ans+1,9      //replace *s with spaces

Or this code, which should display the day of the week, only the display method takes less space and space pads it.
Disp sub("***SUN***MON**TUESWEDNES*THURS***FRI*SATUR",6Ans+1,6)+"DAY       //replace *s with spaces

Error Conditions

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/day-of-week


Decimal to Base B

Routine Summary

Converts a decimal (base 10) number to a number in any other integer base B.

Inputs

A - The decimal number that you want to convert.
B/ - The base you want to convert A into.

Outputs

Ans - The base B representation of the decimal number, in list form.

Variables Used

{$variable}

Calculator Compatibility

TI-83/84/+/SE

Author

imcoraline

Download

[{$download}]

:iPart(ln(A)/ln(B
:BfPart(int(AB^(cumSum(binomcdf(Ans,0))-Ans-1))/B

This routine takes a positive whole decimal number (base 10), stored in A, and converts it to the equivalent representation in base B. The representation will be in list form. For example, the decimal number 32 is the base 2 number 100000, meaning the routine would result in the list {1,0,0,0,0,0}.

Note: This routine will not work for A<B.

It also may be important to note that adding 0’s to the front of a number will not change the decimal equivalent. For example, both 01101012 and 1101012 are equivalent to 5310.

Error Conditions

  • ERR:DATATYPE is thrown if A is complex or negative.
  • ERR:DOMAIN is thrown if A is 0 or less than B.
  • An error will not be thrown is A isn’t an integer. Nonetheless, the conversion will not work correctly.

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/decimal-to-binary


Decimal to Fraction

Routine Summary

Converts a decimal number to a fraction.

Inputs

Ans - the number you want to convert to a fraction

Outputs

Ans - the fraction in list format

Variables Used

Ans, X

Calculator Compatibility

TI-83/84/+/SE

Author

Weregoose

URL: United TI

Download

decimaltofraction.zip

:Ans→X:{1,abs(Ans
:Repeat E‾9>Ans(2
:abs(Ans(2){1,fPart(Ans(1)/Ans(2
:End
:round({X,1}/Ans(1),0
:Ans/gcd(Ans(1),Ans(2

Although there is a ►Frac command available for converting a decimal number to a fraction, this is only a formatting command and doesn't actually give you the numerator and denominator as separate numbers. This limits your choices for using fractions, especially since ►Frac only works with the Disp and Pause commands. In addition, it does not work very well, and fails for several inputs that you would think are within its ability to figure out (such as -1.3427625). Fortunately, you can improve upon the ►Frac command by using your own routine.

The basic algorithm that you use when converting a number to a fraction is commonly known as the Euclidean algorithm. While it has been around for literally millennia, it is still one of the best algorithms because of its sheer simplicity (it doesn't require any factoring or other complex math operations).

The way it works is that you have two numbers (in our routine, it's one and the decimal number you input), and you divide the first number by the second number, and check to see if there is a remainder. If there is a remainder, you then repeat the process again, except this time you swap the numbers. This process is repeated over and over again until the second number is equal to zero, at which point you will have your desired fraction.

One thing you will probably notice is that we aren't actually checking for zero in the Repeat loop. Because of the way that TI designed the TI-Basic language, each number has a limited amount of precision. As a result, any math calculations that involve extremely small or large numbers will produce rounding errors that don't return the right number. The easiest way to deal with this problem is by checking for a really small number (in this case, E‾9).

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/decimal-to-fraction


Deck of Cards

Routine Summary

Simulates a standard 52-card deck of cards.

Inputs

None

Outputs

∟DECK - the cards, in the format:

Value.Suit

Value is 1..13
Suit is 0, .25, .5, .75

Variables Used

L₁, ∟DECK

Calculator Compatibility

TI-83/84/+/SE

Download

deckofcards.zip

Creating the deck

seq(X/4,X,4,55→DECK

Shuffling the deck

rand(52→L₁
SortA(L₁,∟DECK

Accessing individual cards

∟DECK(I
Disp "VALUE:",sub("A23456789TJQK",int(Ans),1 
Disp "SUIT:",sub("SHCD",4fPart(Ans)+1, 1

The cards in the deck are stored in the form Value.Suit, where the value of the card (Ace through King) is encoded as a number 1 through 13; and the suit of the card is the fractional part, encoded as one of 0, 0.25, 0.5, or 0.75. In the above code (accessing individual cards), the convention is that 0=Spades, 0.25=Hearts, 0.5=Clubs, 0.75=Diamonds; however, you can pick any order as long as you're consistent.

Since any value from 1.00 to 13.75, that's 1/4 of an integer, is a valid card, we can generate the entire deck as 1/4 of the values {4,5, …, 54, 55}.

When shuffling the deck, we generate a random list in L₁, then use SortA( to sort ∟DECK by the values in L₁. Since the values in L₁ are random, this has the effect of sorting ∟DECK in a random order.

The main overhead of this shuffling method, however, is that generating a random list might take a long time (around a second or two). To avoid this, you can generate individual elements of L₁ randomly in a getKey loop, while waiting for a key, then use L₁ to shuffle later. Since shuffling isn't done often, by the time you need to shuffle, L₁ will most likely be fully randomized already.

Finally, accessing the cards is done using fPart( and int(. If a variable X is encoded in the same way that we encode cards, int(X) will return its value (1-13) and 4fPart(X)+1 will return its suit as a number 1-4.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/deck-of-cards


Draw Ellipse

Routine Summary

Draws an ellipse with specified coordinates.

Inputs

(A,B) - upper left corner, in pixels
(C,D) - lower right corner, in pixels

Outputs

Ellipse inscribed in the rectangle from (A,B) to (C,D)

Variables Used

A,B,C,D for input
∟X and ∟Y store a sin/cos look-up table
Plot1 to store the unit circle
Pic1 to preserve background

Calculator Compatibility

All

Author

Mikhail Lavrov (DarkerLine)

URL: http://mpl.unitedti.org/?p=13

Setup:

:cos(.1πcumSum(binomcdf(20,0→X
:sin(.1πcumSum(binomcdf(20,0→Y
:Plot1(xyLine,∟X,∟Y,(dot)
:PlotsOff

Main code:
:StorePic 1
(:ZoomSto)
:-(B+D)/abs(D-B→Xmin
:(A+C-124)/abs(C-A→Ymin
:2/abs(D-B→ΔX
:2/abs(C-A→ΔY
:PlotsOn 1
:RecallPic 1
:StorePic 1
:PlotsOff
(:ZoomRcl)
:RecallPic 1

To use the routine, add the setup code to the beginning of your program. Then, to draw an ellipse, initialize (A,B) and (C,D) to be opposite corners of an imagined rectangle, in pixel coordinates, and run the main code of the routine. The ellipse will be drawn inside this rectangle (much like the functionality of the circle tool in Paint). Unlike built-in pixel commands, this routine doesn't require the pixels to be on-screen: you can use negative coordinates, and coordinates past the 62nd row and 94th column - of course, if you do, then the off-screen part of the ellipse won't be drawn.

As for speed, the routine is far faster than the Circle( command. If you use Circle( with its undocumented fourth argument, that is a bit faster still - but doesn't allow you as much control over the shape of the ellipse as this routine does.

This routine draws an ellipse given its pixel coordinates in two overall steps:

  1. First, it calculates the window dimensions so that the unit circle (centered at the origin, with radius 1) will be stretched to the required pixel coordinates.
  2. Next, it draws the unit circle.

If the unit circle is stretched to fit in the rectangle from (A,B) to (C,D) then we know the following:

  • The vertical distance from A to C (in pixel rows) should be equivalent to the window distance 2 (from -1 to 1). This allows us to solve for ΔY.
  • The horizontal distance from B to D (in pixel columns) should also be equivalent to the window distance 2. This allows us to solve for ΔX.
  • The pixel most nearly corresponding to the midpoint between (A,B) and (C,D) should be equivalent to the point (0,0), the center of the circle. Given ΔX and ΔY, this allows us to solve for Xmin and Ymin.

The exact math isn't significant, but it gives rise to the formulas you see in the routine. Note that by using the abs( command, we ensure that the order of the two points (A,B) and (C,D) isn't important: you can switch A and C, or B and D, and still get the same circle.

The code for actually drawing the circle uses a look-up table for sine and cosine (which defines 20 points spaced around the circle). The table is calculated in the setup code, and then an xyLine plot is initialized, which will connect these 20 points when graphed. Now, to draw the unit circle, all that needs to be done is to enable the plot, using the PlotsOn command. This actually draws a 20-gon, rather than a circle, but the difference is imperceptible even on large circles.

The rest of the code is necessary to preserve the graph screen as the window changes and Plot1 is enabled and disabled (which causes the screen to be cleared), using StorePic and RecallPic. Optionally, you can also preserve the window dimensions, using ZoomSto and ZoomRcl — this is useful if your program mixes pixel and point commands.

The routine uses three fairly large variables to do its work: ∟X, ∟Y, and Pic1. ∟X and ∟Y need to be preserved from the setup code to whenever the routine is called; Pic1 is only used temporarily. It's a good idea to clean up all three by deleting them at the end of the program.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/draw-ellipse


Highlighting Text

Routine Summary

Highlights text, displaying it in white on a black background.

Inputs

Str1 - text to be displayed
A - row coordinate of the text
B - column coordinate of the text
W - pixel width of the text

Outputs

None

Variables Used

Str1, A, B, C, W

Calculator Compatibility

TI-83/84/+/SE

Download

highlighttext.zip

:Text(A,B,Str1
:For(A,A,A+6
:For(C,B-1,B+W
:Pxl-Change(A,C
:End:End

First, we display the string using Text( on the graph screen. This displayed it normally, using black on white. To switch it to white on black, we need to flip the pixels from white to black and black to white — this can be done using Pxl-Change(. We chose the pixel command over the point command for two reasons: first, it is slightly faster, and second, it uses the same coordinate system as Text( — pixels (if we used Pt-Change, we'd need to convert from pixels to points to be sure of drawing in the same location).

We loop A from above to below the text, and C from just before the text to immediately after it. Note that because of the way the For( loop works — it saves the lower and upper bound before doing the loop — we can reuse the variable A. But we can't reuse B in the same way in the second For( loop, because the loop is done multiple times — it would work correctly the first time, but then B would have changed for the second.

Since Text( uses variable-width font, we need the W variable to tell us how long the string is in pixels. For uppercase letters, the width is 4 pixels; for spaces, the width is 1 pixel, and for lowercase letters, the width varies from 2 to 6 pixels.

Because Pxl-Change( must not go off the screen, check to see that the string fits on the screen entirely (with a border of 1 pixel around it) before displaying it.

Error Conditions

  • ERR:DOMAIN is thrown if the string does not fit on the screen entirely.

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/highlighting-text


Key Code Retriever

Routine Summary

Retrieves the key code of any key pressed

Calculator Compatibility

TI-83/84/+/SE

:Repeat Ans
:getKey
:End
:Ans

This routine loops until a key is pressed. When a key is pressed, the key code for that specific key is displayed.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/key-code-retriever


List Frequency

Routine Summary

Returns a list of the frequency of values in another list.

Inputs

L₁ - the list you want to find the frequency of

Outputs

L₂ - the values of L₁ without repetition
L₃ - the frequencies of the values in the list L₂

Variables Used

L₁, L₂, L₃, I

Calculator Compatibility

TI-83/84/+/SE

Author

DarkerLine

URL: United TI

Download

listfrequency.zip

:{L₁(1→L₂
:{1→L₃
:For(I,2,dim(L₁
:If max(L₂=L₁(I:Then
:L₃+(L₂=L₁(I→L₂
:Else
:augment(L₂,{L₁(I→L₂
:augment(L₂,{1→L₃
:End:End

With our list of values stored in L₁, we store the first element of L₁ to L₂ to initialize it, and store a value of one to L₃ because that value has appeared once in the list (by default it is the first value and thus we know it appeared). We then begin looping in the second element to avoid an extra increment and then through all of the elements of L₁.

When determining the frequency of a value, we need to check to see if the particular element (in this case, L₁(I)) has already appeared in L₂. If it has, we increment (add one) to its respective frequency in L₂. However, if the value has never appeared in L₁, we add that value as a new element to the end of L₂ and also set its frequency to one. We repeat this until we have the frequency of all of the values in L₁ stored in L₂.

When you are done using L₁, L₂, and L₃, you should clean them up at the end of your program.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/deleted:list-frequency


List Frequency Fast

Routine Summary

Returns a list of the frequency of values in another list sorted.

Inputs

L₁ - the list you want to find the frequency of

Outputs

L₂ - the values of L₁ without repetition sorted
L₃ - the frequencies of the values in the list L₂ sorted

Variables Used

L₁, L₂, L₃, θ

Calculator Compatibility

TI-83/84/+/SE

Author

Galandros

URL: United TI

Download

listfrequency2

:DelVar L₂DelVar L₃SortA L₁
:For(θ,1,dim(L₁
:L₁(θ→L₂(1+dim(L₂
:sum(L₁=Ans→L₃(dim(L₂
:θ-1+Ans→θ
:End

In the first line we initialize L₁, L₂, and L₃. We sort L₁ so like values will be adjacent.

Then we start looping by storing the first value encountered to the next element of list L₂.
In the next line we find the frequency of the value already stored in L₂ and is stored to the correspondent element in L₃. θ is increased by the frequency found minus 1 to pass to next number, but then incremented by 1 in the For loop.
We loop we reach the end of L₁.

And that's it. The output is put on L₂ and L₃ already sorted. Notice how well Ans is used for speed and size optimization.

When you are done using L₁, L₂, and L₃, you should clean them up at the end of your program.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/list-frequency2


List Frequency Sorting

Routine Summary

Sorts a list based on frequency, then by value

Inputs

L₁ - A list to be sorted

Outputs

L₁ - The original list, sorted by frequency of elements

Variables Used

L₁, L₂, L₃

Calculator Compatibility

TI-83/84/+/SE/CSE/CE

Author

Trenly

SortD(L₁
DelVar L₂DelVar L₃
SetUpEditor
For(θ,1,dim(L₁
L₁(θ→L₂(1+dim(L₂
sum(L₁=Ans→L₃(dim(L₂
θ-1+Ans→θ
End
DelVar L₁
SetUpEditor
While dim(L₂
1+sum(not(cumSum(L₃=max(L₃→θ
L₃(θ)→N
For(E,1,N
L₂(θ→L₁(1+dim(L₁
End
For(E,θ+1,dim(L₂
L₂(E→L₂(E-1
L₃(E→L₃(E-1
End
dim(L₂)-1→dim(L₂
dim(L₃)-1→dim(L₃
End

This routine uses the List Frequency routine to find the frequency of each number. It then deletes, and reconstructs L₁ from the values in those lists by searching for the highest frequency, then adding it into L₁ the number of times it occurs. It then shifts the elements inside the frequency lists above the value down 1, overwriting the value which was just inserted into L₁. It then decreases the length of the frequency lists, and repeats until there are no more values to be added. This routine automatically cleans up, leaving L₂ and L₃ empty. If you wish to sort in ascending frequency, change the max( on line 12 to min(. If you wish to sort the values in ascending order instead of descending order, change the SortD( on line 1 to SortA(

Error Conditions

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/list-frequency-sorting


List to String

Routine Summary

Converts a list of numbers to a string.

Inputs

L₁ - The list you want to convert

Outputs

Str1 - The string that the text is stored to

Variables Used

L₁, A, Ans, Str1

Calculator Compatibility

TI-83/84/+/SE

Download

listtostring.zip

Note: If you have a TI-84+ CE with OS 5.2 or higher, you can ignore this entire routine and just use the toString( command.

:"?
:For(A,1,dim(L₁
:Ans+sub("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ ",1+L₁(A),1
:End
:sub(Ans,2,length(Ans)-1→Str1

With our list of values stored in L₁, we loop through each element of L₁ and store the character to our string that is at the matching position in our substring. In order to construct a string with all of the characters from L₁, we first need to create a dummy string. This is what the "? is used for.

Each time through the For( loop, we concatenate the string from before (which is still stored in the Ans variable) to the next character that is found in the list. Using Ans allows us to not have to use another string variable, since Ans can act like a string and it gets updated accordingly, and Ans is also faster than a string variable.

By the time we are done with the For( loop, all of our characters are put together in Ans. However, because we stored the dummy character as the first character at the beginning of the string, we now need to remove it, which we do by simply getting the substring from the second character to the end of the string. Finally, we store the string to a more permanent variable (in this case, Str1) for future use.

This routine allows for values from 0 to 36 in the list, since our string of characters is the ten digits and 26 uppercase letters, plus a space, and each list value must match up to one of the string positions. If you add more characters to the string, such as lowercase letters, however, you can increase the range of values in the list; if you need fewer characters you can simply remove them. This routine uses L₁, so you should clean it up at the end of your program.

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/list-to-string


Marquee

Routine Summary

Scrolls a string across one line, in marquee fashion, on the home screen.

Inputs

Str1 - the text to be scrolled
A,B - the Output( coordinates for the text
N - the number of characters to display at a time

Outputs

None

Variables Used

Str1, A, B, N, Ans

Calculator Compatibility

TI-83/84/+/SE

Author

Weregoose

URL: United TI

Download

marquee.zip

:Str1
:Repeat getKey
:Output(A,B,sub(Ans,1,N
:sub(Ans,2,length(Ans)-1)+sub(Ans,1,1
:If dim(rand(4
:End

By leaving Str1 by itself on one line, we store it to Ans, which will be easier to work with. Then, the Repeat getKey loop will display the marquee until a key — any key — is pressed.

Output(A,B,sub(Ans,1,N will display N characters of Str1 at A,B. Then, the next line will rotate Str1, so that the next time we're at this point in the loop, the string shifts one character.

Finally, If dim(rand(4 is a clever way of delaying the marquee, so it doesn't scroll too fast. rand(4 generates a list of 4 random numbers, which is a slightly time-consuming process. If dim( is just a way of wrapping this list so it doesn't change Ans. Since dim(rand(4 is always 4, the If statement will always be true, so we don't have to worry about the next line being skipped. By changing 4 to a lower or higher number, you can make the marquee go faster or slower, respectively.

Error Conditions

  • ERR:INVALID DIM is thrown if the length N is longer than the number of characters in Str1.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/marquee


Matrix to String

Routine Summary

Converts a matrix to a string.

Inputs

[A] - The matrix you want to convert

Outputs

Str1 - The string that the text is stored to

Variables Used

[A], L₁, A, B, Ans, Str1

Calculator Compatibility

TI-83/84/+/SE

Download

matrixtostring.zip

Note: If you have a TI-84+ CE with OS 5.2 or higher, you can ignore this entire routine and just use the toString( command.

:dim([A]→L₁:"?
:For(A,1,L₁(1
:For(B,1,L₁(2
:Ans+sub("ABCDEFGHIJKLMNOPQRSTUVWXYZ",[A](A,B),1
:End:End
:sub(Ans,2,length(Ans)-1→Str1

With our values stored in [A], we get the dimensions (row x column) of the matrix, which are stored in a list. We then loop through each row and column, and store the character at the respective element to our string that is at the matching position in our substring. In order to construct a string with all of the characters from [A], we first need to create a dummy string. This is what the "? is used for.

Each time through the For( loops, we concatenate the string from before (which is still stored in the Ans variable) to the next character that is found in the matrix. Using Ans allows us to not have to use another string variable, since Ans can act like a string and it gets updated accordingly, and Ans is also faster than a string variable.

By the time we are done with the For( loops, all of our characters are put together in Ans. However, because we stored the dummy character as the first character at the beginning of the string, we now need to remove it, which we do by simply getting the substring from the second character to the end of the string. Finally, we store the string to a more permanent variable (in this case, Str1) for future use.

This routine only allows for values from 1 to 26 in the matrix, since our string of characters is the uppercase alphabet, and each matrix value must match up to one of the string positions. If you add more characters to the string, however, you can increase the range of values in the matrix. This routine uses [A] and L₁, so you should clean them up at the end of your program.

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/matrix-to-string


Modular Arithmetic Solver

Routine Summary

Finds the remainder of a division between two numbers.

Inputs

A,M

Variables Used

A,M

Calculator Compatibility

TI-83/84/+/SE

:A-Mint(A/M

This program takes modular equations of the form X ≡ A (mod M) and solves them for the common residue, which is equal to the remainder after A has been divided by M. Among other things, it can be useful for finding the day of the week (with Sunday–Saturday matching up with 0–6) after M number of days has passed, or the time on a clock after a number of hours has passed.

For example, if we were on a Saturday (which is day 6, given that Sunday is day 0), and we wanted to figure out what it will be in 18 days, we would store 6+18→A, then 7→M as the appropriate number of days in a week, and finally we would calculate MfPart(A/M to get 3, which translates to a Wednesday.

This simpler version can be used if A is guaranteed to be positive:

:MfPart(A/M

It may fail due to rounding precision errors.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/modular-arithmetic-solver


Newtons Method

Routine Summary

Newton's Method - calculates the value of an equation

Inputs

Variant 1: Str1, A
Variant 2: Str1, Str2

Str1 and Str2 - The equation(s) are stored to the string variables.
Y1 and Y2 - The equation(s) are stored to the Y-variables from the string variables, then used for operations.
A - To store the seed value, and then the final value of the equation.

Outputs

A - The answer is stored to A

Variables Used

A, Y1, Y2

Calculator Compatibility

TI-83/84/+/SE/CSE/CE

Authors

Variant 1:Myles_Zadok
Variant 2: Xeda Elnara

Download

newton.zip

Newton's Method is a routine for math that calculates the value of the zeroes of an equation, or the intersection point of two equations.

Variant 1

:Input "Y1=",Str1
:Str1→Y1
:Input "SEED VALUE=",A
:For(I,1,10)
:Tangent(Y1,A)
:A-((Y1(A))/(nDeriv(Y1,X,A)))→A
:End
:Disp "APPROX. ROOT IS ",A

The program asks the user for an equation and the seed value. The seed value is the point from which the calculator approximates the zero of the function, so the seed value needs to be close to the desired zero. The calculator then begins the For( loop, which is run 10 times, each time getting a closer approximation of the zero. The loop draws a tangent line and runs the formula for the zero of the function. The answer, depending on the seed value, should be really close to the zero of the function.

In case you're wondering, you can remove the Tangent( command altogether and make the program run faster. However, you will have no clue as to whether you chose a good seed value or not. The Tangent( command slows down the program, but it lets you see if your chosen seed value will be accurate or not.

Variant 2

Variant 2
:Input "Y1 ",Str1
:Str1→Y1
:Input "Y2 ",Str2
:Str2→Y2
:0→I
:Repeat I=10 or K<20
:I+1→I
:0→K
:10rand→A
:Ans+1
:While K<20 and E-10<abs(A-Ans
:Ans→A
:K+1→K
:A-(Y1(A)-Y2(A))/nDeriv((Y1-Y2),X,A
:End
:End
:Disp Ans

The program asks for two equations and runs Repeat and While loops followed by the formula for the X-coordinate of the intersection of the two equations. The answer should be the value of the X-coordinate of the intersection.

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/newtons-method


Number Concatenation

Routine Summary

Concatenates two whole numbers together.

Inputs

M - the first number
N - the second number

Outputs

O - the concatenated number

Variables Used

M, N, O

Calculator Compatibility

TI-83/84/+/SE

Author

DarkerLine

URL: United TI

Download

numberconcatenation.zip

:N+M10^(1+int(log(N→O

With our two numbers stored in M and N respectively, we add the first number to the second number by raising it to the 10th power, with the exponent being how many digits are in the number. We then store this result to a new variable for later use.

We can figure out how many digits are in a number by using the 1+int(log( trick. This trick works with any positive whole numbers, and if you add abs( after log(, it will also work with negative numbers. Unfortunately, it does not work with decimals.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/number-concatenation


Number Factorization

Routine Summary

Returns the factors of a number.

Inputs

X - the number you want to factor

Outputs

L₁ - the factors of the number

Variables Used

X, L₁, Ans

Calculator Compatibility

TI-83/84/+/SE

Author

Weregoose

URL: United TI

Download

numberfactors.zip

:{1→L₁
:Repeat Ans=1
:2:While fPart(X/Ans
:Ans+1
:End
:Ans→L₁(1+dim(L₁
:X/Ans→X
:End

Number factorization breaks a number up into its factors - smaller numbers that that are multiplied together to create the number. For example, the number 100 can be broken up into the factors 2*2*5*5. It can also be represented as 10*10, or 5*20, but for the sake of completeness, this routine finds prime factors — which can't be broken down themselves (2*2*5*5 is such a factorization, since there's no way to factor 2 or 5, but 5*20 isn't, since 20 can still be factored).

In order to start collecting the factors of the number, we create a list with the initial factor of 1 (because 1 is a factor for every number). We then begin looping through numbers, starting with 2, to find the next factor. The way we determine if we have a factor is by dividing the original number by the respective number we are at, and checking if there is a remainder.

If there is a remainder, we know that the number is not a factor, and we then increment it and continue looping. If there is no remainder, however, we have found a factor, and thus the loop will end. We then add that factor as the next element in our factors list, and divide the original number by that factor and set the result as the new number. This gets repeated over and over again until we have our list of factors.

The factors list should be generated pretty quickly, but it all depends on the original value that you chose for X; a smaller value will be faster, and likewise a larger value will be slower. In addition, if you try starting with a negative number or a number with a decimal part, then the program will not work correctly.

When you are done using L₁, you should clean it up at the end of your program.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/factorization


Number Subset

Routine Summary

Returns a subset of a number.

Inputs

A - the number to get the subset from
B - the starting position of the subset
C - the length of the subset

Outputs

Ans - the subset of the number

Variables Used

A, B, C, Ans

Calculator Compatibility

TI-83/84/+/SE

Author

Weregoose

URL: United TI

Download

numbersubset.zip

:10^(2-B+int(log(A
:int((A-int(A/Ans)Ans)/Ans10^(C

With our number stored in A, and the staring position and length of the subset stored in B and C respectively, we get the subset of the number by first subtracting the number divided by 10 to the power of 2-B+int(log(A (which is used to get how many digits are in the number), and then dividing that result by multiplying 10 to the power of 2-B+int(log(A and 10 to the power of C (which is the length of the subset).

A simple example should help you understand this routine. Say you input the number 123, with a starting position of 2 and a length of 2, it will return a result of 23. You can also use negative and decimal numbers with the routine, and it will still work correctly: a number of 13579.02468 with a starting position of 4 and length 4 will return 7902.

This routine is comparable to the sub( command that works with strings.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/number-subset


Number to String

Routine Summary

Converts a real number to a string.

Inputs

N - the number you want to convert

Outputs

Str1 - the number N in string form

Variables Used

L₁, L₂, Y₁, Str1, N

Calculator Compatibility

TI-83/84/+/SE

Download

numbertostring.zip

Note: If you have a TI-84+ CE with OS 5.2 or higher, you can ignore this entire routine and just use the toString( command.

:{0,1→L₁
:NAns→L₂
:LinReg(ax+b) Y₁
:Equ►String(Y₁,Str1
:sub(Str1,1,length(Str1)-3→Str1

This code works because it creates two points with a known best fit line: the best fit line through (0,0) and (1,N) is y=Nx+0. LinReg(ax+b) calculates this best fit line, and stores its equation to Y₁.

Then, we use Equ►String( to store this equation to Str1, which now contains "NX+0" with N replaced by the numerical value of N. After that, the sub( command get rids of the "X+0" at the end, leaving only the string representation of N.

This routine uses L₁, L₂, and Y₁, so you should clean up those variables at the end of your program. If you're working with the graph screen in function mode, storing to Y₁ can be a problem since it will draw an unwanted line through your graphics. Use r₁ instead but make sure the calculator isn't in polar mode.

Note: This only works for real numbers. With complex numbers, such as imaginary numbers, you can use this code at the end of the first to get the same effect with i in it. This routine will also only work for N<10^50. To convert larger N, see the alternate below.

:Str1+"i→Str1

Alternate Routine

The following routine will perform the same function for converting N to a string as shown above. This routine, however, allows N to be as large as the TI-84+ overflow limit (10^100) by utilizing Med-Med regression.

:{0,.5,1→L₁
:NAns→L₂
:Med-Med Y₁
:Equ►String(Y₁,Str1
:sub(Str1,1,length(Str1)-3→Str1

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/number-to-string


Pad a String

Routine Summary

Pad a string with spaces on the left and right.

Inputs

Ans - The string you want to pad
N - How many spaces you want

Outputs

Str1 - The padded string

Variables Used

X, N, Ans, Str1

Calculator Compatibility

TI-83/84/+/SE

Download

padstring.zip

:For(X,1,N
:" "+Ans+" 
:End
:Ans→Str1

With our string stored in Ans, we concatenate (add) a space to the beginning and end of the string. At the same time, the new string is stored to Ans, which is what we use next time through the For( loop. The loop gets repeated over and over again until we have added however many spaces we wanted. If you only want spaces on one side of the string, edit the second line accordingly.

Using Ans allows us to not have to use another string variable, since Ans can act like a string and it gets updated accordingly, and Ans is also faster than a string variable.

We store the string to a more permanent variable (in this case, Str1) for future use. When you are done using Str1, you should clean it up at the end of your program.

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/pad-a-string


Repeat a String

Routine Summary

Repeats a string however many times you want.

Inputs

Ans - The string you want to repeat
2N - How many times you want the string repeated

Outputs

Str1 - The repeated string

Variables Used

X, N, Ans, Str1

Calculator Compatibility

TI-83/84/+/SE

Download

repeatstring.zip

:For(X,1,N
:Ans+Ans→Str1
:End

With our string stored in Ans, we concatenate (add) another copy to the end of the string, and store the new string to Str1. At the same time, the new string is also stored to Ans, which is what we use next time through the loop. The loop gets repeated over and over again until we have added however many copies we wanted. If you want to add more than one copy of the string each time through the loop, edit the second line accordingly.

Using Ans allows us to not have to use another string variable, since Ans can act like a string and it gets updated accordingly, and Ans is also faster than a string variable. In addition, by storing the string to Str1 inside the loop, we avoid having to add an additional storage to the routine.

We store the string to a more permanent variable (in this case, Str1) for future use. When you are done using Str1, you should clean it up at the end of your program.

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/deleted:repeat-a-string


Reverse a String

Routine Summary

Reverses the characters in a string.

Inputs

Str1 - The string you want to reverse

Outputs

Str1 - The reversed string

Variables Used

Str1, I, Ans

Calculator Compatibility

TI-83/84/+/SE

Download

reversestring.zip

:Str1
:For(I,1,length(Ans)-1
:sub(Ans,2I,1)+Ans
:End
:sub(Ans,1,I→Str1

With our string stored in Str1 and Ans, we loop through each character, starting from the beginning to the end, and add it to the beginning of the string, building the reversed string up at the beginning as we go:

12345    (original string - the first character is the first reversed character)
212345   (add then second character before the first, reversing the string)
3212345  (continue adding characters in reverse)
543212345 (this is what the end result looks like)

Since adding to the beginning of the string alters the indices, we must take that into account — this is where the 2I in the formula comes from. It adds the 2nd character the first time, the 4th character (which was originally the 3rd) next, the 6th character (originally the 4th) after that, and so on.

Using Ans allows us to not have to use another string variable, since Ans can act like a string and it gets updated accordingly, and Ans is also faster than a string variable.

By the time we are done with the For( loop, all of our characters are put together in Ans in reverse order, before the original string. To finish, we take the first (reversed) half as a substring and store it back in Str1 for further use. We can use I for this purpose because it looped from 1 to length(Str1)-1, so its value will be length(Str1) when exiting.

If you want to preserve the original string, store it to a different string variable in the first line of the code.

When you are done using Str1, you should clean it up at the end of your program.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/reverse-a-string


Run-Length Encoding (RLE) Compression

Routine Summary

Compresses a list of numbers using RLE compression.

Inputs

L₁ - The list of numbers you want to compress

Outputs

L₁ - The list of compressed numbers

Variables Used

L₁, I, J

Calculator Compatibility

TI-83/84/+/SE

Download

rlecompress.zip

:1→J
:For(I,2,dim(L₁
:If L₁(I)=L₁(J:Then
:.002+L₁(J→L₁(J
:Else
:If L₁(I)=int(L₁(J:Then
:.001+L₁(J→L₁(J
:Else
:J+1→J
:L₁(I→L₁(J
:End:End:End
:J→dim(L₁

Run-length encoding (RLE) is a very easy compression algorithm that you can use for compressing a list of numbers. The way it works is that you remove all of the consecutive repeated numbers from the list, and modify the first instance of the numbers with how many repeated numbers there were.

For example, say you have a list of numbers 1,2,2,3,3,3,4. You start with the 1, and since there is only one 1, it wouldn't be modified. There are two 2's, however, so you would remove the second two, and add a decimal part (using fPart() of how many 2's there were (in this case, just two, which we represent as .002). You would do this for the rest of the list, and the final list would be 1,2.002,3.003,4.

To save memory (which is of course the reason we're compressing) we will store the result to L₁, the same list the uncompressed data is in. Throughout the loop, J is the index of the last element of the compressed part of the list, and I is the index in the uncompressed part. We don't have to worry about the indices colliding, since I is always bigger than J.

We loop over the list with I, and check if the current element has the same value as the last element of the compressed list. If it is, then it's the beginning of a run, so we add .002 to that last element.

If it isn't there's another possibility — the last element could represent an existing run of the same element. We check for this with the code If L₁(I)=int(L₁(J)). If this turns out to be the case, we add .001 to increase the length of the run. Otherwise, the element really is different, and we increase J and add a new element.

At the end, we store J to the size of L₁. This gets rid of all the unnecessary data, leaving us only with the compressed portion of the list.

Note that we never store anything to L₁ itself, only to its elements. This is a useful technique to avoid using too much memory while the program is running: if we stored to L₁, a copy of the list would be stored to Ans, which could easily give a ERR:MEMORY if the list is too large. As the program is now, the only additional memory used is contained in three real variables (I, J, and Ans).

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/rle-compress


Run-Length Encoding (RLE) Decompression

Routine Summary

Decompresses a run length-encoded list.

Inputs

L₁ - The compressed list

Outputs

L₁ - The decompressed list

Variables Used

L₁, I, J

Calculator Compatibility

TI-83/84/+/SE

Download

rledecompress.zip

:dim(L₁→J
:sum(E3fPart(L₁)+not(fPart(L₁→dim(L₁
:For(I,Ans,1,-1
:int(L₁(J→L₁(I
:If .001<fPart(L₁(J:Then
:L₁(J)-.001→L₁(J
:Else
:J-1→J
:End:End

Run-length encoding (RLE) is a very easy compression algorithm that you can use for compressing a list of numbers. The way it works is that you remove all of the consecutive repeated numbers from the list, and modify the first instance of the numbers with how many repeated numbers there were.

For example, say you have a list of numbers 1,2,2,3,3,3,4. You start with the 1, and since there is only one 1, it wouldn't be modified. There are two 2's, however, so you would remove the second two, and add a decimal part (using fPart() of how many 2's there were (in this case, just two, which we represent as .002). You would do this for the rest of the list, and the final list would be 1,2.002,3.003,4.

This routine could loosely be described as the RLE compression routine, but backwards. We start by calculating the length of the decompressed list. This is the sum of the length of the runs — E3fPart(L₁) — plus the number of elements with no runs — not(fPart(L₁)). Here E represents the scientific E.

Then, the decompression begins. The routine keeps the following loop invariants (things that stay true after each iteration of the loop):

  • Every element after the Ith element is the correct decompressed element in that spot.
  • The portion of the list up to and including the Jth element is the compressed version of the list elements that will be 1 through I.

We "unpack" one element from the end of the compressed portion: int(L₁(J→L₁(I. Then we test if this compressed portion is a run that still contains more elements. If it is, we subtract .001, reducing the number of elements in the run by 1. If it's not, we decrease J by 1 to move on to the previous compressed element. As you can see, the conditions listed above are still true.

Once the loop ends, the first condition of the ones above ensures that all elements have been correctly decompressed.

Note that we never store anything to L₁ itself, only to its elements. This is done to avoid using any more memory than necessary: if we stored to L₁, a copy of the list would get temporarily stored to Ans, and we would be using twice the memory we need. This way, the routine will work even for large lists. As a bonus, the only time we change the size of the list is the very beginning. So if the decompressed list wouldn't fit in memory, the routine crashes immediately and keeps the list intact.

Error Conditions

  • ERR:MEMORY is thrown if there is not enough space to store the decompressed list.
  • ERR:INVALID DIM is thrown if the decompressed list would be longer than 999 elements.

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/rle-decompress


Scramble a String
scramble_routine.gif

Routine Summary

Scrambles a string

Inputs

Str1 - The string you want to scramble

Outputs

Ans - The scrambled string

Variables Used

Ans, Str1, L, N, L₁, L₂

Calculator Compatibility

TI-83/84/+/SE

Authors

seb83, Edward H, Timothy Foster

Download

scramble_prgm.zip

This routine takes a string stored in Str1 and scramble it. The results is contained in Ans. For example, "ABCDE12345" could be scrambled to "B34AC1DE25".

:rand(length(Str1→L₁
:cumSum(1 or Ans→L₂
:SortA(L₁,L₂
:sub(Str1,L₂(1),1
:For(N,2,length(Str1
:Ans+sub(Str1,L₂(N),1
:End

With your string stored in Str1, it creates L₁={1,2,3,4,…,length(Str1)}. After that, L₂ is created randomly to sort L₁ in function of L₂. L₁ now could look like {5,3,4,1,2} if you entered a 5 character string. In the For( loop, it takes one by one the character of Str1 accordingly to L₁ to store it to Ans. Your scrambled string is now in Ans.

For the TI-84+ and higher with a MathPrint or color OS, use this code instead:

:randIntNoRep(1,length(Str1→L₁
:sub(Str1,Ans(1),1
:For(N,2,length(Str1
:Ans+sub(Str1,L₁(N),1
:End

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/scramble-a-string


Shading Circles

Routine Summary

Shades in a circle.

Inputs

R - the radius of the circle
A - the X coordinate of the circle's center
B - the Y coordinate of the circle's center

Outputs

None

Variables Used

N, R, A, B

Calculator Compatibility

TI-83/84/+/SE

Author

Jutt

URL: United TI

Download

shadecircles.zip

:For(N,0,R,ΔX
:√(R²-N²
:Line(A+N,B-Ans,A+N,B+Ans
:Line(A-N,B-Ans,A-N,B+Ans
:End

Although it is possible to shade in a circle using the Shade( command (i.e., Shade(-√(R²-(X-A)²)+B,√(R²-(X-A)²)+B)), that is actually quite impractical in a real program because of its slow speed. Fortunately, you can improve upon that by using your own routine.

When graphing a circle, there are a few main things you need to know: the radius and the (X,Y) coordinates of the center. In our routine, the R variable is the radius, the A variable is the circle's X coordinate and the B variable is the circle's Y coordinate.

Rather than displaying the circle as one big circle, we are going to display it line by line using a For( loop, starting from the center. The √(R²-N² formula is based on the circle formula R2=(X–H)2+(Y–K)2, with the formula rearranged to get the respective part of the circle.

The circle should display pretty quickly, but it all depends on the values that you chose for the variables; smaller values will be faster, and likewise larger values will be slower. In addition, the circle may not display correctly if you don't have the right graph settings, so you should set your calculator to a friendly graphing window.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/shading-circles


String to List

Routine Summary

Converts a string to a list of numbers.

Inputs

Str1 - The string you want to convert

Outputs

L₁ - The list that the numbers are stored to

Variables Used

L₁, A, Str1

Calculator Compatibility

TI-83/84/+/SE

Download

stringtolist.zip

:1+seq(inString("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ ",sub(Str1,A,1)),A,1,length(Str1→L₁

With our characters stored in Str1, we loop through each character and store its position in our reference string (the uppercase alphabet) to the respective element of L₁.

This routine only allows for values from 1 to 26 in the list, since our string of characters is the uppercase alphabet, and each list value must match up to one of the string positions. If you add more characters to the string, however, you can increase the range of values in the list. This routine uses Str1, so you should clean it up at the end of your program.

Advanced Routine

Since a list element can store up to 14 digits, you can use int(, fPart(, and exponents to compress an additional 7 letters per element (2 digits for each letter), thus increasing your total number of characters to 6993.

" ABCDEFGHIJKLMNOPQRSTUVWXYZ->Str0
DelVar L1
For(A,0,dim(L1
0
For(B,1,min(7,length(Str1)-7A
Ans+.1^(2B)inString(Str0,sub(Str1,B+7A,1
End
Ans->L1(A+1
End
"

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/string-to-list


Strip a String

Routine Summary

Strip a string of its spaces on the left and right.

Inputs

Ans - The string you want to strip

Outputs

Str1 - The stripped string

Variables Used

Ans, Str1

Calculator Compatibility

TI-83/84/+/SE

Download

stripstring.zip

:While " "=sub(Ans,1,1) or " "=sub(Ans,length(Ans),1
:sub(Ans,1+(" "=sub(Ans,1,1)),length(Ans)-1→Str1
:End

With our string stored in Ans, we check to see if there is a space at the beginning or end of the string. If there is a space, then we remove it by storing the substring of the string that doesn't include the first character (for a space at the beginning) or the last character (for a space at the ending), and store the new string to Str1.

At the same time, the new string is stored to Ans, which is what we use next time through the While loop. The loop gets repeated over and over again until we have stripped all of the spaces from the beginning and end of the string. If you only want to remove spaces on one side of the string, edit the first and second lines accordingly.

Using Ans allows us to not have to use another string variable, since Ans can act like a string and it gets updated accordingly, and Ans is also faster than a string variable. In addition, by storing the string to Str1 inside the loop, we avoid having to add an additional storage to the routine.

We store the string to a more permanent variable (in this case, Str1) for future use. When you are done using Str1, you should clean it up at the end of your program.

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/strip-a-string


Sum of Digits

Routine Summary

Returns the sum of digits of a number.

Inputs

X - the number you want

Outputs

Ans - the sum of X's digits

Variables Used

X, Ans

Calculator Compatibility

TI-83/84/+/SE

Author

DarkerLine

URL: United TI

:sum(int(10fPart(Xseq(10^(-I-1),I,0,log(X

With our number stored in X, we loop through each of the digits of the number starting from the right using the seq( command. We get the respective digit by raising the number to the respective power of 10 and then multiplying the result by 10. The digits are returned separately in a list, and then we take the sum of them using the sum( command.

For example, if the number is 1234, we get a list of {1,2,3,4}, which then returns a sum of 10. You should note, though, that this routine only works with positive and negative whole numbers, and will return incorrect results if you try to use a decimal number. You could fix this problem by using the code below instead:

:abs(E13(X/10^(int(log(abs(X+not(X→X

Here, we obtain the appropriate power of ten by which to divide the number so as to leave only one digit to the left of the decimal point. Because a real variable may contain only 14 digits, the answer is multiplied by 10^13 to guarantee the removal of any fractional part. From taking the absolute value of this new result, our number can be safely entered into the routine above.

Note: It should be understood that this routine is only capable of adding the first 14 digits of a number. An input of π, for instance, would return 69 even though the sum of all digits of π is infinite.

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/sum-of-digits


Sum of Matrix Elements

Routine Summary

Returns the sum of the elements of a matrix.

Inputs

[A] - the matrix whose elements you want to sum

Outputs

Ans - the sum of the matrix elements

Variables Used

[A], L₁, Ans

Calculator Compatibility

TI-83/84/+/SE

Author

zada

URL: United TI

Download

sumofmatrix.zip

:dim([A]
:Matr►list(cumSum([A])T,Ans(1),L₁
:sum(L₁

The cumSum( command gets the cumulative sum of each column in the matrix, adding the value of the previous element to the next element, and repeating this for each consecutive element in the column. When the cumSum( command is finished, the last element in each column will contain the sum of that column. Taking the T (transpose) of the resulting matrix switches columns and rows.

Then, using the Matr►list( command, the last column of this result is stored to L₁. This column was originally the last row of cumSum('s output, so it contains all the column sums. Finally, by calculating the sum of that list, we get the total of the matrix elements. L₁ is no longer necessary, and can be deleted.

If you want to use the sum for future use, you can store it to a more permanent variable, such as A or X. When you are done using [A], you should clean it up at the end of your program.

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/sum-of-matrix


Typewriter Routine

Routine Summary

Makes text appear letter by letter

Inputs

Str1 - Text to be displayed.
A,B - Row and colum to display text.

Variables Used

A, B, T, Str1

Calculator Compatibility

All TI calculators

:For(T,1,length(Str1
:Text(A,B,sub(Str1,1,T
:rand(5
:End

We use a For( loop over the length of the string to go through the string letter by letter. In order to make the spacing come out right, instead of figuring out the right coordinate to display each character at, we display the first T characters of the string starting from the beginning. The rand(5) provides a split-second delay to achieve the typewriter effect.

For multiple lines with the typewriter effect, you can combine this routine with the one to wordwrap text.

Error Conditions

  • ERR:DOMAIN is thrown if the string doesn't fit entirely on the screen.

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/typewriter


Wordwrapping Text on the Graphscreen

Routine Summary

Displays text on several lines on the graph screen.

Inputs

Str1 - text to display
A - starting row
B - starting column

Outputs

None

Variables Used

Str1, A, B, C, Ans

Calculator Compatibility

TI-83/84/+/SE

Download

wordwrap.zip

:1→C
:For(A,A,57,6
:inString(Str1,"/",Ans
:Text(A,B,sub(Str1,C,Ans-C
:If Ans=length(Str1:57→A
:Ans+1→C
:End

This routine displays a string on the graph screen, with line breaks after every slash "/" character. The routine requires there to be a slash at the end of the string (so, a sample string would be "THIS TEXT IS TOO LONG TO/DISPLAY ON ONE LINE/").

The row and column (A and B) inputs determine the upper and left boundaries of the text. You determine the right boundary by where you put the slash characters. The lower boundary is 57, hardcoded into the routine (this is the lowest that text can be displayed), but you could change this if you wanted a different boundary.

The variable C is used for an index inside Str1, that tells us which character we're currently on. We're starting at the beginning of the string, so we store 1 to C.

The For( loop will increment A by 6 each time we display a line (small font characters are 6 pixels tall). We start at the current value of A, and end at 57 because beyond that, Text( will throw a domain error.

Now, we search for the next slash "/" character using the inString( command. Then, using Text(, we display the line between C and the "/", not including the slash itself. Ans+1→C will move the C index to the next character after the slash.

The line If Ans=length(Str1:57→A will end the loop early as soon as we reach the end of the string. This command can modify Ans, which would be bad, but it only does so when we're ready to exit anyway — at that point, we won't be needing Ans anymore.

Error Conditions

  • ERR:INVALID DIM is thrown if Str1 is improperly formatted (check for the backslash at the end).
  • ERR:DOMAIN is thrown if text goes off the screen. This shouldn't happen unless B is very close to the right edge, if A or B are negative, or if the calculator is in Horiz mode (in which case, replace 57 with 25).

Related Routines

For the most up-to-date version of this routine, see http://tibasicdev.wikidot.com/wordwrap-text


Binary, Hexadecimal and Octal number system

Binary, hexadecimal, and octal refer to different number systems. The one that we typically use is called decimal. These number systems refer to the number of symbols used to represent numbers. In the decimal system, we use ten different symbols: 0, 1, 2, 3, 4, 5, 6, 7, 8, and 9. With these ten symbols, we can represent any quantity. For example, if we see a 2, then we know that there is two of something. For example, this sentence has 2 periods on the end..

When we run out of symbols, we go to the next digit placement. To represent one higher than 9, we use 10 meaning one unit of ten and zero units of one. This may seem elementary, but it is crucial to understand our default number system if you want to understand other number systems.

For example, when we consider a binary system which only uses two symbols, 0 and 1, when we run out of symbols, we need to go to the next digit placement. So, we would count in binary 0, 1, 10, 11, 100, 101, and so on.

This article will discuss the binary, hexadecimal, and octal number systems in more detail and explain their uses.

How a Number System Works

Number systems are used to describe the quantity of something or represent certain information. Because of this, I can say that the word "calculator" contains ten letters. Our number system, the decimal system, uses ten symbols. Therefore, decimal is said to be Base Ten. By describing systems with bases, we can gain an understanding of how that particular system works.

When we count in Base Ten, we count starting with zero and going up to nine in order.

0, 1, 2, 3, 4, 5, 6, 7, 8, 9, …

Once we reach the last symbol, we create a new placement in front of the first and count that up.

8, 9, 10, 11, 12, … , 19, 20, …


This continues when we run out of symbols for that placement. So, after 99, we go to 100.

The placement of a symbol indicates how much it is worth. Each additional placement is an additional power of 10. Consider the number of 2853. We know this number is quite large, for example, if it pertains to the number of apples in a basket. That's a lot of apples. How do we know it is large? We look at the number of digits.

Each additional placement is an additional power of 10, as stated above. Consider this chart.
103 102 101 100
digit digit digit digit
*1000 *100 *10 *1

Each additional digit represents a higher and higher quantity. This is applicable for Base 10 as well as to other bases. Knowing this will help you understand the other bases better.

Binary

Binary is another way of saying Base Two. So, in a binary number system, there are only two symbols used to represent numbers: 0 and 1. When we count up from zero in binary, we run out of symbols much more frequently.

0, 1, …

From here, there are no more symbols. We do not go to 2 because in binary, a 2 doesn't exist. Instead, we use 10. In a binary system, 10 is equal to 2 in decimal.

We can count further.

Binary 0 1 10 11 100 101 110 111 1000 1001 1010
Decimal 0 1 2 3 4 5 6 7 8 9 10
Just like in decimal, we know that the more digits there are, the larger the number. However, in binary, we use powers of two. In the binary number 1001101, we can create a chart to find out what this really means.
26 25 24 23 22 21 20
1 0 0 1 1 0 1
64+0+0+8+4+0+1
77

Since this is base two, however, the numbers don't get quite as large as it does in decimal. Even still, a binary number with 10 digits would be larger than 1000 in decimal.


The binary system is useful in computer science and electrical engineering. Transistors operate from the binary system, and transistors are found in practically all electronic devices. A 0 means no current, and a 1 means to allow current. With various transistors turning on and off, signals and electricity is sent to do various things such as making a call or putting these letters on the screen.

Computers and electronics work with bytes or eight digit binary numbers. Each byte has encoded information that a computer is able to understand. Many bytes are stringed together to form digital data that can be stored for use later.

Octal

Octal is another number system with less symbols to use than our conventional number system. Octal is fancy for Base Eight meaning eight symbols are used to represent all the quantities. They are 0, 1, 2, 3, 4, 5, 6, and 7. When we count up one from the 7, we need a new placement to represent what we call 8 since an 8 doesn't exist in Octal. So, after 7 is 10.

Octal 0 1 2 3 4 5 6 7 10 11 12… 17 20… 30… 77 100
Decimal 0 1 2 3 4 5 6 7 8 9 10… 15 16… 24… 63 64

Just like how we used powers of ten in decimal and powers of two in binary, to determine the value of a number we will use powers of 8 since this is Base Eight. Consider the number 3623 in base eight.

83 82 81 80
3 6 2 3
1536+384+16+3
1939

Each additional placement to the left has more value than it did in binary. The third digit from the right in binary only represented 23-1, which is 4. In octal, that is 83-1 which is 64.

Hexadecimal

The hexadecimal system is Base Sixteen. As its base implies, this number system uses sixteen symbols to represent numbers. Unlike binary and octal, hexadecimal has six additional symbols that it uses beyond the conventional ones found in decimal. But what comes after 9? 10 is not a single digit but two… Fortunately, the convention is that once additional symbols are needed beyond the normal ten, letters are to be used. So, in hexadecimal, the total list of symbols to use is 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, and F. In a digital display, the numbers B and D are lowercase.

When counting in hexadecimal, you count 0, 1, 2, and so on. However, when you reach 9, you go directly to A. Then, you count B, C, D, E, and F. But what is next? We are out of symbols! When we run out of symbols, we create a new digit placement and move on. So after F is 10. You count further until you reach 19. After 19, the next number is 1A. This goes on forever.

Hexadecimal 9 A B C D E F 10 11… 19 1A 1B 1C… 9F A0
Decimal 9 10 11 12 13 14 15 16 17 25 26 27 28 159 160

Digits are explained as powers of 16. Consider the hexadecimal number 2DB7.

163 162 161 160
2 D B 7
8192+3328+176+7
11703

As you can see, placements in hexadecimal are worth a whole lot more than in any of the other three number systems.

Conversion

It is important to know that 364 in octal is not equal to the normal 364. This is just like how a 10 in binary is certainly not 10 in decimal. 10 in binary (this will be written as 102 from now on) is equal to 2. 108 is equal to 8. How on earth do we know this? What is 20C.38F16, and how do we find out?

Here is why it is important to understand how the number systems work. By using our powers of the base number, it becomes possible to turn any number to decimal and from decimal to any number.

Base to Decimal

So, we know that 3648 is not equal to the decimal 364. Then what is it? There is a simple method in converting from any base to the decimal base ten. If you remember how we dissected the numbers above, we used powers, such as 24, and ended up with a number we understand. This is exactly what we do to convert from a base to decimal. We find out the true value of each digit according to their placement and add them together.

In a formula, this algorithm looks like:

(1)
\begin{equation} V_{10} = v_pB^p+v_{p-1}B^{p-1}+...+v_1B+v_0 \end{equation}

Where V10 is the decimal value, v is the digit in a placement, p is the placement from the right of the number assuming the rightmost placement is 0, and B is the starting base. Do not be daunted by the formula! We are going to go through this one step at a time.

So, let us say we had the simple hexadecimal number 2B. We want to know what this number is in decimal so that we can understand it better. How do we do this?

Let us use the formula above. Define every variable first. We want to find V10, so that is unknown. The number 2B16 has two positions since it has two digits. p therefore is one less than that1, so p is 1. The number is in base 16, so B is 16. Finally, we want to know what v is, but there are multiple v's. You have v1 and v0. This refers to the value of the digit in the subscripted position. v1 refers to the digit in position one (the second digit from the right). So, v1 is 2. v0 is the first digit which is B. In the case of the conversion, you must convert all the letters to what they are in decimal. B is 11 in decimal, so v0 is 11.

Now, plug all this into the formula:

(2)
\begin{align} V_{10} = 2(16^1)+11(16^0) \\ V_{10} = 2(16)+11(1) \\ V_{10} = 32+11 \\ V_{10} = 43 \\ \end{align}

Therefore, 2B16 is equal to 43.

Now, let me explain how this works. Remember how digit placement affects the actual value? For example, in the decimal number 123, the "1" represents 100 which is 1*102. The "2" is 20, or 2*101. Likewise, in the number 2B16, the "2" is 2*161, and the B is 11*160.

We can determine the value of numbers in this way. For the number 3648, we will make a chart that exposes the decimal value of each individual digit. Then, we can add them up so that we have the whole. The number has three digits, so starting from the right, we have position 0, position 1, and position 2. Since this is base eight, we will use powers of 8.

82 81 80
3 6 4

Now, 82 is 64. 81 is 8. 80 is 1. Now what?

Remember what we did with the decimal number 123? We took the value of the digit times the respective power. So, considering this further…

3*64 6*8 4*1
192 48 4

Now, we add the values together to get 244. Therefore, 3648 is equal to 24410.

In the same way that for 123, we say there is one group of 100, two groups of 10, and three groups of 1, for octal and the number 364, there are three groups of 64, six groups of 8, and four groups of 1.

Decimal to Base

Just like how we can convert from any base to decimal, it is possible to convert decimal to any base. Let us say that we want to represent the number 23610 in binary, octal, and hexadecimal. What we need to do is pretty much reverse whatever we did above. There isn't really a good formula for this, but there is an algorithm that you can follow which will help accomplish what we want.

(3)
\begin{align} (1) \hspace{6pt} Let \hspace{4pt} P = \operatorname{int}(\sqrt[B]{V}) \\ (2) \hspace{6pt} Let \hspace{4pt} v = \operatorname{int}(V \div B^P) \\ (v \hspace{4pt} is \hspace{4pt} the \hspace{4pt} next \hspace{4pt} digit \hspace{4pt} to \hspace{4pt} the \hspace{4pt} right) \\ (3) \hspace{6pt} Make \hspace{4pt} V = V-vB^p \\ (4) \hspace{6pt} Repeat \hspace{4pt} steps \hspace{4pt} 1 \hspace{4pt} through \hspace{4pt} 3 \hspace{4pt} until \hspace{4pt} p=0 \\ \end{align}

This algorithm may look confusing at first, but let us go through an example to see how it can be used. We want to represent 236 in binary, octal, and hexadecimal. So, let's try getting it to binary first.

The first step is to make p equal to $\operatorname{int}(\sqrt[B]{V})$. B is the base we want to convert to which is 2. The V is the number we want to convert, 236. Essentially, we are taking the square root of 236 and disregarding the decimal part. Doing this makes p become 7.

Step two says to let v equal our number V divided by Bp. Bp is 27, or 128, and the integer part of 236 divided by 128 is 1. Therefore, our first digit on the left is 1. Now, we actually change V to become V minus the digit times the Bp. So, V will now be 236-128, or 108.

We simply repeat the process until the p becomes a zero. When p becomes zero, we complete the steps a last time and then end.

So, since V is now 108, p becomes 6. 108 divided by 26 is 1. The 1 goes to the right of the 1, so now we have 11. V becomes 44 since 108-64 is 44.

How?

Now you might be asking yourself how to read these numbers. Well, that’s not so difficult. First, I’ll give a general mathematical explanation which can be fit into one formula:

(4)
\begin{equation} V=vB^P \end{equation}

In human language: the value of the cipher in the number is equal to the value of the cipher on its own multiplied by the base of the number system to the power of the position of the cipher from left to right in the number, starting at 0. Read that a few times and try to understand it.

Thus, the value of a digit in binary doubles every time we move to the left. (see table below)

From this follows that every hexadecimal cipher can be split up into 4 binary digits. In computer language: a nibble. Now take a look at the following table:

Binary Numbers
8 4 2 1 Hexadecimal Value Decimal Value
0 0 0 0 0 0
0 0 0 1 1 1
0 0 1 0 2 2
0 0 1 1 3 3
0 1 0 0 4 4
0 1 0 1 5 5
0 1 1 0 6 6
0 1 1 1 7 7
1 0 0 0 8 8
1 0 0 1 9 9
1 0 1 0 A 10
1 0 1 1 B 11
1 1 0 0 C 12
1 1 0 1 D 13
1 1 1 0 E 14
1 1 1 1 F 15

Another interesting point: look at the value in the column top. Then look at the values. You see what I mean? Yeah, you’re right! The bits switch on and off following their value. The value of the first digit (starting from the right), goes like this: 0,1,0,1,0,1,0,1,0,1,… Second digit: 0,0,1,1,0,0,1,1,0,0,1,1,0,0… Third digit (value=4): 0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,1,… And so on…

Now, what about greater numbers? Therefore we’ll need an extra digit. (but I think you figured that out by yourself). For the values starting from 16, our table looks like this:

Binary Numbers
16 8 4 2 1 Hexadecimal Value Decimal Value
1 0 0 0 0 10 16
1 0 0 0 1 11 17
1 0 0 1 0 12 18
1 0 0 1 1 13 19
1 0 1 0 0 14 20
1 0 1 0 1 15 21
1 0 1 1 0 16 22
1 0 1 1 1 17 23
1 1 0 0 0 18 24
1 1 0 0 1 19 25
1 1 0 1 0 1A 26
1 1 0 1 1 1B 27
1 1 1 0 0 1C 28
1 1 1 0 1 1D 29
1 1 1 1 0 1E 30
1 1 1 1 1 1F 31
For octals, this is similar, the only difference is that we need only 3 digits to express the values 1->7. Our table looks like this:
Binary Numbers
4 2 1 Octal Value Decimal Value
0 0 0 0 0
0 0 1 1 1
0 1 0 2 2
0 1 1 3 3
1 0 0 4 4
1 0 1 5 5
1 1 0 6 6
1 1 1 7 7

Conversion.

In the latter topic I explained the logic behind the binary, hexadecimal and octal number systems. Now I’ll explain something more practical. If you fully understood the previous thing you can skip this topic.

From decimal to binary

  • Step 1: Check if your number is odd or even.
  • Step 2: If it's even, write 0 (proceeding backwards, adding binary digits to the left of the result).
  • Step 3: Otherwise, if it's odd, write 1 (in the same way).
  • Step 4: Divide your number by 2 (dropping any fraction) and go back to step 1. Repeat until your original number is 0.

An example:
Convert 68 to binary:

  • 68 is even, so we write 0.
  • Dividing 68 by 2, we get 34.
  • 34 is also even, so we write 0 (result so far - 00)
  • Dividing 34 by 2, we get 17.
  • 17 is odd, so we write 1 (result so far - 100 - remember to add it on the left)
  • Dividing 17 by 2, we get 8.5, or just 8.
  • 8 is even, so we write 0 (result so far - 0100)
  • Dividing 8 by 2, we get 4.
  • 4 is even, so we write 0 (result so far - 00100)
  • Dividing 4 by 2, we get 2.
  • 2 is even, so we write 0 (result so far - 000100)
  • Dividing 2 by 2, we get 1.
  • 1 is odd, so we write 1 (result so far - 1000100)
  • Dividing by 2, we get 0.5 or just 0, so we're done.
  • Final result: 1000100

From binary to decimal

  • Write the values in a table as shown before. (or do so mentally)
  • Add the value in the column header to your number, if the digit is turned on (1).
  • Skip it if the value in the column header is turned off (0).
  • Move on to the next digit until you’ve done them all.

An example:
Convert 101100 to decimal:

  • Highest digit value: 32. Current number: 32
  • Skip the "16" digit, its value is 0. Current number: 32
  • Add 8. Current number: 40
  • Add 4. Current number: 44
  • Skip the "2" and "1" digits, because their value is 0.
  • Final answer: 44

From decimal to hexadecimal.

THIS IS ONLY ONE OF THE MANY WAYS!

  • Convert your decimal number to binary
  • Split up in nibbles of 4, starting at the end
  • Look at the first table on this page and write the right number in place of the nibble

(you can add zeroes at the beginning if the number of bits is not divisible by 4, because, just as in decimal, these don’t matter)

An example:
Convert 39 to hexadecimal:

  • First, we convert to binary (see above). Result: 100111
  • Next, we split it up into nibbles: 0010/0111 (Note: I added two zeroes to clarify the fact that these are nibbles)
  • After that, we convert the nibbles separately.
  • Final result: 27

From hexadecimal to decimal

*Check the formula in the first paragraph and use it on the ciphers in your hexadecimal number. (this actually works for any conversion to decimal notation)

An example:
Convert 1AB to decimal:

  • Value of B = 160×11. This gives 11, obviously
  • Value of A = 161×10. This gives 160. Our current result is 171.
  • Value of 1 = 162×1. This gives 256.
  • Final result: 427

From decimal to octal

  • Convert to binary.
  • Split up in parts of 3 digits, starting on the right.
  • Convert each part to an octal value from 0 to 7

Example: Convert 25 to octal

  • First, we convert to binary. Result: 11001
  • Next, we split up: 011/001
  • Conversion to octal: 31

From octal to decimal

Again, apply the formula from above

Example: convert 42 to decimal

  • Value of 2=80×2=2
  • Value of 4=81×4=32
  • Result: 34

Fun Facts

OK, these may not be 100% "fun", but nonetheless are interesting.

  • Do you tend to see numbers beginning with 0x? This is common notation to specify hexadecimal numbers, so you may see something like:
0x000000
0x000002
0x000004

This notation is most commonly used to list computer addresses, which are a whole different story.
  • This is pretty obvious, but you can "spell" words using hexadecimal numbers. For example:
    • CAB = 3243 in decimal notation.

End

Did you understand everything? If you think so, test yourself:

Bin Dec Hex
3A
76
101110
88
1011110
47

Make some exercises yourself, if you want some more.

For the most up-to-date version of this page, see http://tibasicdev.wikidot.com/binandhex


Error Conditions

A | B | D | E | I | L | M | N | O | R | S | T | U | V | W | Z

In the Error Conditions section on a command page, descriptions will be given of the errors that can result when using a command. These do not include errors that can occur with virtually any command, such as ERR:ARGUMENT or ERR:SYNTAX. However, if one of these errors is triggered in an unusual way, it will be listed.

Be aware that certain errors don't occur when graphing or using one of the commands DrawF, DrawInv, Tangent(, or Shade(. Instead, the graph point is skipped and treated as an undefined value. Tangent( is a minor exception, actually: if there's an error at the tangent point, it will be treated normally. The errors that are ignored in graphs are:

There are are also several error messages that don't actually occur (as far as anyone knows) from normal use of the calculator — however, the messages are stored in the OS along with the normal messages. It's conceivable that an assembly program, especially an official TI application, would use these error messages for its own purposes. These messages are ERR:SOLVER, ERR:SCALE, ERR:NO MODE, ERR:LENGTH, and ERR:APPLICATION.

A

ARCHIVED

  • You have attempted to use, edit, or delete an archived variable. For example, dim(L1) is an error if L1 is archived.
  • Use UnArchive variable name to unarchive the variable before using it. For lists, SetUpEditor is recommended instead since it does the same thing, but works on the TI-83 (which has no archive) as well, and does not crash when the list is undefined.
  • There is no way to archive or unarchive programs using pure Basic, although several assembly utilities are available for doing so.
  • When you attempt to edit a archived Matrix,List,Variable, or program, the option 2:GOTO doesn't show up.
  • Use Unarchive or the memory manager to unarchive a variable,matrix,list, program, etc.

ARCHIVE FULL

  • You have attempted to archive a variable and there is not enough space in archive to receive it.
  • Sometimes, if the calculator displays a message from memory management saying "Garbage Collect?", choosing the option No gives this error.

ARGUMENT

  • A function or instruction does not have the correct number of arguments. See the appropriate command page.
  • A function or instruction that can have any number of arguments has 256 or more.
  • In general, if a function has more than one non-SYNTAX error in it, this is the error that will be generated first (if it applies, of course).
  • Generally, on graphing calculators and such, most functions ex: randInt( require that you use commas to make a list.

B

BAD ADDRESS

  • You have attempted to send or receive an application and an error (e.g., electrical interference) has occurred in the transmission.

BAD GUESS

  • With the solve( function, the equation solver, or an operation from the CALC menu, your guess wasn't within the lower and upper bound, or else the function is undefined at that point. Change the guess.

BOUND

  • In a CALC operation or with Select(, you defined Left Bound > Right Bound.
  • In fMin(, fMax(, solve(, or the equation solver, the lower bound must be less than the upper bound.

BREAK

  • You pressed the [ON] key to break execution of a program, to halt a DRAW instruction, or to stop evaluation of an expression.

D

DATA TYPE

  • You entered a value or variable that is the wrong data type.
  • For a function (including implied multiplication) or an instruction, you entered an argument that is an invalid data type, such as a complex number where a real number is required.
  • In an editor, you entered a type that is not allowed, such as a matrix entered as an element in the stat list editor.
  • You attempted to store an incorrect data type, such as a matrix to a list.
  • You attempted to divide matrices, which should be done by matrix inversion and multiplication instead.
  • This error is not returned when graphing (see the note at the top of the page).

DATE

  • Only on the TI-84+ or TI-84+ SE, this error occurs when an invalid date is entered.
  • Below the error menu, an explanation of what's wrong is given: e.g., "Invalid day for month selected."

DIM MISMATCH

  • You attempted to perform an operation that references more than one list or matrix, but the dimensions do not match.
  • In most cases, the dimensions are required to be equal, with the following exceptions:
    • When multiplying two matrices, the number of columns of the first must match the number of rows of the second.
    • When using augment( to combine two matrices, only the number of rows must match.
    • With the List►matr( command, the lists don't have to match sizes - shorter lists will be padded with zeroes.

DIVIDE BY 0

  • You attempted to divide by zero.
  • You attempted a linear regression on data that fit a vertical line.
  • This error is not returned when graphing (see the note at the top of the page).

DOMAIN

  • You specified an argument to a function or instruction outside the valid range. This error is not returned during graphing. The TI-83+ allows for undefined values on a graph.
  • You attempted a logarithmic or power regression with a negative X or an exponential or power regression with a negative Y.
  • You attempted to compute ΣPrn( or ΣInt( with pmt2 < pmt1.
  • You've assigned a value to n (the sequential graph variable), nMin or nMax that isn't an integer, or that is less than 0.
  • This error is not returned when graphing (see the note at the top of the page).

DUPLICATE

  • You attempted to create a duplicate group name.
  • You attempted to create a duplicate program using AsmComp(.

Duplicate Name

  • A variable you attempted to transmit cannot be transmitted because a variable with that name already exists in the receiving unit.
  • Also appears when you unpack a group and a variable in the group is already defined. In both cases, it will give you several options for correcting the error, including Omit, Rename, and Overwrite.

E

EXPIRED

  • You have attempted to run a Flash application with a limited trial period which has expired.

Error in Xmit

  • The TI-83+ was unable to transmit an item. Check to see that the cable is firmly connected to both units and that the receiving unit is in receive mode.
  • You pressed [ON] to break during transmission.
  • You attempted to perform a backup from a TI-82 to a TI-83+.
  • You attempted to transfer data (other than L1 through L6) from a TI-83+ to a TI-82.
  • You attempted to transfer L1 through L6 from a TI-83+ to a TI-82 without using 5:Lists to TI-82 on the LINK SEND menu.
  • You attempted to use SendOS with no other calculator connected.
  • When this error occurs, the option 2:Goto doesn't show up, but will redirect you to the LINK screen instead of the main screen.

I

ID NOT FOUND

  • This error occurs when the SendID command is executed, but the proper calculator ID cannot be found.
  • When this error occurs, the option 2:Goto does not show up.

ILLEGAL NEST

  • You attempted to use an invalid function in an argument to a function.
  • This happens when using seq( in the expression for seq(, fnInt( within the first argument of fnInt(, expr( inside the string argument of expr(, or Σ( within the argument for Σ(.

INCREMENT

  • The increment in seq( is 0 or has the wrong sign.
  • The increment in a For( loop is 0.
  • This error is not returned when graphing (see the note at the top of the page).

INVALID

  • You attempted to reference a variable or use a function where it is not valid. For example, Yn cannot reference Y, Xmin, ΔX, or TblStart.
  • You attempted to reference a variable or function that was transferred from the TI-82 and is not valid for the TI-83+. For example, you may have transferred UnN1 to the TI-83+ from the TI-82 and then tried to reference it.
  • In Seq mode, you attempted to graph a phase plot (uvAxes, uwAxes, or vwAxes) without defining both equations of the phase plot.
  • In Seq mode, you attempted to graph a recursive sequence without having input the correct number of initial conditions.
  • In Seq mode, you attempted to reference terms other than (n-1) or (n-2).
  • You attempted to designate a graph style that is invalid within the current graph mode.
  • You attempted to use Select( without having selected (turned on) at least one xyLine or scatter plot.
  • You attempted to use certain functions (e.g. If, Then, Else) outside a program.

INVALID DIM

  • You tried to access an element past the end of a list or matrix (there is an exception: it's allowed to store to the element one past the end of a list, adding the element).
  • You specified dimensions for an argument that are not appropriate for the operation.
  • You specified a list dimension as something other than an integer between 1 and 999.
  • You specified a matrix dimension as something other than an integer between 1 and 99.
  • You attempted to invert a matrix that is not square.

ITERATIONS

  • The solve( function or the equation solver has exceeded the maximum number of permitted iterations. Examine a graph of the function. If the equation has a solution, change the bounds, or the initial guess, or both.
  • irr( has exceeded the maximum number of permitted iterations.
  • When computing I%, the maximum number of iterations was exceeded.

L

LABEL

  • The label in the Goto instruction is not defined with a Lbl instruction in the program.
  • When this error occurs, the option 2:Goto doesn't show up.

Link

  • Something in the flash application was invalid while running.
  • When this error occurs, the option 2:Goto doesn't show up.

M

MEMORY

  • Memory is insufficient to perform the instruction or function. You must delete items from memory before executing the instruction or function.
  • You might also want to try archiving some variables,matrixes,lists,etc if you have nothing in RAM that you don't need.
  • Recursive problems return this error; for example, graphing the equation Y1=Y1. (but Y1=X, Y2=Y1, for example, will NOT cause an error.)
  • Branching out of an If:Then, For(, While, or Repeat loop with a Goto will waste memory until the program finishes running, because the End statement that terminates the loop is never reached. Unless a program is very large, this is one of the likeliest causes of ERR:MEMORY. Refer to memory-leaks.

MemoryFull

  • You are unable to transmit an item because the receiving unit’s available memory is insufficient. You may skip the item or exit receive mode.
  • During a memory backup, the receiving unit’s available memory is insufficient to receive all items in the sending unit’s memory. A message indicates the number of bytes the sending unit must delete to do the memory backup. Delete items and try again.
  • You may also try to archive some variables to free up some memory that you do not plan to transmit.

MODE

  • You attempted to store to a window variable in another graphing mode or to perform an instruction while in the wrong mode; for example, DrawInv in a graphing mode other than Func.

N

NO SIGN CHNG

  • The solve( function or the equation solver did not detect a sign change.
  • You attempted to compute I% when FV, (N*PMT), and PV all share the same sign.
  • You attempted to compute irr( when CFList and CFO share the same sign.

NONREAL ANS

  • In Real mode, the result of a calculation yielded a complex result.
  • This error is not returned when graphing (see the note at the top of the page).
  • This error can appear if you use a negative number for some operations, such as ln

O

OVERFLOW

  • You attempted to enter, or you have calculated, a number that is beyond the range of the calculator (-1E100 to 1E100, non-inclusive).
  • Sometimes you can fix this error by re-ordering operations. For example, 60!*30!/20! will return an overflow error, but 60!/20!*30! will not.
  • This error is not returned when graphing (see the note at the top of the page).

R

RESERVED

S

SINGULAR MAT

  • A singular matrix (determinant = 0) is not valid as the argument for -1.
  • A regression generated a singular matrix (determinant = 0) because it could not find a solution, or a solution does not exist.
  • This error is not returned when graphing (see the note at the top of the page).

SINGULARTY

  • The expression in the solve( function or the equation solver contains a singularity (a point at which the function is not defined). Examine a graph of the function. If the equation has a solution, change the bounds or the initial guess or both.
  • Although the correct spelling is "singularity", the error message shown has "singularty" on all calculators and OS versions.

STAT

  • You attempted a stat calculation with lists that are not appropriate.
  • Statistical analyses must have at least two data points.
  • Med-Med must have at least three points in each partition.
  • When you use a frequency list, its elements must be at least 0.
  • (Xmax - Xmin) / Xscl must equal 47 for a histogram.

STAT PLOT

  • You attempted to display a graph when a stat plot that uses an undefined list is turned on.
  • To fix this error, use the command PlotsOff to turn off plots when you're using the graph screen.

SYNTAX

  • The command contains a syntax error. Look for misplaced functions, arguments, parentheses, or commas. See the appropriate command page.
  • This error will also occur in place of a DATA TYPE error if the variable type in question is a variable name (with seq(, solve(, For(, and other commands)
  • The command was attempting to get expr( of a non-value string, i.e., trying to evaluate a space, equals sign, etc.

T

TOL NOT MET

  • You requested a tolerance to which the algorithm cannot return an accurate result.

U

UNDEFINED

  • You referenced a variable that is not currently defined. This error doesn't occur with number variables (A-Z,θ), which have a default value of 0.
  • Lists, matrices,strings,pictures, and GDBs have to be stored to first, in order to be used.
  • Most system variables always have a value, so this error doesn't apply to them.
  • However, statistical variables are undefined except for those used by the last relevant command.
  • Undefined equation variables (such as Parametric and Polar variables) return ERR:INVALID instead of ERR:UNDEFINED.

V

VALIDATION

  • Electrical interference caused a link to fail or this calculator is not authorized to run the application and/or Operating System.

VARIABLE

  • You have tried to archive a variable that cannot be archived or you have have tried to unarchive an application or group.
  • Variables that cannot be archived include:
    • The number variables R, T, X, Y, and θ (because they are used for graphing)
    • The list ∟RESID (because it's reserved for residuals from regression models)
    • System variables (including statistical variables, finance variables, equations, plots, and window variables)
    • The AppIdList.

VERSION

  • You have attempted to receive an incompatible variable version from another calculator.
  • You have attempted to use or display certain corrupted tokens that the calculator will not allow.

W

WINDOW RANGE

  • A problem exists with the window variables.
    • You defined Xmin>Xmax or Ymin>Ymax.
    • Xmin and Xmax (or Ymin and Ymax) are equal or so close that numerical precision can't allow for enough values between them.
    • The values for θmin, θmax, and θstep create an empty or never-ending loop for θ.
    • The values for Tmin, Tmax, and Tstep create an empty or never-ending loop for T.
  • When this error occurs, the option 2:Goto doesn't show up.

Z

ZOOM

  • A point or a line, instead of a box, is defined in ZBox.
  • A ZOOM operation returned a math error.
  • When this error occurs, the option 2:Goto doesn't show up.

Other

?

  • An unknown error has occurred.

For the most up-to-date version of this page, see http://tibasicdev.wikidot.com/errors


Glossary

For the most up-to-date version of this page, see http://tibasicdev.wikidot.com/abbreviations


Key Codes
getkey.png
xlib-keys.png

The picture to the right top contains the value returned by getKey for each keypress. The picture is organized so that the key codes are placed where they would be on the literal calculator. You should note that the [ON] key (the key in the bottom left corner) has no key code, so you cannot check for nor disable it.

If you look at the key codes, you will probably notice that they actually follow a pattern: a key is represented by putting its row and column together. For example, the [ENTER] key is row 10, column 5; therefore, its value is 105. The up, right, and left arrow keys are assumed to be in the second row, and the down arrow key is in the 3rd row.

In case you want to know the key codes while using your calculator, here is a simple program to use:

:Repeat Ans=105
:getKey
:If Ans:Disp Ans
:End

The picture to the right bottom contains the value returned by the real(8 command when using xlib. The key placement is somewhat disorganized, but consistent for the most part. The [ON] key will return a value, according to the tutorial, but due to the [ON] break inherent to TI-Basic, it will not be returned.

11 12 13 14 15
25
21 22 23 24 26
31 32 33 34
41 42 43 44 45
51 52 53 54 55
61 62 63 64 65
71 72 73 74 75
81 82 83 84 85
91 92 93 94 95
102 103 104 105

For the most up-to-date version of this page, see http://tibasicdev.wikidot.com/key-codes


Tokens and Token Size

Each command, variable, and operation on the TI-83 series calculators is represented by a "token." This means that internally, the calculator does not store a command such as "cos(" as the letters c, o, s, and (. It stores a single number that it will later translate as "cos(" when necessary. In this case, the value is 196, but you most likely don't need to know that.

What you do need to know is that not all tokens are the same size. If there were 256 tokens or less, then you could fit all their values into 1 byte and be happy. Unfortunately, the TI-83 has more than 256 commands and variables. Therefore TI employed some trickery and made some tokens take up 1 byte (usually the most common ones, though they seem to have had a different idea of "common") and some take up 2 bytes.

What this means to you, as the programmer, is that the size of the program is determined by the number of commands, not the number of letters in it: a short line can take up more memory than a longer one if it uses a lot of commands. Furthermore, some commands will take up the memory of two commands rather than one, so a line with a few of these commands may take up as much memory as a line with more commands of the ordinary type.

Lowercase letters are the epitome of memory wasters: at a single character, they each take up 2 bytes of memory. A program that uses a lot of lowercase letters can fill up all of RAM very quickly! This may be avoided by using uppercase letters instead, which only take up 1 byte each. You can also save memory by replacing words such as "If", " or ", " and " with the appropriate commands, when displaying text. Such a command will only take up 1 byte, whereas the text may be much larger memory-wise. Lowercase letters are also not available on the original TI-83, so if you use them, your program will not work on it.

Token Tables

Below you can find the byte values for all the 83 series tokens, organized by category and two-byte prefix. For up-to-date and machine-readable tables, consider using the TI Toolkit token sheets.

There are several ways to insert a token given its hex value; all of them require an assembly program of some form. One of the easiest is to create an assembly program using AsmPrgm followed by the hex codes you want to convert to tokens, assemble it using AsmComp(, and then unlock it (there are many programs that allow you to do this).

For the most up-to-date version of this page, see http://tibasicdev.wikidot.com/tokens

page revision: 3, last edited: 04 Mar 2009 11:37

Unless stated otherwise Content of this page is licensed under Creative Commons Attribution-Noncommercial 2.5 License.