Floats and Ints¶
Manipulating numbers is one of the most important and useful things a computer
can do. We’ll look at two number types in this course: int for integers
(i.e. whole numbers), and float for floating point numbers, i.e. numbers a
decimal point in them.
Integers¶
In Processing, an int is a whole number (i.e. an integer), such as:
4
-61
0
183993
These are called int literals to distinguish them from variables of
type int. For example:
int age = 18;
This statement does two things:
- It declares
ageto be a variable of typeint. - It assigns the value
18toage. Since this is the first value assigned toage, we say it initializesage.
Keep in mind that age is a variable of type int, while 18 is an
int literal. We usually refer to both as ints, but sometimes the
distinction matters.
Integer Arithmetic¶
You can perform arithmetic on ints using the basic arithmetic operators.
For example:
int averageLifespan = 82; // for Canadians
println(2014 + averageLifespan - 18); // 2078
Or:
int minsInOneHour = 60;
int hoursInOneDay = 24;
int daysInOneYear = 365;
int minsInOneYear = minsInOneHour * hoursInOneDay * daysInOneYear;
println(minsInOneYear); // 525600 --- about half a million minutes in a year
Integer Division¶
Dividing two ints always returns an int in Processing. For
example:
println(1 / 2); // 0
println(3 / 2); // 1
println(4 / 2); // 2
It might come as a surprise that 1 / 2 evaluates to 0. The “correct”
answer is 0.5, but the problem is that 0.5 is not an int (it’s a
float). So, after Processing divides two ints, if the result has
any non-zero digits to the right of the decimal point they get truncated (i.e.
chopped off). This is called integer division: dividing two ints
always returns an int.
There is one exception, though. Dividing by 0 is an undefined operation in
mathematics, and in Processing it causes an error, e.g.:
println(5 / 0); // ArithmeticException: / by zero
This statement crashes the program and issues the error message “ArithmeticException: / by zero”.
Min and Max Integers¶
It is important to know that there is a min int and a max int:
println(Integer.MIN_VALUE); // -2147483648
println(Integer.MAX_VALUE); // 2147483647
As this shows, the maximum value for an int in Processing is, exactly,
the number 2147483647, which is a little over 2.1 billion. Similarly, the
smallest int is a little less than -2.1 billion.
This means is that you cannot represent, say, the number 2.5 billion using an
int. It can also result in some weird calculations, e.g. here’s what
happens if you add 1 to the maximum int:
println(2147483647 + 1); // -2147483648
This is pretty disturbing when you think about it: by adding two positive numbers together we got a negative number!
Here’s another strange behaviour:
println(2147483648); // literal out of range
2147483648 is one more than the max int, so it is not an int. This
program doesn’t even run: You get a “literal out of range error” when you
compile this statement.
Another fact about ints is that there is one more negative int than
positive int. The smallest int is \(-2^{31} = -2147483648\), but
the biggest int is only \(2^{32}-1\). One place were this might be a
small problem is the abs(x) function, that should return x if x >=
0, and -x if x < 0. But the problem is what is abs(-2147483648)?
The correct answer is 2147483648, but 2147483648 is not an int: it’s
too big! In this one case, the abs function cannot possible return the
right answer, and so it does this:
println(abs(-2147483648));
// -2147483648
Note
Processing has a bigger integer type called long, which can
represent any integer in the range -9,223,372,036,854,775,808 to
9,223,372,036,854,775,807. That’s about -9.2 quintillion to 9.2
quintillion.
You may be interested to know that 9223372036854775807 has its own Wikipedia page, but -9,223,372,036,854,775,808 doesn’t.
If you need integers bigger than long, then Java (on which Processing
is based) has a special type called BigInteger that
can represent arbitrarily long integers that are limited only by the amount
of memory in your computer.
The Mod Operator¶
There’s one other useful int operator you should know about: the %
operator, which is called the mod operator, or the remainder operator.
For instance:
println(5 % 2); // 1
println(6 % 2); // 0
println(14 % 8); // 6
The expression 5 % 2 is read “5 mod 2”, and it calculates the remainder
when 5 is divided 2: since 2 goes into 5 two times with 1 left over, 5 % 2
equals 1.
One application of % is to test if a number is even or odd. For example,
178 % 2 is 0, which means 178 is even (because 2 goes into 178 exactly
89 times with 0 left over). In general, if n is a positive int and n
% 2 is 0, then n must be even. The only other possibility is that n %
2 is 1, which means n is odd.
Here’s an example of you might use % in animation. This program makes a
ball wrap-around the screen without using an if-statement:
float x;
void setup() {
size(500, 500);
}
void draw() {
background(255);
ellipse(x, 250, 100, 100);
x += 2;
x = x % 500;
}
Floating Point Numbers¶
In Processing, a float is a number with a decimal point in it, such as:
4.5
-61.2
0.0
-3.0
183.993
These are examples of float literals, which are so-named to
distinguish them from variables of type float. For example:
float speed = 1.8;
Here, speed is a variable of type float, while 1.8 is a float
literal. Just as for ints, this statement does two things:
- It declares
speedto be a variable of typefloat. - It assigns
speedthe initial value of1.8.
Floating Point Arithmetic¶
In most cases, floating point arithmetic works like regular arithmetic. For example:
println(1.2 + 3.2); // 4.4
println(6.0 - 3.344); // 2.7
println(2.1 * 3.14); // 6.594
println(-18.6 / 29.1); // -0.63917524
println(10.0 / 2.0); // 5.0
Notice that 10.0 / 2.0 evaluates to 5.0, which is a float.
Whenever you divide two floats, the result is always a float.
However, there are a few important details you need to be aware of.
Division by 0.0¶
Dividing a number by 0.0 is undefined mathematically, but for a float we
get a surprising result:
println(5.6 / 0.0); // Infinity
There is no error message here — the actual result is a special float
value called infinity. Another special float value occurs in this case:
println(5.6 / 0.0 - 5.6 / 0.0); // NaN
Again, this does not cause an error, but instead prints the special float
value NaN, which means “not a number”.
If you think about this, it leads to a strange conclusion: if x is a
float, then it is possible that x - x is not equal to 0.0!
The reasons when and how floats use these special values are quite
technical and beyond the scope of the course. The important thing for us is to
know that these values exist and can occur in ordinary calculations.
Min and Max floats¶
The smallest and largest float values are as follows:
println(Float.MIN_VALUE); // 1.4E-45
println(Float.MAX_VALUE); // 3.4028235E38
Notice a few things here:
- The numbers
1.4E-45and3.4028235E38are written in exponential notation, and are equivalent to \(1.4 \times 10^{-45}\) and \(3.4028235 \times 10^{38}\). - The min
floatis1.4E-45, and it is traditionally called machine epsilon. It is, approximately, the smallest possible number that we can represent as afloat. Any positive number less than1.4E-45is treated as equivalent to 0.0. - The max value,
3.4028235E38, is a huge number with 39 digits in it. However, only the first 8 or so digits are significant, i.e. after 8 digits all the digits are 0. - The smallest
floatis-3.4028235E38, which is just the negation of the maxfloat.
Rounding Errors¶
A major problem with floating point numbers is that they are often unavoidably
inaccurate. For example, in mathematics
\(\frac{1}{3} = 0.3333 \dots\), where the \(\ldots\) means there are
an infinite number of 3s after the decimal point. But a Processing
float can’t have an infinite number of digits:
println(1.0 / 3.0); // 0.33333334
As you can see, there are a finite number digits, plus the final digit has been rounded to 4. So it is not exactly equal to \(\frac{1}{3}\), but is instead a little bit bigger.
For many programs, round-off errors don’t make any noticeable difference. But sometimes they can be the source of serious bugs that are very hard to fix. There is an entire sub-field of computer science called numerical analysis that studies how to do accurate and efficient floating point arithmetic on machines.
In this course, we will usually just ignore round-off errors and hope that our floating point calculations are accurate enough.
Mixing ints and floats¶
You can often use ints and floats together without a problem. For
example:
println(4.0 + 5); // 9.0
In the expression 4.0 + 5, 4.0 is of type float, and 5 is of type
int. Processing doesn’t actually know how to add float and int,
so it automatically converts 5 into the float 5.0. This makes the
expression equivalent to 4.0 + 5.0, which is 9.0.
You can also assign an int to a float without error, e.g.:
float temperature = 21; // 21 is an int, but temperature is a float
This works because Processing automatically converts 21 to 21.0.
By default, you cannot assign a float to an int:
int age = 5.5; // compiler error
This statement fails to compile because 5.5 is of type float, and you
are not allowed to store a float in an int variable. However, you can
explicitly convert 5.5 to a float like this:
int age = int(5.5);
println(age); // 5
Summary Table¶
intfloatSample literals 4, -5, 0 -4.0, 3.14, 0,0 Min -2147483648 -3.4028235E38 Max 2147483647 3.4028235E38 Smallest positive 1 1.4E-45 When dividing by 0 run-time error infinity or NaN Special values none infinity, NaN
Questions¶
Give an example of:
- a positive
intliteral - a negative
intliteral - an
intliteral that is neither positive nor negative - statement that declares a new
intvariable and initializes it to 15
- a positive
What does this print?
println(5 * (1/2 + 1/3 + 1/4 + 1/5));
In regular arithmetic, \(\frac{5}{\frac{1}{2}} = 5 \cdot \frac{2}{1} = 10\). What does the equivalent expression,
5 / (1 / 2), evaluate to in Processing?What is the biggest possible
int? You answer should be accurate to within about 2 million.Suppose
nis a positiveint. Is the expressionn + 1always greater than 0? Why, or why not?What is the name of the
%operator?What are the values of the following expressions?
8 % 28 % 317 % 4(100 % 2) + (100 % 3) + (100 % 4)
Give an example of:
- a positive
floatliteral greater than 100 - a positive
floatliteral between 0 and 1 - statement that declares a new
floatvariable and initializes it to 3.14
- a positive
How many digits are there in the maximum possible
floatvalue? Your answer should be correct within 1 digit.What does
NaNstand for?What does this print?
println(91.22 / 0.0);
Give a simple example of an expression involving
floats that suffers from a round-off error.What does this print?
println(91.22 / 0);
What does this print?
println(int(6.9) + 3);
Answer “true” or “false” for each of the following questions:
- If
nis a positiveint, thenn + 1is also a positiveint. - If
aandbare both of typeint, anda > bis true, thena + 1 > bis also true. - If
nis a positiveint, thenn - nis0. - If
xis afloat, thenx - xis0.0.
- If