OFFICIAL ADAM GUEST WEB SITE
Numbers and Basic Programming

Home

Site Map | About Me | Favorite Links | Contact Me | My Resume

Welcome To Numbers and Basic Programming.  This page is deticated to the understanding of the various types of numbers, and sometimes letters accociated with technology.  I hope that the compiled information can clear up any confusion as to how these systems work.  I deticate this page to my good buddy Mike, his stern strait forward approach certainly reminds me of math and programming, no room for error, no beating around the bush, hope you enjoy all of your days BRO!? 

Chapter 1
 
Bits, bytes, kilobytes and megabytes...

 

A bit is short for "binary digit." It is the smallest possible unit of information; i.e. a bit is to information what an atom is to an element! A bit could be represented by an on-off switch. This is essentially the case for static memory chips, or RAM (random-access memory), where each of the thousands of bits is a transistor, which may be in the on or off state. Dynamic RAM uses charged or uncharged capacitors to store data. [As an aside, static RAM is faster than dynamic RAM, but is also more expensive and power-consuming. Because capacitors discharge over time, dynamic memory must be constantly refreshed.] Magnetic media (floppies, hard drives, tape, even credit cards and ATM cards, use a positively or negatively charged magnetic region for each bit.

Data lines

Transferring individual bits between CPU and memory would be very time consuming, so it is customary to send a larger chunk of information. For some reason or another, memory is usually divided into eight-bit chunks called bytes. Four-bit chunks are called nibbles - no kidding! Most computers, then, will have at least 8 lines running between CPU and memory for data in and 8 lines for data out. Thus, a whole byte is transferred at once (in parallel). This also means that we only need a unique address for each byte in our memory, rather than having to have a unique address for each bit. Early IBM-type PCs had an 8-line (or 8-bit) data bus running between memory and the 8086 CPU. Later, the 80286 CPU improved on this by have a 16-bit data bus. Computers containing 80386, or 80486 have a 32-bit data bus. Pentium chips have a 64-bit external data bus.

We also have names for larger chunks of information. Since computers work in binary, memory is usually divided up into divisions that are a power of 2. Hence,

kilobyte = 1024 bytes (1024 = 210), abbreviated KB (Kb is kilobits)

megabyte = 1024 KB = 1,048,576 bytes, abbreviated MB (Mb is megabits)

gigabyte = 1024 MB = 1,073,741,824 bytes, abbreviated GB (Gb is gigabits)

Address lines

Address lines run between the CPU and memory and are used to tell the memory which particular byte we want to read or write. Early microcomputers used 16 address lines. Each line could be [on/off; high/low; true/false; 0/1; etc.], allowing for 216 unique addresses, or 65,536 bytes of addressable memory.

The original IBM PC had 20 address lines. Since 220 = 1,048,576, IBM PCs, and the Microsoft DOS which was written for it, could only utilize 1 MB of memory. About 360 KB was reserved for ROM BIOS, video RAM, etc. (more on this later), and the other 640 KB was available for the DOS operating system and user programs. PCs have essentially been stuck with that limitation ever since, although Windows (and other, newer, operating systems like OS/2, LINUX, Windows 95) gets around it somewhat. The CPUs themselves have advanced beyond that stage (the 80286 has 24 address lines, allowing for 16 MB to be addressed; the 80386/486 has 32 address lines to address 4 gigabytes), but in order to maintain "backward compatibility," DOS has remained a 1 MB (640 KB) world. Windows, and to a much greater extent, Windows 95, have crashed the 1 MB barrier by using protected mode, 32-bit addressing

So what do we put into memory?

Instructions and data!

Instructions

Instructions are stored as binary numbers, just as data is. For example, 10110010 (decimal 178) might be interpreted by the CPU as "get the byte of data located at the address given by the next two bytes and add it to the number in the accumulator (a part of the CPU that contains numbers to be acted on).

Data: ASCII, integers, floating point real and complex, etc.

To View ASCII Chart Go To DIGITAL BASICS

Data are usually either numbers or letters. Of course, memory can only hold binary numbers, so we have to agree how to interpret those numbers (a kind of code) when we want them to represent letters (or numbers, for that matter). ASCII stands for American Standard Code for Information Interchange. In this system, 7 bits are used to represent 128 (27) different letters, numbers, punctuation, and special codes. When the eighth bit is used (why waste it?), we have Extended ASCII, in which 256 characters are available. The "upper" 128 characters are not as standard as the first 128. Refer to an Extended ASCII chart.

Not all computers use this system. IBM, on their mainframes, stubbornly sticks with EBCDIC, which means something but I have tried very hard to forget what. Unicode is a new system which use 2 bytes, allowing many more characters to be represented (how many, class?), such as Kanji, Cyrillic, Hebrew, etc. Unicode is backwards compatible with ASCII, meaning that operating systems using Unicode, such as Windows 95, can still make sense of ASCII files.

Earlier it was mentioned that 10110010 equals decimal 178. So why do we need a "code" for representing numbers in a computer? Why not just use binary (converted back to decimal when we type it in or read it, of course)? Well, how would we represent negative numbers? What about fractions? What about numbers larger than 8 bits can represent (28 = 256)? You see the problem. The solution, shortened a bit (no pun intended) is to use more than one byte, and, for floating point numbers, to use some of the bits for an exponent and the rest for the mantissa. The table below shows some of the more common data types. The exact details depend on the particular program used (which, in turn, usually depends on the compiler used to create the program).

Common Data Types

Data Type

Approximate Range

Significant
 

(from)

(to)

Bits

Digits

logical

False (0)

True (1)

8

NA

character

a

Z (sort of!)

8

NA

short integer

-128.00

127.00

8

2

integer

-32,768

+32,767

16

4

long integer

-2 x 109

+2 x 109

32

9

single precision IEEE real

-3.4 x 10+38 to -1.2 x 10-38

+1.2 x 10-38 to +3.4 x 10+38

32

6

double precision IEEE real

-1.8 x 10+308 to -2.2 x 10-308

+2.2 x 10-308 to 1.8 x 10+308

64

15

single precision complex

like single precision real, for both real and imaginary parts

like single precision real, for both real and imaginary parts
   

double precision complex

like double precision real, for both real and imaginary parts

like double precision real, for both real and imaginary parts
   


Hey do you want to test your skills?    Click below to go to Test Page 1.

Test Page:1 BITS BYTES AND DATA TYPES

Chapter 2

Breaking Down Binary Even Further

Table of Contents

  • Basic Concepts Behind the Binary System
  • Binary Addition
  • Binary Multiplication
  • Binary Division
  • Conversion from Decimal to Binary
  • Negation in the Binary System

Basic Concepts Behind the Binary System

To understand binary numbers, begin by recalling elementary school math. When we first learned about numbers, we were taught that, in the decimal system, things are organized into columns:

    H | T | O
    1 | 9 | 3
such that "H" is the hundreds column, "T" is the tens column, and "O" is the ones column. So the number "193" is 1-hundreds plus 9-tens plus 3-ones.

Years later, we learned that the ones column meant 10^0, the tens column meant 10^1, the hundreds column 10^2 and so on, such that

      10^2|10^1|10^0
        1 |  9 |  3 
the number 193 is really {(1*10^2)+(9*10^1)+(3*10^0)}.

As you know, the decimal system uses the digits 0-9 to represent numbers. If we wanted to put a larger number in column 10^n (e.g., 10), we would have to multiply 10*10^n, which would give 10^(n+1), and be carried a column to the left. For example, putting ten in the 10^0 column is impossible, so we put a 1 in the 10^1 column, and a 0 in the 10^0 column, thus using two columns. Twelve would be 12*10^0, or 10^0(10+2), or 10^1+2*10^0, which also uses an additional column to the left (12).

The binary system works under the exact same principles as the decimal system, only it operates in base 2 rather than base 10. In other words, instead of columns being

 
       10^2|10^1|10^0
they are
        2^2|2^1|2^0

Instead of using the digits 0-9, we only use 0-1 (again, if we used anything larger it would be like multiplying 2*2^n and getting 2^n+1, which would not fit in the 2^n column. Therefore, it would shift you one column to the left. For example, "3" in binary cannot be put into one column. The first column we fill is the right-most column, which is 2^0, or 1. Since 3>1, we need to use an extra column to the left, and indicate it as "11" in binary (1*2^1) + (1*2^0).

Examples: What would the binary number 1011 be in decimal notation? 



Try converting these numbers from binary to decimal:

  • 10
  • 111
  • 10101
  • 11110
Remember:
      2^4| 2^3| 2^2| 2^1| 2^0
         |    |    |  1  |  0
         |    | 1  |  1  |  1
      1  | 0  | 1  |  0  |  1
      1  | 1  | 1  |  1  |  0

 

Binary Addition

Consider the addition of decimal numbers:

     23
    +48
    ___

We begin by adding 3+8=11. Since 11 is greater than 10, a one is put into the 10's column (carried), and a 1 is recorded in the one's column of the sum. Next, add {(2+4) +1} (the one is from the carry)=7, which is put in the 10's column of the sum. Thus, the answer is 71.

Binary addition works on the same principle, but the numerals are different. Begin with one-bit binary addition:

    0    0    1
   +0   +1   +0
  ___  ___  ___  
    0    1    1

1+1 carries us into the next column. In decimal form, 1+1=2. In binary, any digit higher than 1 puts us a column to the left (as would 10 in decimal notation). The decimal number "2" is written in binary notation as "10" (1*2^1)+(0*2^0). Record the 0 in the ones column, and carry the 1 to the twos column to get an answer of "10." In our vertical notation,

    1
   +1
  ___
   10

The process is the same for multiple-bit binary numbers:

         1010
        +1111
       ______

  • Step one:
    Column 2^0: 0+1=1.
    Record the 1.
    Temporary Result: 1; Carry: 0
  • Step two:
    Column 2^1: 1+1=10.
    Record the 0, carry the 1.
    Temporary Result: 01; Carry: 1
  • Step three:
    Column 2^2: 1+0=1 Add 1 from carry: 1+1=10.
    Record the 0, carry the 1.
    Temporary Result: 001; Carry: 1
  • Step four:
    Column 2^3: 1+1=10. Add 1 from carry: 10+1=11.
    Record the 11.
    Final result: 11001

Alternately:

    11   (carry)
    1010
   +1111
  ______
   11001

Always remember

  • 0+0=0
  • 1+0=1
  • 1+1=10

Try a few examples of binary addition:

       111      101      111
      +110     +111     +111
    ______    _____    _____

Binary Multiplication

Multiplication in the binary system works the same way as in the decimal system:

  • 1*1=1
  • 1*0=0
  • 0*1=0

   101                      
  * 11
  ____
   101
  1010
 _____
  1111

Note that multiplying by two is extremely easy. To multiply by two, just add a 0 on the end.

Binary Division

Follow the same rules as in decimal division. For the sake of simplicity, throw away the remainder.

For Example: 111011/11

      10011 r 10
    _______
  11)111011
    -11
     ______
       101
       -11
     ______
        101
         11
     ______
         10

 

Decimal to Binary

Converting from decimal to binary notation is slightly more difficult conceptually, but can easily be done once you know how through the use of algorithms. Begin by thinking of a few examples. We can easily see that the number 3= 2+1. and that this is equivalent to (1*2^1)+(1*2^0). This translates into putting a "1" in the 2^1 column and a "1" in the 2^0 column, to get "11". Almost as intuitive is the number 5: it is obviously 4+1, which is the same as saying [(2*2) +1], or 2^2+1. This can also be written as [(1*2^2)+(1*2^0)]. Looking at this in columns,

        2^2 | 2^1 | 2^0
         1     0     1
or 101.

What we're doing here is finding the largest power of two within the number (2^2=4 is the largest power of 2 in 5), subtracting that from the number (5-4=1), and finding the largest power of 2 in the remainder (2^0=1 is the largest power of 2 in 1). Then we just put this into columns. This process continues until we have a remainder of 0. Let's take a look at how it works. We know that:

   2^0=1
   2^1=2
   2^2=4
   2^3=8
   2^4=16
   2^5=32
   2^6=64
   2^7=128
and so on. To convert the decimal number 75 to binary, we would find the largest power of 2 less than 75, which is 64. Thus, we would put a 1 in the 2^6 column, and subtract 64 from 75, giving us 11. The largest power of 2 in 11 is 8, or 2^3. Put 1 in the 2^3 column, and 0 in 2^4 and 2^5. Subtract 8 from 11 to get 3. Put 1 in the 2^1 column, 0 in 2^2, and subtract 2 from 3. We're left with 1, which goes in 2^0, and we subtract one to get zero. Thus, our number is 1001011.

Making this algorithm a bit more formal gives us:

  1. Let D=number we wish to convert from decimal to binary
  2. Repeat until D=0
    • a. Find the largest power of two in D. Let this equal P.
    • b. Put a 1 in binary column P.
    • c. Subtract P from D.
  3. Put zeros in all columns which don't have ones.
This algorithm is a bit awkward. Particularly step 3, "filling in the zeros." Therefore, we should rewrite it such that we ascertain the value of each column individually, putting in 0's and 1's as we go:

  1. Let D= the number we wish to convert from decimal to binary
  2. Find P, such that 2^P is the largest power of two smaller than D.
  3. Repeat until P<0
    • If 2^P<=D then
      • put 1 into column P
      • subtract 2^P from D
    • Else
      • put 0 into column P
    • End if
    • Subtract 1 from P

Now that we have an algorithm, we can use it to convert numbers from decimal to binary relatively painlessly. Let's try the number D=55.

  • Our first step is to find P. We know that 2^4=16, 2^5=32, and 2^6=64. Therefore, P=5.
  • 2^5<=55, so we put a 1 in the 2^5 column: 1-----.
  • Subtracting 55-32 leaves us with 23. Subtracting 1 from P gives us 4.
  • Following step 3 again, 2^4<=23, so we put a 1 in the 2^4 column: 11----.
  • Next, subtract 16 from 23, to get 7. Subtract 1 from P gives us 3.
  • 2^3>7, so we put a 0 in the 2^3 column: 110---
  • Next, subtract 1 from P, which gives us 2.
  • 2^2<=7, so we put a 1 in the 2^2 column: 1101--
  • Subtract 4 from 7 to get 3. Subtract 1 from P to get 1.
  • 2^1<=3, so we put a 1 in the 2^1 column: 11011-
  • Subtract 2 from 3 to get 1. Subtract 1 from P to get 0.
  • 2^0<=1, so we put a 1 in the 2^0 column: 110111
  • Subtract 1 from 1 to get 0. Subtract 1 from P to get -1.
  • P is now less than zero, so we stop.

Another algorithm for converting decimal to binary

However, this is not the only approach possible. We can start at the right, rather than the left.

All binary numbers are in the form

a[n]*2^n + a[n-1]*2^(n-1)+...+a[1]*2^1 + a[0]*2^0
where each a[i] is either a 1 or a 0 (the only possible digits for the binary system). The only way a number can be odd is if it has a 1 in the 2^0 column, because all powers of two greater than 0 are even numbers (2, 4, 8, 16...). This gives us the rightmost digit as a starting point.

Now we need to do the remaining digits. One idea is to "shift" them. It is also easy to see that multiplying and dividing by 2 shifts everything by one column: two in binary is 10, or (1*2^1). Dividing (1*2^1) by 2 gives us (1*2^0), or just a 1 in binary. Similarly, multiplying by 2 shifts in the other direction: (1*2^1)*2=(1*2^2) or 10 in binary. Therefore

{a[n]*2^n + a[n-1]*2^(n-1) + ... + a[1]*2^1 + a[0]*2^0}/2

is equal to

a[n]*2^(n-1) + a[n-1]*2^(n-2) + ... + a[1]2^0 

Let's look at how this can help us convert from decimal to binary. Take the number 163. We know that since it is odd, there must be a 1 in the 2^0 column (a[0]=1). We also know that it equals 162+1. If we put the 1 in the 2^0 column, we have 162 left, and have to decide how to translate the remaining digits.

Two's column: Dividing 162 by 2 gives 81. The number 81 in binary would also have a 1 in the 2^0 column. Since we divided the number by two, we "took out" one power of two. Similarly, the statement a[n-1]*2^(n-1) + a[n-2]*2^(n-2) + ... + a[1]*2^0 has a power of two removed. Our "new" 2^0 column now contains a1. We learned earlier that there is a 1 in the 2^0 column if the number is odd. Since 81 is odd, a[1]=1. Practically, we can simply keep a "running total", which now stands at 11 (a[1]=1 and a[0]=1). Also note that a1 is essentially "remultiplied" by two just by putting it in front of a[0], so it is automatically fit into the correct column.

Four's column: Now we can subtract 1 from 81 to see what remainder we still must place (80). Dividing 80 by 2 gives 40. Therefore, there must be a 0 in the 4's column, (because what we are actually placing is a 2^0 column, and the number is not odd).

Eight's column: We can divide by two again to get 20. This is even, so we put a 0 in the 8's column. Our running total now stands at a[3]=0, a[2]=0, a[1]=1, and a[0]=1.

We can continue in this manner until there is no remainder to place.

  Let's formalize this algorithm:
1.  Let D= the number we wish to convert from decimal to binary.
2.  Repeat until D=0:
    a) If D is odd, put "1" in the leftmost open column, and subtract 1 from D.
    b) If D is even, put "0" in the leftmost open column.
    c) Divide D by 2.
    End Repeat
For the number 163, this works as follows:
1.  Let D=163
2.  b) D is odd, put a 1 in the 2^0 column.
  Subtract 1 from D to get 162.
    c) Divide D=162 by 2.
Temporary Result: 01     New D=81
D does not equal 0, so we repeat step 2.

2.  b) D is odd, put a 1 in the 2^1 column.
  Subtract 1 from D to get 80.
     c) Divide D=80 by 2.
Temporary Result: 11     New D=40
D does not equal 0, so we repeat step 2.

2.  b) D is even, put a 0 in the 2^2 column.
    c) Divide D by 2.
Temporary Result:011    New D=20

2.  b) D is even, put a 0 in the 2^3 column.
    c) Divide D by 2.
Temporary Result: 0011     New D=10

2.  b) D is even, put a 0 in the 2^4 column.
    c) Divide D by 2.
Temporary Result:  00011      New D=5

2.  a) D is odd, put a 1 in the 2^5 column.
       Subtract 1 from D to get 4.
    c) Divide D by 2.
Temporary Result:  100011   New D=2

2.  b) D is even, put a 0 in the 2^6 column.
    c) Divide D by 2.
Temporary Result:  0100011   New D=1

2.  a) D is odd, put a 1 in the 27 column.
       Subtract 1 from D to get D=0.
    c) Divide D by 2.
Temporary Result:  10100011   New D=0

D=0, so we are done, and the decimal number 163 is equivalent to the binary number 10100011.

Since we already knew how to convert from binary to decimal, we can easily verify our result. 10100011=(1*2^0)+(1*2^1)+(1*2^5)+(1*2^7)=1+2+32+128= 163.

Negation in the Binary System

  • Signed Magnitude
  • One's Complement
  • Two's Complement
  • Excess 2^(m-1)

These techniques work well for non-negative integers, but how do we indicate negative numbers in the binary system?

Before we investigate negative numbers, we note that the computer uses a fixed number of "bits" or binary digits. An 8-bit number is 8 digits long. For this section, we will work with 8 bits.

Signed Magnitude:

The simplest way to indicate negation is signed magnitude. In signed magnitude, the left-most bit is not actually part of the number, but is just the equivalent of a +/- sign. "0" indicates that the number is positive, "1" indicates negative. In 8 bits, 00001100 would be 12 (break this down into (1*2^3) + (1*2^2) ). To indicate -12, we would simply put a "1" rather than a "0" as the first bit: 10001100.

One's Complement:

In one's complement, positive numbers are represented as usual in regular binary. However, negative numbers are represented differently. To negate a number, replace all zeros with ones, and ones with zeros - flip the bits. Thus, 12 would be 00001100, and -12 would be 11110011. As in signed magnitude, the leftmost bit indicates the sign (1 is negative, 0 is positive). To compute the value of a negative number, flip the bits and translate as before.

Two's Complement:

Begin with the number in one's complement. Add 1 if the number is negative. Twelve would be represented as 00001100, and -12 as 11110100. To verify this, let's subtract 1 from 11110110, to get 11110011. If we flip the bits, we get 00001100, or 12 in decimal.

In this notation, "m" indicates the total number of bits. For us (working with 8 bits), it would be excess 2^7. To represent a number (positive or negative) in excess 2^7, begin by taking the number in regular binary representation. Then add 2^7 (=128) to that number. For example, 7 would be 128 + 7=135, or 2^7+2^2+2^1+2^0, and, in binary,10000111. We would represent -7 as 128-7=121, and, in binary, 01111001.

Note:

  • Unless you know which representation has been used, you cannot figure out the value of a number.
  • A number in excess 2^(m-1) is the same as that number in two's complement with the leftmost bit flipped.

To see the advantages and disadvantages of each method, let's try working with them.

Using the regular algorithm for binary adition, add (5+12), (-5+12), (-12+-5), and (12+-12) in each system. Then convert back to decimal numbers.

Answers

What would the binary number 1011 be in decimal notation?

  1011=(1*2^3)+(0*2^2)+(1*2^1)+(1*2^0)
      = (1*8) + (0*4) + (1*2) + (1*1)
  = 11 (in decimal notation)

Try converting these numbers from binary to decimal:

10=(1*2^1) + (0*2^0) = 2+0 = 2
111 = (1*2^2) + (1*2^1) + (1*2^0) = 4+2+1=7
10101= (1*2^4) + (0*2^3) + (1*2^2) + (0*2^1) + (1*2^0)=16+0+4+0+1=21
11110= (1*2^4) + (1*2^3) + (1*2^2) + (1*2^1) + (0*2^0)=16+8+4+2+0=30

Try a few examples of binary addition:

                      1                1
          111            111            111
         +110                  +110           +110
        ______               ______         _____
               1                      01          1101

           1                        11             1   
  101            101    101
        +111                  +111            +111
        _____                 ____           _____
              0                     00            1100

              1                    1                      1
     111    111          111
           +111                +111                 +111
          _____               _____                _____
         0                    10                 1110
Using the regular algorithm for binary adition, add (5+12), (-5+12), (-12+-5), and (12+-12) in each system. Then convert back to decimal numbers.

Signed Magnitude:

    5+12         -5+12         -12+-5            12+-12 

 00000101       10000101       10001100        00001100
 00001100       00001100       10000101        10001100
__________      ________       ________        _________
 00010001       10010001       00010000        10011000

    17             -17            16              -24

One' Complement:

 00000101       11111010       11110011        00001100
 00001100       00001100       11111010        11110011
_________       ________       ________        ________
 00010001       00000110       11101101        11111111

    17             6              -18             0

Two's Complement:

 00000101       11111011       11110100        00001100
 00001100       00001100       11111011        11110100
 ________       ________       ________        ________
 00010001       00000111       11101111        00000000

     17            7              -17               0

Signed Magnitude:

 10000101       01111011       01110100        00001100
 10001100       10001100       01111011        01110100
 ________       ________       ________        ________
 00010001       00000111       11101111        01111100 

    109           119             111             124   

Chapter 3
 
Numbering systems


Normally, when we use a number such as 110, we understand it to mean "one hundred and ten," but in this chapter you will see how this is not always the case.


Hexadecimal numbers

We generally use the base 10 (decimal) numbering system, where each digit must be between 0-9; but the "hexadecimal" system (base 16) can also have digits A, B, C, D, E, and F (16 total digits).

(The hexadecimal numbers in this tutorial are red.)

    0 = Zero
    1 = One
    2 = Two
    3 = Three
    4 = Four
    5 = Five
    6 = Six
    7 = Seven
    8 = Eight
    9 = Nine
    A = Ten
    B = Eleven
    C = Twelve
    D = Thirteen
    E = Fourteen
    F = Fifteen
In the base 10 system, you add another digit when you get past the number 9; but with base 16, it isn't added until after F (or fifteen).
    10 = Sixteen
    11 = Seventeen
    12 = Eighteen
    13 = Nineteen
    14 = Twenty
    15 = Twenty one
    16 = Twenty two
    17 = Twenty three
    18 = Twenty four
    19 = Twenty five
    1A = Twenty six
    1B = Twenty seven
    1C = Twenty eight
    1D = Twenty nine
    1E = Thirty
    1F = Thirty one
    20 = Thirty two
    21 = Thirty three
    22 = Thirty four
    23 = Thirty five
    24 = Thirty six
     .
     .
     .
In the decimal system (base 10), we multiply ten for each time a digit goes to the left.
       10 = 10
      100 = 10 * 10
     1000 = 10 * 10 * 10
    10000 = 10 * 10 * 10 * 10
        .
        .
        .
But in the hexadecimal (base 16) system, we multiply sixteen, instead.
       10 = 16                 (16)
      100 = 16 * 16            (256)
     1000 = 16 * 16 * 16       (4096)
    10000 = 16 * 16 * 16 * 16  (65536)
        .
        .
        .
Therefore, since 10 is 16 and 100 is 256, the number 110 is two hundred and seventy two (272).

    110 = (100 + 10) = (256 + 16) = 272
(To download a number converter, click here.) However you will need to click the back arrow to get back to my site. :)



TIP: To enter a hexadecimal number in QBasic, use &H.

&H110



Binary numbers

The "binary" system (base 2) can only have two digits, 0 and 1. Therefore, no binary number has a digit between 2 and 9.

(Binary numbers are shown in dark blue.)
        0 = Zero
        1 = One
       10 = Two
       11 = Three
      100 = Four
      101 = Five
      110 = Six
      111 = Seven
     1000 = Eight
     1001 = Nine
     1010 = Ten
     1011 = Eleven
     1100 = Twelve
     1101 = Thirteen
     1110 = Fourteen
     1111 = Fifteen
    10000 = Sixteen
    10001 = Seventeen
    10010 = Eighteen
    10011 = Nineteen
    10100 = Twenty
        .
        .
        .
Notice how binary numbers can be found by excluding numbers that have a 2, 3, 4, 5, 6, 7, 8, or 9.
       0
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
       .
       .
       .
      97
      98
      99
     100
     101
     102
     103
     104
     105
     106
     107
     108
     109
     110
     111
     112
     113
     114
     115
       .
       .
       .
In base 10, as explained above, we multiply ten for each time a digit goes to the left.
       10 = 10
      100 = 10 * 10
     1000 = 10 * 10 * 10
    10000 = 10 * 10 * 10 * 10
        .
        .
        .
But in binary, we multiply by two.
       10 = 2              (2)
      100 = 2 * 2          (4)
     1000 = 2 * 2 * 2      (8)
    10000 = 2 * 2 * 2 * 2  (16)
        .
        .
        .
So, since 10 is 2 and 100 is 4, the number 110 is six.

    110 = (10 + 100) = (2 + 4) = 6
(To download a number converter, click here.) However you will need to click the back arrow to get back to my site. :)


TIP: Binary (and hexadecimal) numbers are often written with leading 0's.

0000  (same as 0
0001  (same as 1
0010  (same as 10)
0011  (same as 11)

Chapter 4
 
How data is stored

Data is stored in RAM at a certain memory address. Each address takes up 1 byte of memory. Therefore, it can only have a value between 0 and 255.

A memory address (on a 32-bit computer) can be somewhere between 0 and 4,294,967,295. In hexadecimal, this is between 0 and FFFFFFFF.

Each memory address is divided into two parts: segments and offsets.

A memory address such as 12345678 (in hexadecimal) has a segment of 1234 and an offset of 5678.

A segment can have a value between 0 and 65535 (or between 0 and FFFF). An offset can be within the same range.

You can find out a memory address of a piece of data by multiplying its segment by 65536 (or 10000, in hexadecimal) and then adding its offset to the result. In QBasic, you can get a variable's segment by using VARSEG and its offset by using VARPTR.
    segment = VARSEG(x)
    offset = VARPTR(x)

    ' This prints the memory address of "x" (in decimal):

    PRINT (segment * 65536) + offset

Chapter 5
 
Variables


This chapter discusses an important topic in programming, "variables." Please read this section thoroughly.

A variable is a piece of data kept in the computer's memory (RAM). The location of a variable in RAM is called the "address."

The following program prints the variable X to the screen:
    print X
Since the variable hasn't been assigned a number, the value of the variable is 0. So, the output of the program is:
    0
This next program sets X to 15, and then prints the variable:
    X = 15

    print X
This time, the output is:
    15
In the above example, the number 15 was stored in the computer's RAM at a certain memory address. Then the PRINT command accessed (or looked at) that address when it printed "15" to the screen.
 
ADVANCED TIP: Although you don't normally need to, you can find the actual memory address of a variable (X, for example) by using the VARSEG and VARPTR commands.

PRINT (VARSEG(X) * 65536) + VARPTR(X)

(For more information, see Memory.)


As in the programs above, a variable is accessed by calling its name. Variable names can have a combination of letters and numbers. The following are valid variables:
    Y

    num

    VALUE

    xYz

    abc123


Also, you can use multiple variables in your program.
    X = 82
    Y = 101
    Z = 79

    PRINT X
    PRINT Y
    PRINT Z
Output:
    82
    101
    79

    Expressions

    If you pass an expression to a variable, the expression is evaluated and the variable is set to that value. x = 500 + (10 * 7)

    PRINT x
Output:
    570

You can also use variables as expressions.
    rate = 50
    time = 2

    distance = rate * time

    PRINT distance
Output:
    100

Plus, you can have both variables and numbers in an expression.
    X = 100
    Y = X * 7

    PRINT Y
Output:
    700

TIP: The following increases X by 1:

X = X + 1



Strings

If you add a dollar sign ($) to the end of a variable, the variable is a string.
    X$ = "Hello World!"

    PRINT X$
Output:
    Hello World!

If you try to set a string to a non-string variable, an error occurs.
    X = "Hello World!"
The QBasic interpreter says "Type mismatch" when you try to run the above program.


A string can be added to the end of an existing variable string.
    X$ = "Hello"
    X$ = X$ + "World"

    PRINT X$
Output:
    HelloWorld

You can also add variable strings together.
    a$ = "String1"
    b$ = "String2"
    c$ = "String3"

    d$ = a$ + b$ + c$

    PRINT d$
Output:
    String1String2String3

Retrieving keyboard input from the user


One way to receive input from the keyboard is with the INPUT command. The INPUT command allows the user to enter either a string or a number, which is then stored in a variable.
    INPUT data$

    PRINT data$
When this program is executed, the INPUT command displays a question mark, followed by a blinking cursor. And when you enter text, the program stores that text into the variable data$, which is printed to the screen.


TIP: If you place a string and a semi-colon between INPUT and the variable, the program will print the string.

INPUT "Enter some text:"; data$


To receive a number, use a non-string variable.
    INPUT number

    PRINT number
If you enter text instead of a number, the QBasic interpreter displays an error message ("Redo from start").


Below is another example of the INPUT command:
    PRINT "Enter some text:"
    INPUT text$

    PRINT "Now enter a number:"
    INPUT num

    PRINT text$
    PRINT num

TIP: You can have the question mark displayed on the previous line by using a semi-colon.

PRINT "Enter some text:";
INPUT text$
 
The IF and THEN commands Star


The IF and THEN commands are used to compare an expression and then perform some task based on that expression.

    x = 5

    IF x = 5 THEN PRINT "x equals 5"
Since X does equal 5 in this case, the program outputs:
    x equals 5

Expression signs

You can also enter the following statements, instead of the equals sign:
    x < 5  (x is less than 5)

    x > 5  (x is greater than 5)


Run the following:
    x = 16

    IF (x > 5) THEN PRINT "x is greater than 5"
Output:
    x is greater than 5

You can also combine the signs like this:
    x <= 5  (x is less than or equal to 5)

    x >= 5  (x is greater than or equal to 5)

    x <> 5  (x does not equal 5)


Run the following example:
    CLS

    x = 5

    IF (x >= 5) THEN PRINT "x is greater than or equal to 5"
    IF (x <= 5) THEN PRINT "x is less than or equal to 5"
    IF (x <> 5) THEN PRINT "x does not equal 5"
Output:
    x is greater than or equal to 5
    x is less than or equal to 5

ELSE

Using the ELSE command, you can have the program perform a different action if the statement is false.
    x = 3

    IF x = 5 THEN PRINT "Yes" ELSE PRINT "No"
Since X doesn't equal 5, the output is:
    No

END IF

END IF allows you to have multiple commands after the IF...THEN statement, but they must start on the line after the IF statement. END IF should appear right after the list of commands.
    x = 5

    IF (x = 5) THEN

      INPUT a$
      PRINT a$

    END IF

The following program uses ELSE with the END IF command:
    x = 16

    IF (x = 5) THEN

      INPUT a$
      PRINT a$

    ELSE

      PRINT x * 2

    END IF
Output:
    32

TIP: There is a way to have multiple commands after IF...THEN without using END IF. To do so, place a colon between each command.

IF (x = 5) THEN INPUT a$: PRINT a$



ELSEIF

The ELSEIF command allows you to perform a secondary action if the first expression was false. Unlike ELSE, this task is only performed if a specified statement is true.
    x = 6

    IF (x = 5) THEN
      PRINT "Statement 1 is true"

    ELSEIF (x = 6) THEN
      PRINT "Statement 2 is true"

    END IF
Output:
    Statement 2 is true

You can have multiple ELSEIF commands, along with ELSE.
    x = 8

    IF (x = 5) THEN
      PRINT "Statement 1 is true"

    ELSEIF (x = 6) THEN
      PRINT "Statement 2 is true"

    ELSEIF (x = 7) THEN
      PRINT "Statement 3 is true"

    ELSE
      PRINT "No above statements are true"

    END IF
Output:
    No above statements are true

Multiple expressions

You can have more than one expression in IF...THEN by using either the OR operator or the AND operator.

The OR operator only requires one expression to be true in order to print "Yes" in the following program:
    x = 20

    IF (x = 5 OR x = 20) THEN PRINT "Yes"
Output:
    Yes

The AND operator requires both expressions to be true.
    x = 7

    IF (x > 5 AND x < 10) THEN PRINT "True"
Output:
    True

This is a slightly more complex example:
    x = 16
    y = 3

    IF ((x > 5 AND x < 10) OR y = 3) THEN PRINT "Correct"
Output (since Y is 3):
    Correct

Strings in IF...THEN

So far in this chapter, we've only been dealing with numbers, but you can also use strings with the IF...THEN command.
    x$ = "Hello"

    IF (x$ = "Hello" OR x$ = "World") THEN PRINT x$
Output:
    Hello

You can also compare two variable strings:
    x$ = "Hello"
    y$ = "World"

    IF (x$ <> y$) THEN PRINT x$; " "; y$
Output:
    Hello World

Labels and the GOTO and GOSUB
commands


The GOTO and GOSUB commands enables you to jump to certain positions in your program. Labels are used to specify what point in the program to continue execution.


GOTO

To use GOTO, place a label somewhere in your program, and then enter.
    GOTO <label>

Run the following example program:
    PRINT "1"

    GOTO TheLabel

    PRINT "2"


    TheLabel:

    PRINT "3"
Output (notice how PRINT "2" is skipped):
    1
    3

TIP: TheLabel can be placed on the same line as PRINT "3"

TheLabel: PRINT "3"



GOSUB

The GOSUB command is the same as GOTO, except when it encounters a RETURN statement, the program "returns" back to the GOSUB command. In other words, RETURN continues program execution immediately after the previous GOSUB statement.

    PRINT "1"

    GOSUB TheLabel

    PRINT "2"

    END


    TheLabel:

    PRINT "3"

    RETURN
(Note: The END command exits the program.)

Since the program returns to the GOSUB command, the number 2 is printed this time.
    1
    3
    2

Line numbers

"Line numbers" can be used as labels.
    PRINT "1"

    GOTO 10

    PRINT "2"

    10 PRINT "3" 
     (Notice the line number)

You can also write the program like this:
    10 PRINT "1"

    20 GOTO 40

    30 PRINT "2"

    40 PRINT "3"

The line numbers don't even have to be in sequence.
    17 PRINT "1"

    2 GOTO 160

    701 PRINT "2"

    160 PRINT "3"

Each of these programs output:
    1
    3

Guessing game

The following is a simple guessing game:
    CLS

    start:
    PRINT "Guess a number between 1 and 10: ";
    INPUT num

    IF (num < 1 OR num > 10) THEN
      PRINT "That is not between 1 and 10"
      GOTO start
    END IF

    IF (num = 6) THEN
      PRINT "Correct!!!"
    ELSE
      PRINT "Try again"
      PRINT
      GOTO start
    END IF
Output (may be slightly different):
    Guess a number between 1 and 10: ? 2
    Try again

    Guess a number between 1 and 10: ? 
    7
    Try again

    Guess a number between 1 and 10: ? 
    6
    Correct!!!

TIP: Notice the second PRINT statement under PRINT "Try again". It adds a blank line under Try again when the program is executed.

Loops


"Loops" make it easier to do an action multiple times. There are at least four types of loops: IF...GOTO, WHILE...WEND, DO...LOOP, and FOR...NEXT.


IF...GOTO

This program uses IF...GOTO to create a loop:

    x = 10

    start:
    PRINT x

    x = x + 1  
    (This adds 1 to x)

    IF x < 15 THEN GOTO start
Output:
    10
    11
    12
    13
    14

WHILE...WEND

The WHILE...WEND commands continue a loop until a specified expression is false.

To use WHILE...WEND:
  1. Place an expression after WHILE

  2. Enter a list of commands

  3. Place WEND at the end


Run the following:
    x = 10

    WHILE x < 15

      PRINT x

      x = x + 1

    WEND
Output (same as in previous example):
    10
    11
    12
    13
    14

DO...LOOP

DO...LOOP is exactly the same as WHILE...WEND, except it has at least two slight advantages. With DO...LOOP you can:
  1. Loop until an expression is true

  2. Loop at least one time regardless of whether the expression is true or not.


To use DO...LOOP:
  1. Specify whether the loop continues "while" the expression is true or "until" the expression is true, using the WHILE and UNTIL statements, respectively.

  2. Place an expression after WHILE/UNTIL

  3. Enter a list of commands

  4. Place LOOP at the end


The following uses the WHILE statement:
    x = 10

    DO WHILE x < 15

      PRINT x

      x = x + 1

    LOOP

This program uses the UNTIL statement:
    x = 10

    DO UNTIL x = 15

      PRINT x

      x = x + 1

    LOOP

They both output:
    10
    11
    12
    13
    14

If you place the expression at the end of the loop instead, the program goes through the loop at least once.
    x = 32

    DO

      PRINT x

      x = x + 1

    LOOP WHILE x < 5
This is the output because the loop was only gone through one time:
    32

FOR...NEXT

FOR...NEXT provides an easier way to create a loop.

    FOR x = 1 TO 5

      PRINT x

    NEXT x
Output:
    1
    2
    3
    4
    5

TIP: The X after NEXT is optional (unless you have a loop within a loop).


Also, you can use the STEP attribute to specify how much X will be increased each time through the loop.
    FOR x = 1 TO 5 STEP 2

      PRINT x

    NEXT x
Output:
    1
    3
    5

STOPPING LOOPS

To stop a loop prematurely, use the EXIT command, followed by either FOR or DO.
    FOR x = 1 TO 5

      PRINT x

      IF (x = 3) THEN EXIT FOR

    NEXT x
Output:
    1
    2
    3
(NOTE: This command only works with the DO...LOOP and FOR...NEXT commands, not with WHILE...WEND or IF...GOTO.)
What next?

If you want, you can move on to a more advanced programming language. The rest of this chapter briefly explains how you can start using the most popular ones.

One reason you may want to move on, at least at some point, is because QBasic has minimal capabilities. One example of this is that you can't create executable programs (EXE files) in QBasic. (QuickBasic 4.5 can create these files, but this product is no longer on the market.) To get back to my site from any one of these links just click your back arrow.


Other programming languages

Information about the below programming languages can be found at ProgrammingTutorials.com.


C and C++

You can learn C by going to www.cm.cf.ac.uk/Dave/C/CE.html, www.strath.ac.uk/CC/Courses/NewCcourse/ccourse.html, or www.programmingtutorials.com/tutorial.asp?id=C.

Before you can create an EXE file in C, you must have a compiler. I recommend downloading the DJGPP compiler. This program is free, however, the author does accept donations.

See below for information on getting DJGPP.

You may also want to get the Allegro programming library. This library is useful for creating games in C.

(NOTE: C++ is a more powerful version of C. It introduces "object oriented" programming. I recommend learning C++ before moving on to Visual C++.)


Visual C++

With Visual C++, you can create Windows 95 programs, instead of DOS. It costs about $100 for the standard version.

Visual Basic

Visual Basic is similar to QBasic. So, if you are highly involved in QBasic, then you may want to switch directly to Visual Basic, instead of learning C/C++ or Visual C++.

With Visual Basic, like Visual C++, you can create Windows 95 programs. It costs about $100 for the "learning" edition.




Getting DJGPP


Since the installation instructions for DJGPP are a little confusing, I've provided my own below.


Installing DJGPP

  1. Create a new folder called DJGPP in drive C.

  2. Download and save each of the following to the DJGPP folder:


  3. Unzip each of the files to the DJGPP folder.

    If you are using UNZIP32.EXE:

    1. Go to the Start Menu

    2. Click Run...

    3. Type the following (this loads MS-DOS):

        command  <Enter>

    4. Enter the following in DOS:

        cd c:\djgpp

        unzip32 -n *.zip


  4. Edit your AUTOEXEC.BAT file.

    1. Go to the Start Menu

    2. Click Run...

    3. Type the following (you can "copy and paste" it):

        notepad c:\autoexec.bat

    4. Add the following lines to the end of the file (you can "copy and paste" this also):

        set DJGPP=C:\DJGPP\DJGPP.ENV
        set PATH=C:\DJGPP\BIN;%PATH%

    5. Go to the File menu.

    6. Click Save.

    7. Close the program.

  5. Restart your computer.

  6. Run a program called RHIDE.EXE in the c:\djgpp\bin folder.
  7. Have fun with your new toy! 

There will Be More To Come. 

Want to go back to the main page?