Basic Numeric Literals and Variables

One of the major aspects of a computer is that you can read or write values in its main memory. A computer’s main memory is often referred to as RAM, which stands for random access memory.

At the lowest level, RAM is just a series of millions and millions of 0s and 1s (bits) that the CPU can quickly change whenever it wants.

For example, a 64-bit computers would typically represent the number 65 as a series of 64 bits:

0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0100 0001

This is an example of a binary, or base 2, number. Everyday numbers like 65 are decimal, or base 10.

Binary works great for computers because it is so simple, but humans don’t like it as much. People find it hard to read and write all those 1s and 0s, making it both error-prone and tedious to use.

So instead, high-level programming languages like Processing do their best to use more human-friendly data. This includes base 10 numbers, ordinary characters, and even images and fonts.

Using Variables

To understand how make and use variables in Processing, we’ll focus just on the the int and float types. Let start with this simple example:

int age = 18;
println(age);

This code fragment prints 18 on the screen when you run it. Lets look at it in detail:

  • It consists of two individual statements, each ending with a ;.
  • The first statement defines age to be a new variable of type int, and then immediately assigns it the initial value of 18.
  • The second statement prints the contents of age to the screen.

The order of the statements is important. This won’t work:

println(age);   // Oops: age is not yet defined!
int age = 18;

Running this causes Processing to report an error in the first statement: it doesn’t know what age is in the first line because it hasn’t been defined yet. This is important: undefined variables in Processing always cause errors!

Another subtle but important detail is that the case of letters in a variable matter. For example:

int age = 18;
println(Age);   // Oops: Age is not the same as age!

When you run this, Processing reports an error in the second statement: it does not know of any variable called Age.

Defining New Variables

Now lets look just at the first statement:

int age = 18;

This declares age to be a new variable. All variable’s in Processing have a type, and age has the int. That means that age can only be assigned integer values, like 18 or -762.

In addition to declaring that age is a new variable, this statement also assigns it the initial value of 18. This is important, because in programming you always want to know what value a variable contains.

It’s often useful to imagine variable pictorially as boxes that contain a value. For example:

    +----+
age | 18 |
    +----+
     int

Be careful: you cannot declare two (or more) variables with the same name in the same part of your program. For instance, this doesn’t work:

int age = 18;
int age = 19;  // Oops: age is already declared!

If you run this in Processing, it will report that the second declaration of age is a duplicate definition.

Here’s an interesting example:

int age;      // oops: age not given an initial value
println(age);

Here, the Processing compiler reports an error, namely that age might not be defined. The problem is it doesn’t know what initial value to give to age.

Assigning Values to Variables

Assignment statements are used to assign new values to variables. For example:

int age = 18;   // variable definition

age = 19;       // variable assignment

This assignment statement over-writes the value in age and replaces it with 19.

Assignment statements look similar to definitions, but they don’t have a type in from of the variable.

It is unfortunate that Processing uses = to mean assignment. In mathematics, = means equality, i.e. a mathematical statement like x = y means “the value of x is the same as the value of y”. But = in Processing does not mean equality: = means assignment in Processing. Instead, x = y means “put a copy of the value of y into x”.

Here’s an interesting example of assignment statements:

int a = 5;
int b = 7;

int temp = a;
a = b;
b = temp;

println(a);  // prints 7
println(b);  // prints 5

The three statements in the middle show how you can swap the values of any two int variables, no matter their value. You should walk through every statement of this example, making sure you understand every step!

Literals for Numbers

Both ints and floats have pre-defined literal notations in Processing, i.e. ways of directly writing them as sequences of characters.

For example, these are all int literals: 365, -41, 0.

And these are some examples of float literals: 3.14, 365.0, 0.0, -88.1, 3.5e3. float literals always contain a decimal point, which is necessary to distinguish numbers like 365.0 and 365. The last example, 3.5e3 is an example of scientific notation. It means 3.5 times \(10^3\), and so is equivalent to 3500.0.

In this statement, we see both an int variable age and an int literal 18:

int age = 18;

Informally, we will often say that both age and 18 are ints. If it matters, though, we will be careful to specify if we are talking about an int variable or an int literal.

A basic fact about literals that is often left unmentioned because it is so fundamental, is that literals cannot change. Literals are constant values and so cannot be modified, so you are never allowed to write statements like these:

18 = age;  // oops: cannot assign a variable to a literal!

1 = 2;     // oops: cannot assign a literal to a literal!

Mixing floats and ints

Consider this example:

float temperature = 5;   // 5 is an int, but temperature is a float

println(temperature);    // prints 5.0

The first line assigns the literal int 5 to the float variable temperature. Since ints and floats are different, Processing automatically converts 5 to 5.0. This is called casting: the int 5 is cast to the float 5.0, which is then stored in temperature.

It’s possible to explicitly cast an int to a float using float like this:

float temperature = float(5);  // float(5) casts 5 to 5.0

You can also cast an int to a float, but it must always be done explicitly in Processing:

int count = int(3.0);  // int(3.0) casts 3.0 to 3

println(count);        // prints 3

You must write int(3.0), otherwise you can’t a compiler error. For example, this program does not compile:

int count = 3.0;  // oops, compiler error: cannot assign a float to an int
println(count);

Casting an float to an int will chop off any digits after the decimal point. For example:

int count = int(3.999);
println(count);  // prints 3

When you cast with int, no rounding is done. Instead, digits after the decimal point are always chopped off.

Questions

  1. Explain the difference between the statement x = y in mathematics, and the statement x = y in Processing.

  2. Explain the difference between an int literal and an int variable.

  3. Both the int type and the float type are used to represent numbers. What, exactly, is the difference between them?

  4. Each of the following code fragments has an error. Say what the error is, and show how to fix it:

    // fragment 1
    println(x);
    float x = 12.4;
    
    // fragment 2
    float eps;
    println(eps);
    
    // fragment 3
    int a = 1;
    int b = 2;
    int a = 3;
    println(a);
    println(b);
    
    // fragment 4
    int c = 0;
    2 = c;
    println(c);
    
    // fragment 5
    float int = 3;
    println(int);
    
  5. Explain what casting is in Processing. Give an example if an implicit cast, and an explicit cast (using int or float).

  6. What do each of the following code fragments print? If the code fragment does not compile, then say “compiler error”.

    // fragment 1
    int a = int(-2.0);
    println(a);
    
    // fragment 2
    int b = int(-2.9);
    println(b);
    
    // fragment 3
    int c = -2.0;
    println(c);
    
    // fragment 4
    int d = -2.5;
    println(d);
    
    // fragment 5
    float e = 2;
    println(e);
    
    // fragment 6
    float f = int(4.2);
    println(f);