The Secret Guide to Computers 



Series Let’s make the computer add together all the numbers from 7 to 100, so that the computer finds the sum of this series: 7 + 8 + 9 + ... + 100. Here’s how. CLS Start the sum at 0: s = 0 Make i go from 7 to 100: FOR i = 7 TO 100 Increase sum, by adding each i to it: s = s + i NEXT Print the final sum (which is 5029): PRINT s Let’s make the computer add together the squares of all the numbers from 7 to 100, so that the computer finds the sum of this series: (7 squared) + (8 squared) + (9 squared) +… + (100 squared). Here’s how: CLS s = 0 FOR i = 7 TO 100 s = s + i * i NEXT PRINT s It’s the same as the previous program, except that indented line says to add i*i instead of i. The bottom line prints the final sum, which is 338259. Data sums This program adds together the numbers in the data: CLS DATA 5, 3, 6.1, etc. DATA 0 s = 0 DO READ x: IF x = 0 THEN EXIT DO s = s + x LOOP PRINT s The DATA line contains the numbers to be added. The DATA 0 is an end mark. The line saying “s = 0” starts the sum at 0. The READ statement reads an x from the data. The next line (s = s + x) adds x to the sum. The LOOP line makes the computer repeat that procedure for every x. When the computer has read all the data and reaches the end mark (0), the x becomes 0; so the computer will EXIT DO and PRINT the final sum, s. Pretty output Here’s how to make your output prettier. Zones The screen is divided into 5 wide columns, called zones. The leftmost zone is called zone 1; the rightmost zone is called zone 5. Zones 1, 2, 3, and 4 are each 14 characters wide. Zone 5 is extrawide: it’s 24 characters wide. So altogether, the width of the entire screen is 14+14+14+14+24, which is 80 characters. The screen is 80 characters wide. A comma makes the computer jump to a new zone. Here’s an example: CLS PRINT "sin", "king" The computer will print “sin” and “king” on the same line; but because of the comma before “king”, the computer will print “king” in the second zone, like this: sin king
first zone second zone third zone fourth zone fifth zone
Here are the words of a poet who drank too much and is feeling spaced out: CLS PRINT "love", "cries", "out" The computer will print “love” in the first zone, “cries” in the second zone, and “out” in the third zone, so the words are spaced out like this: love cries out This program’s even spacier: CLS PRINT "love", "cries", "out", "to", "me", "at", "night" The computer will print “love” in the first zone, “cries” in the second, “out” in the third, “to” in the fourth, “me” in the fifth, and the remaining words below, like this: love cries out to me at night This program tells a bad joke: CLS PRINT "I think you are ugly!", "I'm joking!" The computer will print “I think you are ugly!”, then jump to a new zone, then print “I’m joking”, like this: I think you are ugly! I'm joking!
first zone second zone third zone fourth zone fifth zone
When you combine commas with semicolons, you can get weird results: CLS PRINT "eat", "me"; "at"; "balls", "no"; "w" That line contains commas and semicolons. A comma makes the computer jump to a new zone, but a semicolon does not make the computer jump. The computer will print “eat”, then jump to a new zone, then print “me” and “at” and “balls”, then jump to a new zone, then print “no” and “w”. Altogether, the computer will print: eat meatballs now Skip a zone You can make the computer skip over a zone: CLS PRINT "Joe", " ", "loves Sue" The computer will print “Joe” in the first zone, a blank space in the second zone, and “loves Sue” in the third zone, like this: Joe loves Sue
first zone second zone third zone fourth zone fifth zone
You can type that example even more briefly, like this: CLS PRINT "Joe", , "loves Sue" Loops This program makes the computer greet you: CLS DO PRINT "hello", LOOP The computer will print “hello” many times. Each time will be in a new zone, like this: hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello etc. Tables This program prints a list of words and their opposites: CLS PRINT "good", "bad" PRINT "black", "white" PRINT "grandparent", "grandchild" PRINT "he", "she" Line 2 makes the computer print “good”, then jump to the next zone, then print “bad”. Altogether, the computer will print: good bad black white grandparent grandchild he she The first zone contains a column of words; the second zone contains the opposites. Altogether, the computer’s printing looks like a table. So whenever you want to make a table easily, use zones, by putting commas in your program. Let’s make the computer print this table: Number Square 3 9 4 16 5 25 6 36 7 49 8 64 9 81 10 100 Here’s the program: CLS PRINT "Number", "Square" FOR i = 3 TO 10 PRINT i, i * i NEXT Line 2 prints the word “Number” at the top of the first column, and the word “Square” at the top of the second. Those words are called the column headings. The FOR line says i goes from 3 to 10; to begin, i is 3. The indented line makes the computer print: 3 9 The bottom line makes the computer do the same thing for the next i, and for the next i, and for the next; so the computer prints the whole table. TAB When the computer puts a line of information on your screen, the leftmost character in the line is said to be at position 1. The second character in the line is said to be at position 2. This program makes the computer skip to position 6 and then print “HOT”: CLS PRINT TAB(6); "hot" The computer will print: hot 12345678 Here’s a fancier example: PRINT TAB(6); "hot"; TAB(13); "buns" The computer will skip to the 6^{th} position, then print “hot”, then skip to the 13^{th} position, then print “buns”: HOT BUNS 12345678 13 Diagonal This program prints a diagonal line: CLS FOR i = 1 TO 12 PRINT TAB(i); "*" NEXT The FOR line says to do the loop 12 times, so the computer does the indented line. The first time the computer does the indented line, the i is 1, so the computer prints an asterisk at position 1: * The next time, the i is 2, so the computer skips to position 2 and prints an asterisk: * The next time, the i is 3, so the computer skips to position 3 and prints an asterisk: * Altogether, the program makes the computer print this picture: * * * * * * * * * * * * Calendar Let’s make the computer print this message: January has 31 days February has 28 days March has 31 days April has 30 days May has 31 days June has 30 days July has 31 days August has 31 days September has 30 days October has 31 days November has 30 days December has 31 days Here’s the program: CLS DATA January,31,February,28,March,31,April,30,May,31,June,30,July,31 DATA August,31,September,30,October,31,November,30,December,31 FOR i = 1 TO 12 READ month.name$, how.many.days PRINT month.name$, "has"; how.many.days; "days" NEXT The DATA shows each month’s name and how many days are in the month. The READ line says to read a month’s name and how many days are in the month. The PRINT line makes the computer print the month’s name, then skip to the next zone, then print the word “has”, then print how many days, then print the word “days”. Instead of making the computer say “January has 31 days”, let’s make the computer print all the days of each month: January 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 Let’s make the computer print that on paper, for each month, so the paper shows a crude calendar for the entire year. To do that, just change the program’s PRINT line to this sequence: LPRINT month.name$ FOR day = 1 TO how.many.days LPRINT day; NEXT LPRINT LPRINT In that sequence, the first LPRINT statement makes the computer print, on paper, the month’s name (“January”). The FOR loop makes the computer print each day (1, 2, 3, etc.). The bottom two lines (which both say LPRINT) make the computer leave blank space under January’s calendar, to separate it from February’s. Here’s the entire program: CLS DATA January,31,February,28,March,31,April,30,May,31,June,30,July,31 DATA August,31,September,30,October,31,November,30,December,31 FOR i = 1 TO 12 READ month.name$, how.many.days LPRINT month.name$ FOR day = 1 TO how.many.days LPRINT day; NEXT LPRINT LPRINT NEXT It makes the computer print a calendar beginning like this: January 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
February 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 You must eject the paper from the printer manually. For a leap year, change the DATA’s 28 to 29. Pretty weeks Although that calendar program makes the computer print the right numbers for each month, it prints the numbers in the wrong places. Let’s make the computer print at most 7 numbers in each row, so each is a week. To print the numbers in the right places, use TAB. So instead of saying — LPRINT day; say: LPRINT TAB(t); day; That line will make the computer print each day in the right position… if we define t correctly. But how should we define t? For Sunday, let’s make t be 1, so that Sunday begins at position 1. For Monday, let’s make t be 5, so that Monday begins at position 5. For Tuesday, let’s make t be 9; for Wednesday, 13; Thursday, 17; Friday, 21; and Saturday, 25. So whenever a day’s been printed, t should normally increase by 4 for the next day: LPRINT TAB(t); day; t = t + 4 Saturday’s the last day of the week. After Saturday, we must begin a new week. So if t has passed Saturday (which is 25), we want t to become 1 (for Sunday); and if there are more days left in the month, we want the computer to press the ENTER key (to start a new week): IF t > 25 THEN t = 1 IF day < how.many.days THEN LPRINT END IF Which year would you like a calendar for: 2002? 2003? 2004? This program makes a pretty calendar for 2003: CLS DATA January,31,February,28,March,31,April,30,May,31,June,30,July,31 DATA August,31,September,30,October,31,November,30,December,31 LPRINT "Calendar for 2003" LPRINT t = 13 FOR i = 1 TO 12 READ month.name$, how.many.days LPRINT month.name$ LPRINT "Sun Mon Tue Wed Thu Fri Sat" FOR day = 1 TO how.many.days LPRINT TAB(t); day; t = t + 4 IF t > 25 THEN t = 1 IF day < how.many.days THEN LPRINT END IF NEXT LPRINT LPRINT IF i = 6 OR i = 12 THEN LPRINT CHR$(12); NEXT Line 4 prints the heading, “Calendar for 2003”. Line 5 puts a blank line underneath the heading. Since 2003 begins on a Wednesday, the next line tells the computer to start t at 13 (which is the position for Wednesday). The next line saying LPRINT “Sun Mon Tue Wed Thu Fri Sat” puts a heading at the top of each month. The nexttobottom line says: if the computer has reached the end of June (month 6) or December (month 12), eject the paper, so that the first half of the year is on one sheet of paper and the second half of the year is on the other. The computer will print a calendar beginning like this: Calendar for 2003
January Sun Mon Tue Wed Thu Fri Sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
February Sun Mon Tue Wed Thu Fri Sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
March Sun Mon Tue Wed Thu Fri Sat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 If you want a different year, change line 4 (which says LPRINT “Calendar for 2003”) and line 6 (which says the year starts on Wednesday, t = 13). For a leap year, change the DATA’s 28 to 29. LOCATE While your running a program, the black screen show 25 lines of information. The screen’s top line is called line 1; underneath it is line 2; then comes line 3; etc. The bottom line is line 25. Each line consists of 80 characters. The leftmost character is at position 1; the next character is at position 2; etc. The rightmost character is at position 80. On the screen, the computer will print wherever you wish. For example, to make the computer print the word “drown” so that “drown” begins at line 3’s 7th position, type this: CLS LOCATE 3, 7: PRINT "drown" The computer will print the word’s first letter (d) at line 3’s 7th position. The computer will print the rest of the word afterwards. You’ll see the first letter (d) at line 3’s 7th position, the next letter (r) at the next position (line 3’s 8th position), the next letter (o) at the next position (line 3’s 9th position), etc. Middle of the screen Since the screen’s top line is 1 and the bottom line is 25, the middle line is 13. Since the screen’s leftmost position is 1 and the rightmost position is 80, the middle positions are 40 and 41. To make the computer print the word “Hi” in the middle of the screen, tell the computer to print at the middle line (13) and the middle positions (40 and 41): CLS LOCATE 13, 40: PRINT "Hi" Bottom line Whenever the computer finishes running a program, the computer prints this message on the black screen’s bottom line: Press any key to continue Then the computer waits for you to press the ENTER key, which makes the screen turn blue and show the lines of your program. That message, “Press any key to continue”, is the only message that the computer wants to print on the bottom line. To force the computer to print anything else on the bottom line, do this: say LOCATE, mention line 25, put a semicolon at the end of the PRINT statement (to prevent the computer from pressing the ENTER key, which would disturb the rest of the screen), and say SLEEP (to make the computer pause awhile so you can admire the printing). For example, this program prints an “x” at the screen’s bottom right corner: CLS LOCATE 25, 80: PRINT "x"; SLEEP Pixels The image on the computer’s screen is called the picture. If you stare at the picture closely, you’ll see the picture’s composed of thousands of tiny dots. Each dot, which is a tiny rectangle, is called a picture’s element, or pic’s el, or pixel, or pel. Coordinates The dot in the screen’s top left corner is called pixel (0,0). Just to the right of it is pixel (1,0). Then comes pixel (2,0), etc. Underneath pixel (0,0) is pixel (0,1). Farther down is pixel (0,2). Here are the positions of the pixels: pixel (0,0) pixel (1,0) pixel (2,0) pixel (3,0) pixel (4,0) etc. pixel (0,1) pixel (1,1) pixel (2,1) pixel (3,1) pixel (4,1) etc. pixel (0,2) pixel (1,2) pixel (2,2) pixel (3,2) pixel (4,2) etc. pixel (0,3) pixel (1,3) pixel (2,3) pixel (3,3) pixel (4,3) etc. Each pixel’s name consists of two numbers in parentheses. The first number is the X coordinate; the second number is the Y coordinate. For example, if you’re talking about pixel (4,3), its X coordinate is 4; its Y coordinate is 3. The X coordinate tells how far to the right the pixel is. The Y coordinate tells how far down. So pixel (4,3) is the pixel that’s 4 to the right and 3 down. On the computer, the Y coordinate measures how far down, not up. If you’ve read oldfashioned math books in which the Y coordinate measured how far up, you’ll have to reverse your thinking! Screen modes How many pixels are on the screen? The answer depends on which screen mode you choose. Generally speaking, the best screen mode to choose is mode 12. In that mode, the X coordinate goes from 0 to 639, and the Y coordinate goes from 0 to 479, so the pixel at the screen’s bottom right corner is pixel (639,479). Since you have 640 choices for the X coordinate (numbered from 0 to 639) and 480 choices for the Y coordinate (numbered from 0 to 479), that mode is called a 640by480 mode. In that mode, the computer can display 16 colors simultaneously. Mode 12 works just if your computer’s video card is modern (VGA). If your computer’s video card is inferior (CGA, EGA, MCGA, Hercules, or Olivetti), mode 12 doesn’t work, and you must use a more primitive mode instead. Here are your choices: Mode Video card Pixels Colors 1 CGA (or EGA, MCGA, VGA) 320 by 200 4 2 CGA (or EGA, MCGA, VGA) 640 by 200 2 3 Hercules monochrome 720 by 348 2 4 Olivetti color 640 by 400 2 7 EGA (or VGA) 320 by 200 16 8 EGA (or VGA) 640 by 200 16 9 EGA (or VGA) 640 by 350 4 or 16 10 EGA (or VGA) 640 by 350 4 11 MCGA (or VGA) 640 by 480 2 12 VGA 640 by 480 16 13 MCGA (or VGA) 320 by 200 256 For example, here’s what that chart’s bottom row means: To use mode 13, your video card must be MCGA (or VGA). That mode lets you use 320 values of X (numbered from 0 to 319). That mode lets you use 200 values of Y (numbered from 0 to 199). That mode lets the screen display 256 colors simultaneously. As you can see from that chart, mode 12 is generally the best mode, since it gives you lots of pixels (640 by 480) and lots of colors (16). Mode 13 gives you even more colors (256) but restricts you to fewer pixels (just 320 by 200). That restriction makes mode 13’s drawings look crude. The following modes are just for bizarre situations.… Mode 3 is just for a monochrome monitor attached to a Hercules monochrome card. This mode does not work with color monitors. In this mode, you have just 2 “colors”: black and white. Mode 4 is just for a color video card made by Olivetti. That card is included in the AT&T 6300 computer. Mode 9 is intended mainly for EGA monitors. It gives you 16 colors usually, but just 4 colors if the video card’s RAM is just 64K. Mode 10 is intended mainly for monochrome monitors. It gives you 4 “colors”: black, bright white, dull white (cream), and blinking bright white. Each pixel is a tiny rectangular dot. In modes 11 and 12, each pixel is a perfect square, whose width is the same as its height: on a typical 15inch monitor, each pixel’s width and height is about a 60^{th} of an inch. In other modes, each pixel is slightly taller than it is wide, so each pixel looks like a little tower. There’s also a mode 0, which works on all computers and produces just text (no graphics). Here’s which mode to choose: Video card Which mode to choose Hercules 3 Olivetti 4 CGA 1 (for many colors) or 2 (for many pixels) EGA 9 (for color) or 10 (for monochrome) MCGA 11 (for many pixels) or 13 (for many colors) VGA 12 (for many pixels) or 13 (for many colors) To give commands about pixels, begin by telling the computer which mode you want. For example, if you want screen mode 12, say: SCREEN 12 When you give such a SCREEN command, the computer automatically clears the screen, so the entire screen becomes black. You do not have to say CLS. PSET If your monitor is modern (VGA), this program makes the screen become black, then makes pixel (100,100) turn white: SCREEN 12 PSET (100, 100) If your monitor is less than VGA, choose a different screen mode than 12. In that program, the PSET (100, 100) makes pixel (100,100) turn white. The word “PSET” means “pixel set”: “PSET (100, 100)” means “set the pixel (100,100) to white”. LINE This program draws a white line from pixel (0,0) to pixel (100,100): SCREEN 12 LINE (0, 0)(100, 100) This program draws a white line from pixel (0,0) to pixel (100,100), then draws a white line from that pixel (100,100) to pixel (120,70): SCREEN 12 LINE (0, 0)(100, 100) LINE (120, 70) CIRCLE This program draws a white circle whose center is pixel (100,100) and whose radius is 40 pixels: SCREEN 12 CIRCLE (100, 100), 40 In modes 11 and 12, each pixel is a perfect square, and the computer draws the circle easily. The circle’s radius is 40 pixels; the circle’s diameter (width) is 80 pixels. If you switch to a different screen mode (such as SCREEN 2), each pixel is a tower instead of a square, so a “circle that’s 80 pixels wide and 80 pixels high” would be taller than wide and look like a tall oval. To make sure your “circle of radius 40” looks pretty, the computer cheats: the computer makes the circle’s width be 80 pixels but makes the circle’s height be fewer than 80 pixels, so that the circle’s height is the same number of inches as the width. Avoid the bottom When your program finishes, the bottom of the screen automatically shows this advice: Press any key to continue To prevent that advice from covering up your drawing, position your drawing near the top of the screen (avoiding the bottom), or else make your program’s bottom line say “SLEEP” so the computer will pause and let you admire the drawing before the advice covers it. PAINT After drawing a shape’s outline (by using dots, lines, and circles), you can fill in the shape’s middle, by telling the computer to PAINT the shape. Here’s how to PAINT a shape that you’ve drawn (such as a circle or a house). Find a pixel that’s in the middle of the shape and that’s still black; then tell the computer to PAINT, starting at that pixel. For example, if pixel (100, 101) is inside the shape and still black, say: PAINT (100, 101) Colors In modes 4, 7, 8, and 12, you can use these 16 colors: 0. black 8. light black (gray) 1. blue 9. light blue 2. green 10. light green 3. cyan (greenish blue) 11. light cyan (aqua) 4. red 12. light red (pink) 5. magenta (purplish red) 13. light magenta 6. brown 14. light brown (yellow) 7. cream (yellowish white) 15. light cream (pure white) In mode 1, you must choose from these 4 colors instead: 0. black 1. cyan (greenish blue) 2. magenta (purplish red) 3. cream (yellowish white) In modes 2, 3, and 11, you must choose from these 2 colors instead: 0. black 1. white In mode 10, you have these 4 choices: 0. black 1. cream 2. blinking white 3. white Mode 9 usually gives you the 16 colors used in mode 12; but if you’re using mode 9 with an EGA card having just 64K of RAM, you’re restricted to the 4 colors used in mode 1. Mode 13 gives you the 16 colors used in mode 12 — and many more colors, too! Here’s the spectrum: 0 through 7: black, blue, green, cyan, red, magenta, brown, cream 8 through 15: same colors as above, but lighter 16 through 31: shades of gray (from dark to light) 32 through 55: color blends (from blue to red to green to blue again) 56 through 79: same color blends, but lighter 80 through 103: same color blends, but even lighter 104 through 175: same as 32 through 103, but darker 176 through 247: same as 104 through 175, but even darker 248 through 255: black Normally, the PLOT, LINE, CIRCLE, and PAINT commands draw in yellowish white (cream). If you prefer a different color, put the color’s number at the end of the command. Put a comma before the color’s number. For example, if you want to draw a line from (0,0) to (100,0) using color #2, type this: LINE (0, 0)(100, 0), 2 When you give a PAINT command, you must make its color be the same color as the outline you’re filling in. Boxes If you type — LINE (0, 0)(100, 100), 2 the computer draws a line from pixel (0,0) to (100,100) using color #2. If you put the letter B at the end of the LINE command, like this — LINE (0, 0)(100, 100), 2, B the computer will draw a box instead of a line. One corner of the box will be at pixel (0,0); the opposite corner will be at (100,100); and the box will be drawn using color 2. If you put BF at the end of the LINE command, like this — LINE (0, 0)(100, 100), 2, BF the computer will draw a box and also fill it in, by painting its interior. Return to text mode When you finish drawing pictures, you can return to text mode by saying: SCREEN 0 If you were using mode 1, 7, or 13, say this instead: SCREEN 0 WIDTH 80 The “WIDTH 80” makes sure the screen will display 80 characters per line instead of 40. Sounds To produce sounds, you can say BEEP, SOUND, or PLAY. BEEP appeals to business executives; SOUND appeals to doctors and engineers; and PLAY appeals to musicians. BEEP If your program says — BEEP the computer will beep. The beep lasts for about a quarter of a second. Its frequency (“pitch”) is about 875 hertz. (The beep’s length and frequency might be slightly higher or lower, depending on which computer you have.) You can say BEEP in the middle of your program. For example, you can tell the computer to BEEP if a person enters wrong data. This program makes the computer act as a priest and perform a marriage ceremony: CLS 10 INPUT "Do you take this woman to be your lawful wedded wife"; a$ IF a$ <> "I do" THEN BEEP: PRINT "Try again!": GO TO 10 20 INPUT "Do you take this man to be your lawful wedded husband"; a$ IF a$ <> "I do" THEN BEEP: PRINT "Try again!": GO TO 20 PRINT "I now pronounce you husband and wife." Line 10 makes the computer ask the groom, “Do you take this woman to be your lawful wedded wife?” If the groom doesn’t say “I do”, the next line makes the computer beep, say “Try again!”, and repeat the question. Line 20 does the same thing to the bride. The bottom line congratulates the couple for answering correctly and getting married. SOUND If your program says — SOUND 440, 18.2 the computer will produce a sound. In that command, the 440 is the frequency (“pitch”), measured in hertz (cycles per second); so the sound will be a musical note whose pitch is 440 hertz. (That note happens to be “the A above middle C”). If you replace the 440 by a lower number, the sound will have a lower pitch; if you replace the 440 by a higher number, the sound will have a higher pitch. The lowest pitch that the computer can sing is 37. If you try to go below 37, the computer will gripe by saying: Illegal function call The highest pitch that the computer can sing is 32767, but human ears aren’t good enough to hear a pitch that high. When you were a baby, you could probably hear up to 20000. As you get older, your hearing gets worse, and you can’t hear such high notes. Today, the highest sound you can hear is probably somewhere around 14000. To find out, give yourself a hearing test, by running this program: CLS DO INPUT "What pitch would you like me to play"; p SOUND p, 18.2 LOOP When you run that program, begin by inputting a low pitch (such as 37). Then input a higher number, then an even higher number, until you finally pick a number so high you can’t hear it. (When trying that test, put your ear close to the computer’s speaker, which is in the computer’s front left corner.) When you’ve picked a number too high for you to hear, try a slightly lower number. Keep trying different numbers, until you find the highest number you can hear. Have a contest with your friends: find out which of your friends can hear best. If you run that program every year, you’ll see that your hearing gets gradually worse. For example, when I was 36 years old, the highest pitch I could hear was about 14500, but I can’t hear that high anymore. How about you? In those examples, the 18.2 makes the computer produce the sound for 1 second. If you want the sound to last longer — so that it lasts 2 seconds — replace the 18.2 by 18.2*2. For 10 seconds, say 18.2*10. (That’s because the computer’s metronome beats 18.2 times per second.) PLAY If your program says — PLAY "c d g# b a" the computer will play the note C, then D, then G sharp, then B flat, then A. In the PLAY command, the computer ignores the spaces; so if you wish, you can write: PLAY "cdg#ba" The computer can play in seven octaves, numbered from 0 to 6. Octave 0 consists of very bass notes; octave 6 consists of very highpitched notes. In each octave, the lowest note is a C: the notes in an octave are C, C#, D, D#, E, F, F#, G, G#, A, A#, and B. “Middle C” is at the beginning of octave 2. Normally, the computer plays in octave 4. To make the computer switch to octave 3, type the letter “o” followed by a 3, like this: PLAY "o3" After giving that command, anything else you PLAY will be in octave 3, until you change octaves again. You can use the symbol “>” to mean “go up an octave”, and you can use the symbol “<” to mean “go down an octave”. For example, if you say — PLAY "g > c d < g" the computer will play the note G, then go up an octave to play C and D in that higher octave, then go down to the original octave to play G again. The lowest note the computer can play (which is the C in octave 0) is called “note 1”. The highest note the computer can play (which is the B in octave 6) is called “note 84”. To make the computer play note 84, you can type this: PLAY "n84" To make the computer play its lowest note (1), then its middle note (42), then its highest note (84), type this: PLAY "n1 n42 n84" Besides playing with pitches, you can play with rhythms (“lengths” of the notes). Normally each note is a “quarter note”. To make the computer switch to eighth notes (which are faster), type this: PLAY "L8" Besides using L8 for eighth notes, you can use L16 for sixteenth notes (which are even faster), L32 for thirtysecond notes (which are superfast), and L64 for sixtyfourth notes (which are supersuperfast). For long notes, you can use L2 (which gives a half note) or L1 (which gives a whole note). You can use any length from L1 to L64. You can even use inbetween lengths, such as L7 or L23 (though such rhythms are hard to stamp your foot to). If you put a period after a note, the computer will multiply the note’s length by 1½. For example, suppose you say: PLAY "L8 c e. d" The C will be an 8th note, E will be 1½ times as long as an 8th note, and D will be an 8th note. Musicians call that E a dotted eighth note. If you put two periods after a note (like this: e..), the computer will multiply the note’s length by 13/4. Musicians say the note is double dotted. If you put three periods after a note (like this: e...), the computer will multiply the note’s length by 17/8. To make the computer pause (“rest”) for an eighth note, put a p8 into the music string. Normally, the computer plays 120 quarter notes per minute; but you can change that tempo. To switch to 150 quarter notes per minute, say: PLAY "t150" You can switch to any tempo from 32 to 255. The 32 is very slow; 255 is very fast. In musical terms, 40=larghissimo, 50=largo, 63=larghetto, 65=grave, 68=lento, 71=adagio, 76=andantino, 92=andante, 114=moderato, 120=allegretto, 144=allegro, 168=vivace, 188=presto, and 208=prestissimo. You can combine all those musical commands into a single PLAY statement. For example, to set the tempo to 150, the octave to 3, the length to 8 (which means an eighth note), and then play C and D, and then change the length to 4 and play E, type this: PLAY "t150 o3 L8 c d L4 e" PRINT USING Suppose you want to add $12.47 to $1.03. The correct answer is $13.50. This almost works: PRINT 12.47 + 1.03 It makes the computer print: 13.5 But instead of 13.5, we should try to make the computer print 13.50. This command forces the computer to print 13.50: PRINT USING "##.##"; 12.47 + 1.03 The “##.##” is called the picture or image or format: it says to print two characters, then a decimal point, then two digits. The computer will print: 13.50 This command puts that answer into a sentence: PRINT USING "You spent ##.## at our store"; 12.47 + 1.03 The computer will print: You spent 13.50 at our store Rounding This program makes the computer divide 300 by 7 but round the answer to two decimal places: CLS PRINT USING "##.##"; 300 / 7 When the computer divides 300 by 7, it gets 42.85714, but the format rounds the answer to 42.86. The computer will print: 42.86 Multiple numbers Every format (such as “###.##”) is a string. You can replace the format by a string variable: CLS a$ = "###.##" PRINT USING a$; 247.91 PRINT USING a$; 823 PRINT USING a$; 7 PRINT USING a$; 5 PRINT USING a$; 80.3 The computer will print: 247.91 823.00 7.00 5.00 80.30 When the computer prints that column of numbers, notice that the computer prints the decimal points underneath each other so that they line up. So to make decimal points line up, say PRINT USING instead of just PRINT. To print those numbers across instead of down, say this: PRINT USING "###.##"; 247.91; 823; 7; 5; 80.3 It makes the computer print 247.91, then 823.00, etc., like this: 247.91823.00 7.00 5.0080.30 Since the computer prints those numbers so close together, they’re hard to read. To make the computer insert extra space between the numbers, widen the format by putting a fourth “#” before the decimal point: PRINT USING "####.##"; 247.91; 823; 7; 5; 80.3 Then the computer will print: 247.91 823.00 7.00 5.00 80.30 If you say — PRINT USING "My ## pals drank ###.# pints of gin"; 24; 983.5 the computer will print: My 24 pals drank 983.5 pints of gin Oversized numbers Suppose you say: PRINT USING "###.##"; 16238.7 The computer tries to print 16238.7 by using the format “###.##”. But since that format allows just three digits before the decimal point, the format isn’t large enough to fit 16238.7. So the computer must disobey the format. But the computer also prints a percent sign, which means, “Warning! I am disobeying you!” Altogether, the computer prints: %16238.70 Final semicolon At the end of the PRINT USING statement, you can put a semicolon: CLS PRINT USING "##.##"; 13.5; PRINT "credit" Line 2 makes the computer print 13.50. The semicolon at the end of line 2 makes the computer print “credit” on the same line, like this: 13.50credit Advanced formats Suppose you’re running a highrisk business. On Monday, your business runs badly: you lose $27,931.60, so your “profit” is minus $27,931.60. On Tuesday, your business does slightly better than breakeven: your net profit for the day is $8.95. Let’s make the computer print the word “profit”, then the amount of your profit (such as $27,931.60 or $8.95), then the word “ha” (because you’re cynical about how your business is going). You can do that printing in several ways. Let’s explore them.… If you say — CLS a$ = "profit######.##ha" PRINT USING a$; 27931.6 PRINT USING a$; 8.95 the computer will print: profit27931.60ha profit 8.95ha If you change the format to “profit###,###.##ha”, the computer will insert a comma if the number is large: profit27,931.60ha profit 8.95ha If you change the format to “profit+#####.##ha”, the computer will print a plus sign in front of any positive number: profit27931.60ha profit +8.95ha To print a negative number, the computer normally prints a minus sign before the number. That’s called a leading minus. You can make the computer put the minus sign after the number instead; that’s called a trailing minus. For example, if you change the format to “profit######.##ha”, the computer will print a minus sign AFTER a negative number (and no minus after a positive number), like this: profit27931.60ha profit 8.95 ha Normally, a format begins with ##. If you begin with $$ instead (like this: “profit$$#####.##ha”), the computer will print a dollar sign before the digits: profit$27931.60ha profit $8.95ha If you begin with ** (like this: “profit**#####.##ha”), the computer will print asterisks before the number: profit*27931.60ha profit******8.95ha If you begin with **$ (like this: “profit**$#####.##ha”), the computer will print asterisks and a dollar sign: profit*$27931.60ha profit******$8.95ha When you’re printing a paycheck, use the asterisks to prevent the employee from enlarging his salary. Since the asterisks protect the check from being altered, they’re called check protection. You can combine several techniques into a single format. For example, you can combine the comma, the trailing minus, and the **$ (like this: “profit**$##,###.##ha”), so that the computer will print: profit**$27,931.60ha profit*******$8.95 ha If you change the format to “profit##.#####^^^^ha”, the computer will print numbers by using E notation: profit2.79316E+04ha profit 8.95000E+00ha Fancy calculations You can do fancy calculations — easily! Exponents Try typing this program: CLS PRINT 4 ^ 3 To type the symbol ^, do this: while holding down the SHIFT key, tap this key: ┌───┐ │ ^ │ │ 6 │ └───┘ That symbol (^) is called a caret. In that program, the
“4 ^ 3” makes the computer use the number 4, three times. The
computer will multiply together those three 4’s, like this: 4 times 4 times 4.
Since 64 In the expression “4 ^ 3”, the 4 is called the base; the 3 is called the exponent. Here’s another example: CLS PRINT 10 ^ 6 The “10 ^ 6” makes the computer use the number 10, six
times. The computer will multiply together those six 10’s (like this: 1000000 Here’s another example: CLS PRINT 3 ^ 2 The “3 ^ 2” makes the computer use the number 3, two
times. The computer will multiply together those two 3’s (like this: 9 Order of operations The symbols +, , *, /, and ^ are all called operations. To solve a problem, the computer uses the threestep process taught in algebra and the “new math”. For example, suppose you say: PRINT 70  3 ^ 2 + 8 / 2 * 3 The computer will not begin by subtracting 3 from 70; instead, it will use the threestep process: The problem is 70  3 ^ 2 + 8 / 2 * 3
Step 1: get rid of ^. Now the problem is 70  9 + 8 / 2 * 3
Step 2: get rid of * and /. Now the problem is 70  9 + 12
Step 3: get rid of + and . The answer is 73 In each step, it looks from left to right. For example, in step 2, it sees / and gets rid of it before it sees *. Speed Though exponents are fun, the computer handles them slowly. For example, the computer handles 3 ^ 2 slower than 3 * 3. So for fast calculations, say 3 * 3 instead of 3 ^ 2. Square roots What positive number, when multiplied by itself, gives 9? The answer is 3, because 3 times itself is 9. 3 squared is 9. 3 is called the square root of 9. To make the computer deduce the square root of 9, type this: PRINT SQR(9) The computer will print 3. When you tell the computer to PRINT SQR(9), make sure you put the parentheses around the 9. The symbol SQR is called a function. The number in parentheses (9) is called the function’s input (or argument or parameter). The answer, which is 3, is called the function’s output (or value). SQR(9) gives the same answer as 9 ^ .5. The computer handles SQR(9) faster than 9 ^ .5. Cube roots What number, when multiplied by itself and then multiplied by itself again, gives 64? The answer is 4, because 4 times 4 times 4 is 64. The answer (4) is called the cube root of 64. Here’s how to make the computer find the cube root of 64: PRINT 64 ^ (1 / 3) The computer will print 4. EXP The letter “e” stands for a special number, which is approximately 2.718281828459045. You can memorize that number easily, if you pair the digits: 2.7 18 28 18 28 45 90 45 That weird number is important in calculus, radioactivity, biological growth, and other areas of science. It’s calculated by this formula: 1 1 1 1 1 x e = 1 + + + + + + . . . 1 1*2 1*2*3 1*2*3*4 1*2*3*4*5 Therefore: 1 1 1 1 x e = 1 + 1 + + + + + . . . 2 6 24 120 EXP(x) means e^{x}. For example, EXP(3) means e^{3}, which is e * e * e, which is: 2.718281828459045 * 2.718281828459045 * 2.718281828459045 EXP(4) means e^{4}, which is e * e * e * e. EXP(3.1) means e^{3.1}, which is more than e^{3} but less than e^{4}. Here’s a practical application. Suppose you put $800 in a savings account, and the bank promises to give you 5% annual interest “compounded continuously”. How much money will you have at the end of the year? The answer is 800 * EXP(.05). Logarithms Here are some powers of 2: x 2^{x} 1 2 2 4 3 8 4 16 5 32 6 64 To compute the logarithmbase2 of a number, find the number in the righthand column; the answer is in the left column. For example, the logarithmbase2 of 32 is 5. The logarithmbase2 of 15 is slightly less than 4. The logarithmbase2 of 64 is 6. That fact is written: log_{2} 64 is 6 It’s also written: log 64 is 6 log 2 To make the computer find the logarithmbase2 of 64, say: PRINT LOG(64) / LOG(2) The computer will print 6. Here are some powers of 10: x 10^{x} 1 10 2 100 3 1000 4 10000 5 100000 The logarithmbase10 of 100000 is 5. The logarithmbase10 of 1001 is slightly more than 3. The logarithmbase10 of 10000 is 4. That fact is written: log_{10} 10000 is 4 It’s also written: log 10000 is 4 log 10 To make the computer do that calculation, say: PRINT LOG(10000) / LOG(10) The computer will print 4. The logarithmbase10 is called the common logarithm. That’s the kind of logarithm used in high school and chemistry. So if a chemistry book says to find the logarithm of 10000, the book means the logarithmbase10 of 10000, which is LOG(10000) / LOG(10). What happens if you forget the base, and say just LOG(10000) instead of LOG(10000) / LOG(10)? If you say just LOG(10000), the computer will find the natural logarithm of 10000, which is log_{e} 10000 (where e is 2.718281828459045), which isn’t what your chemistry book wants. Contrasts The computer’s notation resembles that of arithmetic and algebra, but beware of these contrasts.… Multiplication To make the computer multiply, you must type an asterisk: Traditional notation Computer notation 2n 2 * n 5(n+m) 5 * (n + m) nm n * m Exponents Put an exponent in parentheses, if it contains an operation: Traditional notation Computer notation x^{n+2} x ^ (n + 2) x^{3n} x ^ (3 * n) 5^{2/3} 5 ^ (2 / 3) ^{ 4} 2^{3} 2 ^ (3 ^ 4) Fractions Put a fraction’s numerator in parentheses, if it contains addition or subtraction: Traditional notation Computer notation a+b (a + b) / c c k20 (k  20) / 6 6 Put a denominator in parentheses, if it contains addition, subtraction, multiplication, or division: Traditional notation Computer notation 5 x 5 / (3 + x) 3+x 5a^{3} 5 * a ^ 3 / (4 * b) 4b Mixed numbers A mixed number is a number that contains a fraction. For example, 9½ is a mixed number. When you write a mixed number, put a plus sign before its fraction: Traditional notation Computer notation 9½ 9 + 1 / 2 If you’re using the mixed number in a further calculation, put the mixed number in parentheses: Traditional notation Computer notation 7  2¼ 7  (2 + 1 / 4) Clock The computer has a builtin clock/calendar. Setting the date & time To set the date to January 24, 1996, you can run this program — CLS DATE$ = "01241996" or give this DOS command (after leaving QBASIC): C:\>date 01241996 To set the time to 7 seconds after 1:45PM, you can run this program — CLS TIME$ = "13:45:07" or give this DOS command: C:\>time 13:45:07 Printing the date & time After you’ve set the date & time, the computer’s clock/calendar will try to keep track of the date & time for you. Then whenever you want to find out the current date & time, run this program: CLS PRINT DATE$ PRINT TIME$ If you say — PRINT TIMER the computer will tell you how many seconds have elapsed since midnight. This program makes the computer print the DATE$, TIME$, and TIMER across the top of your screen: CLS PRINT DATE$, TIME$, TIMER The top of your screen will look like this: 07291996 18:07:04 65223.85 The following program makes the computer look at the clock (and tell you the TIME$), then look at the clock again and tell you the new TIME$, then look at the clock again and tell you the new TIME$, etc.: CLS DO PRINT TIME$ LOOP For example, if the time starts at 18:07:04 (and eventually changes to 18:07:05 and then 18:07:06), the screen will look like this: 18:07:04 18:07:04 18:07:04 18:07:05 18:07:05 18:07:05 18:07:05 18:07:05 18:07:06 18:07:06 etc. The program will continue telling you the time until you abort the program. Clock battery The typical computer contains a little battery, called a clock battery. While the computer is unplugged from the wall (or the computer’s main power switch is turned off), the clock battery continually sneaks enough electricity to the clock/calendar chips to keep them running, so they keep updating the date & time. After several months or years, the battery will run out, and the chips will forget what the date & time are. Replace the battery, then reset the date & time. Test your computer’s speed How fast can your computer print the numbers from 1 to 1000? (The answer depends on the speed of your computer’s CPU chip, video card, and other components.) This program makes the computer print all the numbers from 1 to 1000, then brag about how fast it printed them: CLS starting.time = TIMER FOR i = 1 TO 1000 PRINT i NEXT elapsed.time = TIMER  starting.time PRINT "The elapsed time is"; elapsed.time; "seconds." Line 2 makes the computer look at the clock’s TIMER and call that time the starting.time. The FOR..NEXT loop makes the computer print all the numbers from 1 to 1000. The line underneath (elapsed.time = TIMER  starting.time) makes the computer look at the clock’s TIMER again, notice how different it is from the starting.time, and call the difference the elapsed.time. The bottom line makes the computer print how much time elapsed. For example, my 386SX16 computer usually prints: The elapsed time is 7.421875 seconds. My 486DX266 computer is faster and usually prints: The elapsed time is 1.976563 seconds. How fast is your computer? Try running the program several times. Sometimes you might get slightly different answers, since the TIMER isn’t very accurate. For a different speed test, make the computer count up to 10000 instead of 1000. That makes the computer take about 10 times as long. Try putting a semicolon at the end of the PRINT i line. That lets the computer print faster, since the computer no longer has to press the ENTER key after each number. Try omitting the PRINT i line altogether, so the computer can just think about the numbers without bothering to print them. That lets the computer finish the program much faster. It tests how fast the CPU can think, rather than how fast the video circuitry can display printed answers. Midnight problem At midnight, TIMER is 0. At 1 second after midnight, TIMER is 1. At 2 seconds after midnight, TIMER is 2. Since there are 60 seconds in a minute, 60 minutes in an hour, and 24 hours in a day, there are 86400 seconds in a day. At 1 second before midnight, TIMER is “86400 minus 1”, which is 86399; but when midnight strikes, TIMER becomes 0 again. To compute elapsed.time, you normally take the current time (TIMER) and subtract the starting.time: elapsed.time = TIMER  starting.time That formula works if TIMER is a bigger number than starting.time. But suppose a program starts running just before midnight and ends just after midnight. Since the starting.time is nearly 86400 and the TIMER (current time) is just slightly bigger than 0, the formula “TIMER  starting.time” gives a negative number, which is not the correct calculation for elapsed.time, since elapsed.time cannot be negative! Here’s how to correct the definition of elapsed.time. Instead of giving this oneline definition — elapsed.time = TIMER  starting.time give this twoline definition: elapsed.time = TIMER  starting.time IF elapsed.time < 0 THEN elapsed.time = elapsed.time + 86400 So the program to test your program’s speed should be: CLS starting.time = TIMER FOR i = 1 TO 1000 PRINT i NEXT elapsed.time = TIMER  starting.time IF elapsed.time < 0 THEN elapsed.time = elapsed.time + 86400 PRINT "The elapsed time is"; elapsed.time; "seconds" If you omit the shaded line, the program will work usually, but not at midnight. The typical novice programmer forgets to insert that line, thinks the program works fine without it, and gets surprised years later by a midnight phone call from an upset user wondering why the computer reports that the elapsed time is a negative number. LOOP UNTIL This program prints the letter “x” repeatedly, for .3 seconds: CLS starting.time = TIMER DO PRINT "x"; elapsed.time = TIMER  starting.time IF elapsed.time < 0 THEN elapsed.time = elapsed.time + 86400 LOOP UNTIL elapsed.time >= .3 Line 2 makes the computer look at the clock’s TIMER and call that time the starting.time. The PRINT line makes the computer print an “x”. The other indented lines compute the elapsed.time. The bottom line says: do the loop again and again, until the elapsed time is at least .3. So that program makes the computer print x’s for about .3 seconds. Experiment! Run that program, and see how many x’s your computer can print in .3 seconds. If you run that program several times, you’ll get slightly different answers, since the TIMER isn’t very accurate. In the bottom line, try changing the .3 to a different number, to see how many x’s your computer can print in a different amount of time. Even if you replace the .3 by a tiny number, the computer will print at least one x, since the computer does the PRINT line before encountering the definition of elapsed.time and the LOOP condition. Pause loop This program makes the computer print “I’m going to take a nap”, then pause for 5 seconds, then print “Now I woke up”: CLS PRINT "I'm going to take a nap" SLEEP 5 PRINT "Now I woke up" This fancier program accomplishes the same goal: CLS PRINT "I'm going to take a nap" starting.time = TIMER DO elapsed.time = TIMER  starting.time IF elapsed.time < 0 THEN elapsed.time = elapsed.time + 86400 LOOP UNTIL elapsed.time >= 5 PRINT "Now I woke up" Line 2 makes the computer print “I’m going to take a nap”. The next line (starting.time = TIMER) makes the computer look at the clock’s TIMER and call that time the starting.time. The DO loop makes the computer look at the time repeatedly, until the elapsed.time is at least 5 seconds. After those 5 seconds of at of staring at the clock, the computer finally does the bottom line, which makes the computer print “Now I woke up”. Since the loop’s only purpose is to make the computer pause for 5 seconds, the loop is called a pause loop. The fancy program (which says LOOP UNTIL) has two advantages over the simple program (which says SLEEP): In the SLEEP program, if the human presses a key while the computer is SLEEPing, the computer wakes up immediately. In the LOOP UNTIL program, the computer ignores the human until 5 seconds have passed, so the LOOP UNTIL program ensures that the computer really DOES pause for 5 seconds. The only way the human can interrupt the computer’s pause loop is to abort the program (by pressing Ctrl with PAUSE/BREAK). In the LOOP UNTIL program, you can make the computer loop for 5.1 seconds instead of 5 seconds, by changing the 5 to 5.1. You can’t create a SLEEP program that sleeps for 5.1 seconds, since the SLEEP command prohibits decimals: if you try to say SLEEP 5.1, the computer will do SLEEP 5 instead. Here’s another way to make the computer take a nap: CLS PRINT "I'm going to take a nap" FOR i = 1 TO 50000: NEXT PRINT "Now I woke up" The FOR line makes the computer count up to 50000. Since the computer doesn’t print anything while counting, the FOR line acts as a pause. How long will the pause last? If your computer is very fast (a Pentium), the pause will last just a few seconds; if your computer is very slow (an 8088), counting to 50000 will take longer, and the pause will last many seconds. How long will your computer pause? Experiment! If you want the computer to pause for 3 seconds, raise or lower the number 50000 until the pause takes 3 seconds. If you someday buy a faster computer, to keep the 3second pause you must raise the number in the FOR line. Stripping Sometimes the computer prints too much info: you wish the computer would print less, to save yourself the agony of reading excess info irrelevant to your needs. Whenever the computer prints too much info about a numerical answer, use ABS, FIX, INT, CINT, or SGN. ABS removes any minus sign. For example, the ABS of 3.89 is 3.89. So if you say PRINT ABS(3.89), the computer will print just 3.89. FIX removes any digits after the decimal point. For example, the FIX of 3.89 is 3. So if you say PRINT FIX(3.89), the computer will print just 3. The FIX of 3.89 is 3. CINT rounds to the NEAREST integer. For example, the CINT of 3.89 is 4; the CINT of 3.89 is 4. INT rounds the number DOWN to an integer that’s LOWER. For example, the INT of 3.89 is 3 (because 3 is an integer that’s lower than 3.89); the INT of 3.89 is 4 (because 4 is lower than 3.89). SGN removes ALL the digits and replaces them with a 1 — unless the number is 0. For example, the SGN of 3.89 is 1. The SGN of 3.89 is 1. The SGN of 0 is just 0. ABS, FIX, CINT, INT, and SGN are all called stripping functions or strippers or diet functions or diet pills, because they strip away the number’s excess fat and reveal just the fundamentals that interest you. Here are more details about those five functions.… ABS To find the absolute value of a negative number, just omit the number’s minus sign. For example, the absolute value of 7 is 7. The absolute value of a positive number is the number itself. For example, the absolute value of 7 is 7. The absolute value of 0 is 0. To make the computer find the absolute value of 7, type this: PRINT ABS(7) The computer will print: 7 Like SQR, ABS is a function: you must put parentheses after the ABS. Since ABS omits the minus sign, ABS turns negative numbers into positive numbers. Use ABS whenever you insist that an answer be positive. For example, ABS helps solve math & physics problems about “distance”, since the “distance” between two points is always a positive number and cannot be negative. This program computes the distance between two numbers: CLS PRINT "I will find the distance between two numbers." INPUT "What's the first number"; x INPUT "What's the second number"; y PRINT "The distance between those numbers is"; ABS(x  y) When you run that program, suppose you say that the first number is 4 and the second number is 7. Since x is 4, and y is 7, the distance between those two numbers is ABS(4  7), which is ABS(3), which is 3. If you reverse those two numbers, so that x is 7 and y is 4, the distance between them is ABS(7  4), which is ABS(3), which is still 3. FIX An integer is a number that has no decimal point. For example, these are integers: 17, 238, 0, and 956. If a number contains a decimal point, the simplest way to turn the number into an integer is to delete all the digits after the decimal point. That’s called the FIX of the number. For example, the FIX of 3.89 is 3. So if you say PRINT FIX (3.89), the computer will print just 3. The FIX of 3.89 is 3. The FIX of 7 is 7. The FIX of 0 is 0. CINT A more sophisticated way to turn a number into an integer is to round the number to the nearest integer. That’s called CINT (which means “Convert to INTeger”). For example, the CINT of 3.9 is 4 (because 3.9 is closer to 4 than to 3). Like FIX, CINT deletes all the digits after the decimal point; but if the digit just after the decimal point is 5, 6, 7, 8, or 9, CINT “rounds up” by adding 1 to the digit before the decimal point. Here are more examples: CINT(3.9) is 4 CINT(3.9) is 4 CINT(3.1) is 3 CINT(3.1) is 3 CINT(3.5) is 4 CINT(3.5) is 4 The highest number CINT can produce is 32767. If you try to go higher than 32767 or lower than 32768, the computer will gripe by saying “Overflow”. To explore the mysteries of rounding, run this program: CLS INPUT "What's your favorite number"; x PRINT CINT(x) In that program, the INPUT line asks you to type a number x. The bottom line prints your number, but rounded to the nearest integer. For example, if you type 3.9, the bottom line prints 4. INT Like FIX and CINT, INT turns a number into an integer. Though INT is slightly harder to understand than FIX and CINT, INT is more useful! INT rounds a number down to an integer that’s lower. For example: The INT of 3.9 is 3 (because 3 is an integer that’s lower than 3.9). The INT of 3.9 is 4 (because a temperature of 4 is lower and colder than a temperature of 3.9). The INT of 7 is simply 7. To explore further the mysteries of rounding, run this program: CLS INPUT "What's your favorite number"; x PRINT "Your number rounded down is"; INT(x) PRINT "Your number rounded up is"; INT(x) PRINT "Your number rounded to the nearest integer is"; INT(x + .5) In that program, the INPUT line asks you to type a number x. The next line prints your number rounded down. For example, if you input 3.9, the computer prints 3. The next line, PRINT INT(x), prints your number rounded up. For example if you input 3.9, the computer prints 4. The bottom line prints your number rounded to the nearest integer. For example, if you input 3.9, the computer will print 4. Here’s the rule: if x is a number, INT(x) rounds x down; INT(x) rounds x up; INT(x + .5) rounds x to the nearest integer. Here’s why INT is usually better than CINT and FIX: To round x to the nearest integer, you can say either CINT(x) or INT(x + .5). Alas, CINT(x) handles just numbers from 32768 to 32767. But INT(x + .5) can handle any number! Another advantage of INT is that it works in all versions of BASIC. Even the oldest, most primitive versions of BASIC understand INT. Alas, CINT and FIX work in just a few versions of BASIC, such as QBASIC. To make sure your programs work on many computers, use INT rather than CINT or FIX. In the rest of this book, I’ll emphasize INT. Rounding down and rounding up are useful in the supermarket: Suppose some items are marked “30¢ each”, and you have just two dollars. How many can you buy? Two dollars divided by 30¢ is 6.66667; rounding down to an integer, you can buy 6. Suppose some items are marked “3 for a dollar”, and you want to buy just one of them. How much will the supermarket charge you? One dollar divided by 3 is 33.3333¢; rounding up to an integer, you will be charged 34¢. By using INT, you can do fancier kinds of rounding: to round x to the nearest thousand, ask for INT(x / 1000 + .5) * 1000 to round x to the nearest thousandth, ask for INT(x / .001 + .5) * .001 This program rounds a number, so that it will have just a few digits after the decimal point: CLS INPUT "What's your favorite number"; x INPUT "How many digits would you like after its decimal point"; d b = 10 ^ d PRINT "Your number rounded is"; INT(x / b + .5) * b Here’s a sample run: What's your favorite number? 4.28631 How many digits would you like after its decimal point? 2 Your number rounded is 4.29 SGN If a number is negative, its sign is 1. For example, the sign of 546 is 1. If a number is positive, its sign is +1. For example the sign of 8231 is +1. The sign of 0 is 0. The computer’s abbreviation for “sign” is “SGN”. So if you say — PRINT SGN(546) the computer will print the sign of 546; it will print 1. If you say — PRINT SGN(8231) the computer will print the sign of 8231; it will print 1. If you say — PRINT SGN(0) the computer will print the sign of 0; it will print 0. SGN is the opposite of ABS. Let’s see what both functions do to 7.2. ABS removes the minus sign, but leaves the digits: ABS(7.2) is 7.2 SGN removes the digits, but leaves the minus sign: SGN(7.2) is 1 The Latin word for sign is signum. Most mathematicians prefer to talk in Latin — they say “signum” instead of “sign” — because the English word “sign” sounds too much like the trigonometry word “sine”. So mathematicians call SGN the signum function. Random numbers Usually, the computer is predictable: it does exactly what you say. But sometimes, you want the computer to be unpredictable. For example, if you’re going to play a game of cards with the computer and tell the computer to deal, you want the cards dealt to be unpredictable. If the cards were predictable — if you could figure out exactly which cards you and the computer would be dealt — the game would be boring. In many other games too, you want the computer to be unpredictable, to “surprise” you. Without an element of surprise, the game would be boring. Being unpredictable increases the pleasure you derive from games — and from art. To make the computer act artistic, and create a new original masterpiece that’s a “work of art”, you need a way to make the computer get a “flash of inspiration”. Flashes of inspiration aren’t predictable: they’re surprises. Here’s how to make the computer act unpredictably.… RND is a RaNDom decimal, bigger than 0 and less than 1. For example, it might be .6273649 or .9241587 or .2632801. Every time your program mentions RND, the computer concocts another decimal: CLS PRINT RND PRINT RND PRINT RND The computer prints: .7055475 .533424 .5795186 The first time your program mentions RND, the computer chooses its favorite decimal, which is .7055475. Each succeeding time your program mentions RND, the computer uses the previous decimal to concoct a new one. It uses .7055475 to concoct .533424, which it uses to concoct .5795186. The process by which the computer concocts each new decimal from the previous one is weird enough so we humans cannot detect any pattern. This program prints lots of decimals — and pauses a second after each decimal, so you have a chance to read it: CLS DO PRINT RND SLEEP 1 LOOP About half the decimals will be less than .5, and about half will be more than .5. Most of the decimals will be less than .9. In fact, about 90% will be. About 36% of the decimals will be less than .36; 59% will be less than .59; 99% will be less than .99; 2% will be less than .02; a quarter of them will be less than .25; etc. You might see some decimal twice, though most of the decimals will be different from each other. When you get tired of running that program and seeing decimals, abort the program (by pressing Ctrl with PAUSE/BREAK). If you run that program again, you’ll get exactly the same list of decimals again, in the same order. RANDOMIZE TIMER If you’d rather see a different list of decimals, say RANDOMIZE TIMER at the beginning of the program: CLS RANDOMIZE TIMER DO PRINT RND SLEEP 1 LOOP When the computer sees RANDOMIZE TIMER, the computer looks at the clock and manipulates the time’s digits to produce the first value of RND. So the first value of RND will be a number that depends on the time of day, instead of the usual .7055475. Since the first value of RND will be different than usual, so will the second, and so will the rest of the list. Every time you run the program, the clock will be different, so the first value of RND will be different, so the whole list will be different — unless you run the program at exactly the same time the next day, when the clock is the same. But since the clock is accurate to a tiny fraction of a second, the chance of hitting the same time is extremely unlikely. Love or hate? Who loves ya, baby? This program tries to answer that question: CLS RANDOMIZE TIMER DO INPUT "Type the name of someone you love..."; name$ IF RND < .67 THEN PRINT name$; " loves you, too" ELSE PRINT name$; " hates your guts" END IF LOOP The RANDOMIZE TIMER line makes the value of RND depend on the clock. The INPUT line makes the computer wait for the human to type a name. Suppose he types Suzy. Then name$ is “Suzy”. The IF line says there’s a 67% chance that the computer will print “Suzy loves you, too”, but there’s a 33% chance the computer will instead print “Suzy hates your guts”. The words DO and LOOP make the computer do the routine again and again, until the human aborts the program. The run might look like this: Type the name of someone you love...? Suzy Suzy loves you, too Type the name of someone you love...? Joan Joan hates your guts Type the name of someone you love...? Alice Alice loves you, too Type the name of someone you love...? Fred Fred loves you, too Type the name of someone you love...? Uncle Charlie Uncle Charlie hates your guts Coin flipping This program makes the computer flip a coin: CLS RANDOMIZE TIMER IF RND < .5 THEN PRINT "heads" ELSE PRINT "tails" The IF line says there’s a 50% chance that the computer will print “heads”; if the computer does not print “heads”, it will print “tails”. Until you run the program, you won’t know which way the coin will flip; the choice is random. Each time you run the program, the computer will flip the coin again; each time, the outcome is unpredictable. Here’s how to let the human bet on whether the computer will say “heads” or “tails”: CLS RANDOMIZE TIMER 10 INPUT "Do you want to bet on heads or tails"; bet$ IF bet$ <> "heads" AND bet$ <> "tails" THEN PRINT "Please say heads or tails" GOTO 10 END IF IF RND < .5 THEN coin$ = "heads" ELSE coin$ = "tails" PRINT "The coin says "; coin$ IF coin$ = bet$ THEN PRINT "You win" ELSE PRINT "You lose" The line numbered 10 makes the computer ask: Do you want to bet on heads or tails? The next line makes sure the human says “heads” or “tails”: if the human’s answer isn’t “heads” and isn’t “tails”, the computer gripes. The bottom three lines make the computer flip a coin and determine whether the human won or lost the bet. Here’s a sample run: Do you want to bet on heads or tails? heads The coin says tails You lose Here’s another: Do you want to bet on heads or tails? tails The coin says tails You win Here’s another: Do you want to bet on heads or tails? tails The coin says heads You lose Here’s how to let the human use money when betting: CLS RANDOMIZE TIMER bankroll = 100 4 PRINT "You have"; bankroll; "dollars" 5 INPUT "How many dollars do you want to bet"; stake IF stake > bankroll THEN PRINT "You don't have that much! Bet less!": GOTO 5 IF stake < 0 THEN PRINT "You can't bet less than nothing!": GOTO 5 IF stake = 0 THEN PRINT "I guess you don't want to bet anymore": GOTO 20 10 INPUT "Do you want to bet on heads or tails"; bet$ IF bet$ <> "heads" AND bet$ <> "tails" THEN PRINT "Please say heads or tails" GOTO 10 END IF IF RND < .5 THEN coin$ = "heads" ELSE coin$ = "tails" PRINT "The coin says "; coin$ IF coin$ = bet$ THEN PRINT "You win"; stake; "dollars" bankroll = bankroll + stake GOTO 4 END IF PRINT "You lose"; stake; "dollars" bankroll = bankroll  stake IF bankroll > 0 THEN GOTO 4 PRINT "You're broke! Too bad!" 20 PRINT "Thanks for playing with me! You were fun to play with!" PRINT "I hope you play again sometime!" Line 3 (bankroll = 100) gives the human a $100 bankroll, so the human starts with $100. The next line makes the computer say: You have 100 dollars The line numbered 5 makes the computer ask: How many dollars do you want to bet? The number that the human inputs (the number of dollars that the human bets) is called the human’s stake. The next three lines (which say “IF stake”) make sure the stake is reasonable. The line numbered 10 gets the human to bet on heads or tails. The next few lines flip the coin, determine whether the human won or lost the bet, and then send the computer back to line 4 for another round (if the human isn’t broke yet). The bottom three lines say goodbye to the human. Here’s a sample run: You have 100 dollars How many dollars do you want to bet? 120 You don't have that much! Bet less! How many dollars do you want to bet? 75 Do you want to bet on heads or tails? heads The coin says tails You lose 75 dollars You have 25 dollars How many dollars do you want to bet? 10 Do you want to bet on heads or tails? tails The coin says tails You win 10 dollars You have 35 dollars How many dollars do you want to bet? 35 Do you want to bet on heads or tails? tails The coin says heads You lose 35 dollars You're broke! Too bad! Thanks for playing with me! You were fun to play with! I hope you play again sometime! To make the output prettier, replace line 4 by this group of lines: 4 PRINT PRINT "You have"; bankroll; "dollars! Here they are:" FOR i = 1 TO bankroll PRINT "$"; NEXT Now the run looks like this: You have 100 dollars! Here they are: $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$$ How many dollars do you want to bet? 120 You don't have that much! Bet less! How many dollars do you want to bet? 75 Do you want to bet on heads or tails? heads The coin says tails You lose 75 dollars
You have 25 dollars! Here they are: $$$$$$$$$$$$$$$$$$$$$$$$$ How many dollars do you want to bet? 10 Do you want to bet on heads or tails? tails The coin says tails You win 10 dollars
You have 35 dollars! Here they are: $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ How many dollars do you want to bet? 35 Do you want to bet on heads or tails? tails The coin says heads You lose 35 dollars You're broke! Too bad! Thanks for playing with me! You were fun to play with! I hope you play again sometime! Random integers If you want a random integer from 1 to 100, ask for 1 + INT(RND * 100). Here’s why: RND is a decimal, bigger than 0 and less than 1. So RND * 10 is a decimal, bigger than 0 and less than 10. So INT(RND * 10) is an integer, at least 0 and no more than 9. So 1 + INT(RND * 10) is an integer, at least 1 and no more than 10. Guessing game This program plays a guessing game: CLS RANDOMIZE TIMER PRINT "I'm thinking of a number from 1 to 10." computer.number = 1 + INT(RND * 10) 10 INPUT "What do you think my number is"; guess IF guess < computer.number THEN PRINT "Your guess is too low.": GOTO 10 IF guess > computer.number THEN PRINT "Your guess is too high.": GOTO 10 PRINT "Congratulations! You found my number!" Line 3 makes the computer say: I'm thinking of a number from 1 to 10. The next line makes the computer think of a random number from 1 to 10; the computer’s number is called “computer.number”. The INPUT line asks the human to guess the number. If the guess is less than the computer’s number, the first IF line makes the computer say “Your guess is too low” and then GOTO 10, which lets the human guess again. If the guess is greater than the computer’s number, the bottom IF line makes the computer say “Your guess is too high” and then GOTO 10. When the human guesses correctly, the computer arrives at the bottom line, which prints: Congratulations! You found my number! Here’s a sample run: I'm thinking of a number from 1 toO 10. What do you think my number is? 3 Your guess is too low. What do you think my number is? 8 Your guess is too high. What do you think my number is? 5 Your guess is too low. What do you think my number is? 6 Congratulations! You found my number! Dice This program makes the computer roll a pair of dice: CLS RANDOMIZE TIMER PRINT "I'm rolling a pair of dice" a = 1 + INT(RND * 6) PRINT "One of the dice says"; a b = 1 + INT(RND * 6) PRINT "The other says"; b PRINT "The total is"; a + b Line 3 makes the computer say: I'm rolling a pair of dice Each of the dice has 6 sides. The next line, a = 1 + INT(RND * 6), rolls one of the dice, by picking a number from 1 to 6. The line saying “b = 1 + INT(RND * 6)” rolls the other. The bottom line prints the total. Here’s a sample run: I'm rolling a pair of dice One of the dice says 3 The other says 5 The total is 8 Here’s another run: I'm rolling a pair of dice One of the dice says 6 The other says 4 The total is 10 Daily horoscope This program predicts what will happen to you today: CLS RANDOMIZE TIMER PRINT "You will have a "; SELECT CASE 1 + INT(RND * 5) CASE 1 PRINT "wonderful"; CASE 2 PRINT "fairly good"; CASE 3 PRINT "soso"; CASE 4 PRINT "fairly bad"; CASE 5 PRINT "terrible"; END SELECT PRINT " day today!" The computer will say — You will have a wonderful day today! or — You will have a terrible day today! or some inbetween comment. That’s because the SELECT CASE line makes the computer pick a random integer from 1 to 5. For inspiration, run that program when you get up in the morning. Then notice whether your day turns out the way the computer predicts! Character codes Alt key Here’s how to type the symbol ñ, whose code number is 164. Hold down the Alt key; and while you keep holding down the Alt key, type 164 by using the numeric keypad (the number keys on the far right side of the keyboard). When you finish typing 164, lift your finger from the Alt key, and you’ll see ñ on your screen! The Alt key works reliably for most numbers in that chart but not for numbers 127 and 127. You can use the Alt key in your program. For example, try typing this program: CLS PRINT "In Spanish, tomorrow is mañana" While typing that program, make the symbol ¤ by typing 164 on the numeric keypad while holding down the Alt key. When you run that program, the computer will print: In Spanish, tomorrow is mañana CHR$ Here’s another way to type the symbol ñ: CLS PRINT CHR$(164) When you run that program, the computer will print the CHaRacter whose code number is 164. The computer will print: ñ This program makes the computer print “In Spanish, tomorrow is mañana”: CLS PRINT "In Spanish, tomorrow is ma"; CHR$(164); "ana" That PRINT line makes the computer print “In Spanish, tomorrow is ma”, then print character 164 (which is ñ), then print “ana”. Since character 34 is a quotation mark, this program prints a quotation mark: CLS PRINT CHR$(34) Suppose you want the computer to print: Scholars think "Hamlet" is a great play. To make the computer print the quotation marks around “Hamlet”, use CHR$(34), like this: CLS PRINT "Scholars think "; CHR$(34); "Hamlet"; CHR$(34); " is a great play." CHR$ works reliably for all numbers in that chart. This program prints, on your screen, all the symbols in the chart: CLS FOR i = 1 TO 6: PRINT CHR$(i);: NEXT PRINT CHR$(8); FOR i = 14 TO 27: PRINT CHR$(i);: NEXT FOR i = 33 TO 254: PRINT CHR$(i);: NEXT That chart shows most code numbers from 1 to 254 but skips the following mysterious code numbers: 7, 913, and 2832. Here’s what those mysterious code numbers do.… In a PRINT statement, CHR$(7) makes the computer beep. Saying — PRINT CHR$(7); has the same effect as saying: BEEP If you say — PRINT "hot"; CHR$(7); "dog" the computer will print “hot”, then beep, then turn the “hot” into “hotdog”. CHR$(9) makes the computer press the TAB key, so your writing is indented. For example, if you say — PRINT "hot"; CHR$(9); "dog" the computer will print “hot”, then indent by pressing the TAB key, then print “dog”, so you see this: hot dog CHR$(31) makes the computer move the cursor (the blinking underline) down to the line below. For example, if you say — PRINT "hot"; CHR$(31); "dog" the computer will print “hot”, then move down, then print “dog” on the line below, so you see this: hot dog You can move the cursor in all four directions: CHR$(28) moves the cursor toward the right CHR$(29) moves the cursor toward the left CHR$(30) moves the cursor up CHR$(31) moves the cursor down CHR$(11) moves the cursor all the way to the screen’s top left corner, which is called the home position. CHR$(32) is a blank space. It’s the same as “ ”. CHR$(12) erases the entire screen. Saying — PRINT CHR$(12); has the same effect as saying: CLS CHR$(10) and CHR$(13) each make the computer press the ENTER key. Printing on paper When printing onto paper, make your program’s bottom line say: LPRINT CHR$(12); That makes the printer eject the paper. Codes 33126 print on paper okay. As on the screen, code 32 prints a blank space. Other codes print okay on some printers but wrong on other printers. Experiment, and see which codes your printer can print correctly. If you want to print codes 128254 on a typical laser printer (such as a HewlettPackard Laserjet 2), put this line at the top of your program (just under the CLS): LPRINT CHR$(27); "(10U"; Type that line carefully. In the quotation marks, make sure you type just a single parenthesis, then the number 10, then a capital U. A typical dotmatrix printer (such as an Epson LQ570) normally prints 10 characters per inch. To make the characters thinner, so you get 17 characters per inch, say: LPRINT CHR$(15); To cancel that 17charactersperinch command, say: LPRINT CHR$(18); To make the characters wider, so you get 5 characters per inch, say: LPRINT CHR$(14); To cancel that command, say: LPRINT CHR$(20); ASC The code numbers from 32 to 126 are for characters that you can type on the keyboard easily. Established by a national committee, those code numbers are called the American Standard Code for Information Interchange, which is abbreviated ASCII, which is pronounced “ass key”. Programmers say, “the ASCII code number for A is 65”. If you say — PRINT ASC("A") the computer will print the ASCII code number for “A”. It will print: 65 If you say PRINT ASC(“B”), the computer will print 66. If you say PRINT ASC(“b”), the computer will print 97. If you say PRINT ASC(“ñ”), the computer will print 164 (which is the code number for ñ), even though ñ isn’t an ASCII character. String analysis Let’s analyze the word “smart”. Length Since “smart” has 5 characters in it, the length of “smart” is 5. If you say — PRINT LEN("smart") the computer will print the LENgth of “smart”; it will print: 5 Left, right, middle The left two characters of “smart” are “sm”. If you say — PRINT LEFT$("smart", 2) the computer will print: sm Try this program: CLS a$ = "smart" PRINT LEFT$(a$, 2) Line 2 says a$ is “smart”. The bottom line says to print the left 2 characters of a$, which are “sm”. The computer will print: sm If a$ is “smart”, here are the consequences.… LEN(a$) is the LENgth of a$. It is 5. LEFT$(a$, 2) is the LEFT 2 characters of a$. It is “sm”. RIGHT$(a$, 2) is the RIGHT 2 characters of a$. It is “rt”. MID$(a$, 2) begins in the MIDdle of a$, at the 2^{nd} character. It’s “mart”. MID$(a$, 2, 3) begins at 2^{nd} character and includes 3 characters. It’s “mar”. You can change the middle of a string, like this: CLS a$ = "bunkers" MID$(a$, 2) = "owl" PRINT a$ Line 2 says a$ is “bunkers”. The MID$ line changes the middle of a$ to “owl”; the change begins at the 2^{nd} character of a$. The bottom line prints: bowlers Here’s a variation: CLS a$ = "bunkers" MID$(a$, 2) = "ad agency" PRINT a$ Line 2 says a$ is “bunkers”. The MID$ line says to change the middle of a$, beginning at the 2^{nd} character of a$. But “ad agency” is too long to become part of “bunkers”. The computer uses as much of “ad agency” as will fit in “bunkers”. The computer will print: bad age Another variation: CLS a$ = "bunkers" MID$(a$, 2, 1) = "owl" PRINT a$ Line 2 says a$ is “bunkers”. The MID$ line says to change the middle of a$, beginning at the 2^{nd} character of a$. But the “,1” makes the computer use just 1 letter from “owl”. The bottom line prints: bonkers Capitals Capital letters (such as X, Y, and Z) are called uppercase letters. Small letters (such as x, y, and z) are called lowercase letters. If you say — PRINT UCASE$("We love America") the computer will print an uppercase (capitalized) version of “We love America”), like this: WE LOVE AMERICA If you say — PRINT LCASE$("We love America") the computer will print a lowercase version of “We love America”, like this: we love america Unfortunately, the computer doesn’t know how to capitalize an accented letter (such as ñ). For example, suppose you say: PRINT UCASE$("mañana") Since the computer doesn’t know how to capitalize the ¤, the computer prints: MAñANA If you say PRINT LCASE$(“MAÑANA”), the computer doesn’t know how to uncapitalize Ñ, so the computer prints: maÑana This program measures geographical emotions: CLS INPUT "What's the most exciting continent"; a$ IF a$ = "Africa" THEN PRINT "Yes, it's the dark continent!" ELSE PRINT "I disagree!" END IF Line 2 asks: What's the most exciting continent? Line 3 checks whether the person’s answer is “Africa”. If the person’s answer is “Africa”, the computer prints “Yes, it’s the dark continent!”; otherwise, the computer prints “I disagree!” But instead of typing “Africa”, what if the person types “africa” or “AFRICA”? We still ought to make the computer print “Yes, it’s the dark continent!” Here’s how: CLS INPUT "What's the most exciting continent"; a$ IF UCASE$(a$) = "AFRICA" THEN PRINT "Yes, it's the dark continent!" ELSE PRINT "I disagree!" END IF The new version of the IF statement says: if the person’s answer, after being capitalized, becomes “AFRICA”, then print “Yes, it’s the dark continent!” So the computer will print “Yes, it’s the dark continent!” even if the person types “Africa” or “africa” or “AFRICA” or “AfRiCa”. Suppose you ask the person a yes/no question. If the person means “yes”, the person might type “yes” or “Yes” or “YES” or “YES!” or just “y” or just “Y”. So instead of saying — IF a$ = "yes" say this: IF UCASE$(LEFT$(a$, 1)) = "Y" That tests whether the first letter of the person’s answer, after being capitalized, is “Y”. Trim Some folks accidentally press the SPACE bar at the beginning or end of a string. For example, instead of typing “Sue”, the person might type “ Sue” or “Sue “. You want to get rid of those accidental spaces. Getting rid of them is called trimming the string. The function LTRIM$ will lefttrim the string: it will delete any spaces at the string’s beginning (left edge). For example, if a$ is “ Sue Smith”, LTRIM$(a$) is “Sue Smith”. RTRIM$ will righttrim the string: it will delete any spaces at the string’s end (right edge). If a$ is “Sue Smith “, RTRIM$(a$) is “Sue Smith”. To trim both edges of a$ and make the trimmed result be the new a$, say this: a$ = LTRIM$(RTRIM$(a$)) Spaces at the string’s beginning (which are deleted by LTRIM$) are called leading spaces. Spaces at the string’s end (which are deleted by RTRIM$) are called trailing spaces. Adding strings You can add strings together, to form a longer string: CLS a$ = "fat" + "her" PRINT a$ Line 2 says a$ is “father”. The bottom line makes the computer print: father Searching in a string You can make the computer search in a string to find another string. To make the computer search IN the STRing “needed” to find “ed”, say: PRINT INSTR("needed", "ed") Since “ed” begins at the third character of “needed”, the computer will print: 3 If you say — PRINT INSTR("needed", "ey") the computer will search in the string “needed” for “ey”. Since “ey” is not in “needed”, the computer will print: 0 If you say — PRINT INSTR(4, "needed", "ed") the computer will hunt in the string “needed” for “ed”; but the hunt will begin at the 4th character of “needed”. The computer finds the “ed” that begins at the 5th character of “needed”. The computer will print: 5 Stringnumber conversion This program converts a string to a number: CLS a$ = "52.6" b = VAL(a$) PRINT b + 1 Line 2 says a$ is the string “52.6”. The next line says b is the numeric VALue of a$, so b is the number 52.6. The bottom line prints: 53.6 VAL converts a string to a number. The opposite of VAL is STR$, which converts a number to a string. For example, STR$(7.2) is the string “7.2”. STR$(81.4) is the string “ 81.4”, in which the 8 is preceded by a space instead of a minus sign. Repeating characters Suppose you love the letter b (because it stands for big, bold, and beautiful) and want to print “bbbbbbbbbbbbbbbbbbbb”. Here’s a shortcut: PRINT STRING$(20, "b") That tells the computer to print a string of 20 b’s. Here’s a different way to accomplish the same goal: PRINT STRING$(20, 98) That tells the computer to print, 20 times, the character whose ASCII code number is 98. STRING$ can make the computer repeat a single character, but not a whole word. So if you say STRING$(20, “blow”), the computer will not repeat the word “blow”; instead, the computer will repeat just the first character of “blow” (which is “b”). Let’s make the computer draw a dashed line containing 50 dashes, like this:  Here’s how: just say PRINT STRING$(50, “”). Let’s make the computer print this triangle: * ** *** **** ***** ****** ******* ******** ********* ********** *********** ************ ************* ************** *************** **************** ***************** ****************** ******************* ******************** To do that, we want the computer to print 1 asterisk on the first line, then 2 asterisks on the next line, then 3 asterisks on the next line, and so on, until it finally prints 20 asterisks on the bottom line. Here’s the program: CLS FOR i = 1 TO 20 PRINT STRING$(i, "*") NEXT The FOR line makes i be 1, then 2, then 3, and so on, up to 20. When i is 1, the PRINT line makes the computer print one asterisk, like this: * When i is 2, the PRINT line makes the computer print a line of 2 asterisks, like this: ** The FOR line makes i be every number from 1 up to 20, so computer will print 1 asterisk, then underneath print a line of 2 asterisks, then underneath print a line of 3 asterisks, and so on, until the entire triangle is printed. Trigonometry The study of triangles is called trigonometry — and the computer can do it for you! To find out the sine and cosine, you can use a ruler but a faster and more accurate way is to let the computer do it! Yes, the computer can calculate triangles in its mind! This program makes the computer measure the sine and cosine of 30°: CLS degrees = ATN(1) / 45 PRINT SIN(30 * degrees) PRINT COS(30 * degrees) Line 2 is a special formula that defines the word degrees. The first PRINT line prints the sine of 30 degrees: .5 The bottom line prints the cosine of 30°, which is a decimal that’s slightly less than .87. The computer can measure the sine and cosine of any size angle. Try it! For example, to make the computer print the sine and cosine of a 33° angle, say: CLS degrees = ATN(1) / 45 PRINT SIN(33 * degrees) PRINT COS(33 * degrees) If you choose an angle of 33° instead of 33°, the triangle will dip down instead of rising up, and so the sine will be a negative number instead of positive. In those PRINT lines, the “* degrees” is important: it tells the computer that you want the sine of 33 degrees. If you accidentally omit the “* degrees”, the computer will print the sine of 33 radians instead. (A radian is larger than a degree. A radian is about 57.3 degrees. More precisely, a radian is 180/p degrees.) Tangent The sine divided by the cosine is called the tangent. For example, to find the tangent of 33°, divide the sine of 33° by the cosine of 33°. To make the computer print the tangent of 33°, you could tell the computer to PRINT SIN(33 * degrees) / COS(33 * degrees). But to find the tangent more quickly and easily, just say PRINT TAN(33 * degrees). Arc functions The opposite of the tangent is called the arctangent: the tangent of 30° is about .58 the arctangent of .58is about 30° Similarly, the opposite of the sine is called the arcsine, and the opposite of the cosine is called the arccosine. This program prints the arctangent of .58, the arcsine of .5, and the arccosine of .87: CLS degrees = ATN(1) / 45 PRINT ATN(.58) / degrees x = .5: PRINT ATN(x / SQR(1  x * x)) / degrees x = .87: PRINT 90  ATN(x / SQR(1  x * x)) / degrees Line 3 prints the arctangent of .58, in degrees. (If you omit the “/ degrees”, the computer will print the answer in radians instead of degrees.) Line 4 sets x equal to .5 and then prints its arcsine (by using a formula that combines ATN with SQR). The bottom line sets x equal to .87 and then prints its arccosine (by using a formula that combines 90 with ATN and SQR). The answer to each of the three problems is about 30 degrees. Types of numbers QBASIC can handle several types of numbers. General rules Here are the general rules about types of numbers. I’ll explain exceptions later. Real numbers versus integers: If a number contains a decimal point, it’s called a real number. For example, 27.1 is a real number. So is 27.1. So is 27.0. A number without a decimal point is called an integer. For example, 27 is an integer. So is 27. 27.0 is not an integer, since it contains a decimal point; 27.0 is a real number instead. The computer handles integers faster than real numbers. To make your program run faster, use integers. Long integers versus short integers: Tiny integers are called short integers. For example, 0, 1, and 2 are short integers. So is 27. So is 589. The biggest permissible short integer is 32767. The lowest permissible short integer is 32768. An integer that’s not short is called long. For example, 50000 is a long integer, since it’s an integer bigger than 32767. Another long integer is 50000. The biggest permissible long integer is 2147483647 (which is about 2 billion, using the American definition of billion). The lowest permissible long integer is 2147483648. If you try to create an integer bigger than 2147483647, the computer will refuse. Instead, put a decimal point in the number, so the number becomes a real number. For example, if you want to deal with 5000000000, which is too big to be an integer, say 5000000000.0 instead, so the number is real. The computer handles short integers faster than long integers, and handles long integers faster than real numbers. To store a short integer in the computer’s RAM chips, the computer uses a special trick that lets the short integer fit into 2 bytes of RAM. So each short integer consumes just 2 bytes. For example, 589 consumes just 2 bytes. 32767 consumes just 2 bytes. 32768 consumes just 2 bytes. To store a long integer, the computer uses a different trick, which consumes 4 bytes of RAM. For example, 2147483648 consumes 4 bytes. Singleprecision versus doubleprecision: A real number contains a decimal point. It can also contain a negative sign and lots of digits. If it contains at least 8 digits, it’s called a doubleprecision number. For example, 725.14592 is a doubleprecision number, since it contains 8 digits. 2943423.0 is doubleprecision. So is .00000001. So are 52341523092342.31 and 6.269549374523423, since each contains at least 8 digits. But .0000001 is not doubleprecision, since it contains just 7 digits. A real number containing fewer than 8 digits is called singleprecision. For example, .0000001 is singleprecision. So is 5.2. So is 27.1. A singleprecision number can be up to 7 digits long. A doubleprecision number can be up to 16 digits long. A singleprecision number consumes 4 bytes of RAM. A doubleprecision number consumes 8 bytes of RAM. The computer handles singleprecision numbers faster than doubleprecision. Suffix At the end of a number, you can put a suffix: Suffix Meaning % short integer & long integer ! singleprecision real # doubleprecision real For example, the number 27 is a short integer. If you want to turn it into a singleprecision real, write “27.0” or “27!” instead of “27”. If you want to turn it into a doubleprecision real, write “27.000000” or “27#”. If you want to turn it into a long integer, write “27&”. In your program, if you write a doubleprecision real, the computer will automatically put the symbol # afterwards when you press the ENTER key. For example, if you write — PRINT 53926.175 * 27.000000 and then press the ENTER key, the computer will automatically turn your typing into this: PRINT 53926.175# * 27# If you write a singleprecision real that ends in .0, the computer will automatically change .0 to “!”. For example, if you write — PRINT 200.0 * 300.0 and then press the ENTER key, the computer will automatically turn your typing into this: PRINT 200! * 300! Scientific notation For singleprecision real numbers, you can use E notation. For example, instead of writing 27945.86, you can write 2.794586E4. The “E4” means “move the decimal point 4 places to the right.” Instead of writing .0006829, you can write 6.829E4, in which the “E4” means “move the decimal point 4 places to the left.” For doubleprecision real numbers, write a D instead of an E. For example, 2.794586D4 is the doubleprecision version of 2.794586E4. The number before the E or D is called the mantissa; the number after the E or D is called the exponent. For example, in the number 2.794586E4, the mantissa is 2.794586; the exponent is 4. For a singleprecision numbers, the mantissa can contain up to 7 digits. For doubleprecision numbers, the mantissa can contain up to 16 digits. A number that contains a D is doubleprecision, even if the mantissa contains few digits or no decimal point. A number that contains an E is singleprecision, even if the mantissa contains no decimal point; but if the mantissa contains more than 7 digits, the computer will turn the E into a D when you press ENTER. Biggest real numbers The biggest permissible singleprecision number is about 3.000000E38. More precisely, it’s 3.402823E38. The biggest permissible doubleprecision number is about 1.000000000000000D308. More precisely, it’s 1.797693134862315D308. If you try to go higher than those numbers, the computer will gripe by saying “Overflow”. Accuracy The computer handles integers accurately. The computer tries to handle real numbers accurately but sometimes makes slight mistakes with the real number’s last digit. For a singleprecision real number, the computer makes slight mistakes with the 7^{th} digit. For a doubleprecision real number, the computer makes slight mistakes with the 16^{th} digit. Tiniest decimals You’ve seen that the biggest permissible doubleprecision number is about 1D308. The tiniest doubleprecision decimal that the computer can handle well is about 1D308. If you try to go much tinier, the computer will usually botch the last few digits of the number (and replace those digits by different digits instead!) or else round the entire number to zero. You’ve seen that the biggest permissible singleprecision number is slightly bigger than 1E38. The tiniest singleprecision decimal that the computer can handle well is about 1E38. If you try to go much tinier, the computer will usually botch the last few digits of the number (and replace those digits by different digits instead!) or else round the entire number to zero. Variables Usually, each ordinary variable (such as x) stands for a singleprecision real number. For example, you can say x=3.7, which makes x be the singleprecision number 3.7. If you say x=3, the computer will make x be 3.0 instead, to make x be a singleprecision number. Though the screen will still say x=3, the x box in the computer’s RAM will contain 3.0 instead. You can create five kinds of variables: A variable that’s ordinary (such as x) or ends in an exclamation (such as x!) is singleprecision real. A variable that ends in a dollar sign (such as x$) is a string. A variable that ends in a percent sign (such as x%)is an short integer. A variable that ends in an ampersand (such as x&)is a long integer. A variable that ends in a number sign (such as x#) is doubleprecision real. If you begin your program by saying — DEFINT AZ all ordinary variables (such as x) will be short integers instead of singleprecision real. (The word “DEFINT” means “DEFine to be INTegers”.) If instead you say — DEFLNG AZ all ordinary variables will be LoNG integers. If instead you say — DEFDBL AZ all ordinary variables will be DouBLeprecision real. What to do Write your program simply, without worrying about which numbers and variables are short integers, long integer, singleprecision real numbers, and doubleprecision real numbers. But after your program is written and you’ve removed any errors, edit the program by making the following changes, which improve the program’s speed and accuracy: All short integers: if your program doesn’t involve any decimals or big numbers, make the top line say DEFINT AZ. That will turn every variable into a short integer, so the program runs faster and consumes less RAM. Mostly short integers: if your program involves just a few decimals or big numbers, make the top line say DEFINT AZ; then put an exclamation point (!) after every variable standing for a decimal, and put an ampersand (&) after every variable standing for a long integer. Extra accuracy: if you want to perform one of the computations extraaccurately, put a number sign after every variable the computation involves. For example, say x# instead of x. Also, make sure that each number in the computation contains a number sign or at least 8 digits; for example, instead of saying 2.4, say 2.4# or 2.4000000. Avoid roundoff errors The computer cannot handle decimals accurately. If you say x=.1, the computer can’t set x equal to .1 exactly; instead, it will set x equal to a number very, very close to .1. The reason for the slight inaccuracy is that the computer thinks in “binary”, not decimals; and .1 cannot be expressed in binary exactly. Usually you won’t see the slight inaccuracy: when you ask the computer to PRINT a number, the computer prints it rounded to six significant figures, and the inaccuracy is so small it doesn’t show up in the rounded result. But there are three situations in which the inaccuracy can be noticed: 1. You’ll get wrong digits if you make the computer do x minus y, where x is almost equal to y (so the first several digits of x are the same as the first several digits of y). For example, if you say — PRINT 8.1  8 the computer will print .1000004 instead of .1. The same thing happens if you say: PRINT 8.1 + (8) If you say — PRINT 80000.1  80000 the computer will print .1015625 instead of .1. If you say — PRINT 800000.1  800000 the computer will print .125 instead of .1. The error can get magnified: if you ask the computer to multiply 800000.1800000 by 1000, it will print .125*1000, which is 125, instead of .1*1000, which is 100. If you ask it to find the reciprocal of 800000.1800000, it will print 1/.125, which is 8, instead of 1/.1, which is 10. 2. You’ll get wrong looping if you say “FOR x = a TO b STEP c”, where c is a decimal and the loop will be done many times. For example: FOR x = 1 TO 2 STEP .1 PRINT x NEXT Theoretically, the computer should print 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, and 2. But that’s not what actually happens. In the FOR line, the computer can’t handle the decimal .1 accurately. The last few numbers the computer thinks of are: slightly more than 1.7 slightly more than 1.8 slightly more than 1.9 The computer does not think of the next number, slightly more than 2.0, because the FOR line says not to go past 2. The PRINT line makes the computer print the numbers rounded to seven significant digits, so it prints: 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 It does not print 2. If you want to compute 1 + 1.1 + 1.2 + 1.3 + 1.4 + 1.5 + 1.6 + 1.7 + 1.8 + 1.9 + 2, you might be tempted to write this program: CLS s = 0 FOR x = 1 TO 2 STEP .1 s = s + x NEXT PRINT s The computer will print a reasonablelooking answer: 14.5. But the computer’s “answer” is wrong, since the last number the computer added was slightly more than 1.9; it never added 2. The correct answer is 16.5. To fix those FOR loops, you can change the FOR line to this FOR x = 1 TO 2.05 STEP .1 The .05 after the 2 allows for the margin of error. The general strategy is to change — FOR x = a TO b STEP c to this: FOR x = a TO b + c / 2 STEP c An alternative fix is to replace — FOR x = 1 TO 2 STEP .1 by this pair of lines: FOR i = 10 TO 20 x = i / 10 As i goes from 10 to 20, x will go from 1 to 2 in steps of .1. This fix is the most accurate of all, since it eliminates decimals from the FOR line. But the new indented line (x = i / 10) makes the program run very slowly, since that line requires the computer to perform division, and the division is performed repeatedly (since it’s in the FOR loop). 3. You’ll get wrong testing if you ask the computer whether two numbers x and y are equal. It’s unwise to ask whether x is exactly equal to y, since both x and y have probably been affected by some slight error. Instead, ask the computer whether the difference between x and y is much tinier than y. Bad:IF x = y THEN Good:IF ABS(x  y) <= .000001 * ABS(y) THEN The .000001 is requesting that the first six significant digits of x be the same as the first six significant digits of y (except that the sixth significant digit might be off by one). Why binary? From those discussions, you might think computers should be made differently, and that they should use the decimal system instead of binary. There are two counterarguments: 1. Binary arithmetic is faster. 2. Even if computers were using the decimal system, inaccuracy would still occur. To store the fraction 2/3 accurately by using the decimal system, the computer would have to store a decimal point followed by infinitely many 6’s. That would require an infinite amount of space in memory, which is impossible — unless you know how to build an infinitely large computer? So even in the decimal system, some fractions must be approximated instead of handled exactly. According to mathematicians, addition is supposed to obey these laws: x+0 is exactly the same as x x+y is exactly the same as y+x x+x is exactly the same as 0 (x+y)+zis exactly the same as x+(y+z) On the computer, the first three laws hold, but the last does not. If x is a decimal tinier than z, the computer does (x+y)+z more accurately than x+(y+z). So to add a list of numbers accurately, begin by adding together the tiniest decimals in the list. Integer division When you add, subtract, or multiply integers together, the answer is an integer: 11 + 4 is an integer, 15 11  4 is an integer, 7 11 * 4 is an integer, 44 When you divide integers by using a slash (/), the answer is a real number: 11 / 4 is a real number, 2.75 If you divide integers by using a backslash (\), the computer will ignore any decimal digits and give you just an integer: 11 \ 4 is an integer, 2 When you divide 11 by 4, the remainder is 3: 2 4 ^{)} 11 8 3 is the remainder If you ask for 11 MOD 4, the computer will tell you the remainder when you divide 11 by 4: 11 MOD 4 is an integer, 3 So if you say — PRINT 11 MOD 4 the computer will print: 3 Prime numbers An integer is called composite if it’s the product of two other integers: 35 is composite because it’s 5 * 7 9 is composite because it’s 3 * 3 12 is composite because it’s 2 * 6 13 is not composite, so it’s called prime This program tells whether a number is prime or composite: CLS DEFLNG AZ INPUT "What's your favorite positive integer"; n FOR i = 1 TO n  1 FOR j = 1 TO n  1 IF n = i * j THEN PRINT n; "is"; i; "times"; j; "and composite": END NEXT NEXT PRINT n; "is prime" To make the program run faster, we want all variables to be integers instead of reals. To let the program handle big numbers, we want the integers to be long. The DEFLNG line accomplishes all that: it makes all variables be long integers. Here’s how the program works. The INPUT line waits for you to type an integer n. The IF line checks whether n is the product of two other integers; if it is, the computer says n is composite. How fast does that program run? If n turns out to be prime, the IF line is encountered once for every i and once for every j; altogether it’s encountered (n1)^{2} times. If n is a big number, around a billion, (n1)^{2} is around a quintillion. (I’m using the American definitions of billion and quintillion. An American billion is 1,000,000,000; an American quintillion is 1,000,000,000,000,000,000. British definitions of billion and quintillion are different.) To do the IF line a quintillion times will take a typical microcomputer many years. For example, if you say that your favorite number is 999999929 (which is close to a billion), the typical 486DX266 computer will take about 400,000 years before it comes to the conclusion that your number is prime! By the time the program finishes running, you’ll be dead and so will many generations of your decendents! Probably your computer or its electricity will have died by then too! The program’s very slow. Some small improvements are possible; for example, i and j can start at 2 instead of 1. But so long as you have a loop inside a loop, the time will remain very huge. The following strategy requires just one loop: divide n by every integer less than it, to see whether the quotient is ever an integer. Here’s the program: CLS DEFLNG AZ INPUT "What's your favorite positive integer"; n FOR i = 2 TO n  1 IF n MOD i = 0 THEN PRINT n; "is divisible by"; i; "and composite": END NEXT PRINT n; "is prime" The IF line makes the computer divide n by i, compute the remainder (which is called “n MOD i”), and check whether that remainder is 0. If the remainder is 0, then n divided evenly by i, so n is divisible by i, so n is composite. How fast is our new program? If n turns out to be prime, the IF line is encountered once for every i; altogether it’s encountered n2 times. That’s less than in the previous program, where it was encountered (n1)^{2} times. If n is about a billion, our new program does the IF line about a billion times, which is much fewer than the quintillion times required by the previous program! It’s nearly a billion times faster than the previous program! To determine whether 999999929 is prime, the new program takes a 486DX266 computer about 5 hours instead of 400,000 years. We can improve the program even further. If an n can’t be divided by 2, it can’t be divided by any even number; so after checking divisibility by 2, we have to check divisibility by just 3, 5, 7, …, n2. Let’s put that shortcut into our program, and also say that every n less than 4 is prime: CLS DEFLNG AZ INPUT "What's your favorite positive integer"; n IF n < 4 THEN PRINT n; "is prime": END IF n MOD 2 = 0 THEN PRINT n; "is divisible by 2 and composite": END FOR i = 3 TO n  2 STEP 2 IF n MOD i = 0 THEN PRINT n; "is divisible by"; i; "and composite": END NEXT PRINT n; "is prime" Line 5 checks divisibility by 2; the FOR loop checks divisibility by 3, 5, 7,… , n2. If n is prime, the indented IF line is encountered n/2  2 times, which is about half as often as in the previous program; so our new program takes about half as long to run. On a 486DX266 computer, it takes about 2½ hours to handle 999999929. Our goal was to find a pair of integers whose product is n. If there is such a pair of integers, the smaller one will be no more than the square root of n, so we can restrict our hunt to the integers not exceeding the square root of n: CLS DEFLNG AZ INPUT "What's your favorite positive integer"; n IF n < 4 THEN PRINT n; "is prime": END IF n MOD 2 = 0 THEN PRINT n; "is divisible by 2 and composite": END FOR i = 3 TO SQR(n) * 1.000001 STEP 2 IF n MOD i = 0 THEN PRINT n; "is divisible by"; i; "and composite": END NEXT PRINT n; "is prime" The “1.00001” is to give a margin of safety, in case the computer rounds SQR(n) a bit down. If n is near a billion, the indented IF line is encountered about 15,000 times, which is much less than the 500,000,000 times encountered in the previous program and the 1,000,000,000,000,000,000 times in the original. This program lets a 486DX266 computer handle 999999929 in about ¼ of a second. That’s much quicker than earlier versions, which required 2½ hours, or 5 hours, or 400,000 years! Moral: a few small changes in a program can make the computer take ¼ of a second instead of 400,000 years. The frightening thing about this example is that the first version we had was so terrible, but the only way to significantly improve it was to take a totally fresh approach. To be a successful programmer, you must always keep your mind open and hunt for fresh ideas. 
all content copyright © 2002 / web design by josh feingold 