Mathematical operators
The basic mathematical operators are the same as the ones available in most programming languages: addition (+), subtraction (-), division (/), multiplication (*) and modulus (%, which produces the remainder from integer division). Integer division truncates, rather than rounds, the result.
Java also uses a shorthand notation to perform an operation and an assignment at the same time. This is denoted by an operator followed by an equal sign, and is consistent with all the operators in the language (whenever it makes sense). For example, to add 4 to the variable x and assign the result to x, use: x += 4.
This example shows the use of the mathematical operators:
//: c03:MathOps.java
// Demonstrates the mathematical operators.
import com.bruceeckel.simpletest.*;
import java.util.*;
public class MathOps {
static Test monitor = new Test();
// Shorthand to print a string and an int:
static void printInt(String s, int i) {
System.out.println(s + " = " + i);
}
// Shorthand to print a string and a float:
static void printFloat(String s, float f) {
System.out.println(s + " = " + f);
}
public static void main(String[] args) {
// Create a random number generator,
// seeds with current time by default:
Random rand = new Random();
int i, j, k;
// Choose value from 1 to 100:
j = rand.nextInt(100) + 1;
k = rand.nextInt(100) + 1;
printInt("j", j); printInt("k", k);
i = j + k; printInt("j + k", i);
i = j - k; printInt("j - k", i);
i = k / j; printInt("k / j", i);
i = k * j; printInt("k * j", i);
i = k % j; printInt("k % j", i);
j %= k; printInt("j %= k", j);
// Floating-point number tests:
float u,v,w; // applies to doubles, too
v = rand.nextFloat();
w = rand.nextFloat();
printFloat("v", v); printFloat("w", w);
u = v + w; printFloat("v + w", u);
u = v - w; printFloat("v - w", u);
u = v * w; printFloat("v * w", u);
u = v / w; printFloat("v / w", u);
// the following also works for
// char, byte, short, int, long,
// and double:
u += v; printFloat("u += v", u);
u -= v; printFloat("u -= v", u);
u *= v; printFloat("u *= v", u);
u /= v; printFloat("u /= v", u);
monitor.expect(new String[] {
"%% j = -?\\d+",
"%% k = -?\\d+",
"%% j \\+ k = -?\\d+",
"%% j - k = -?\\d+",
"%% k / j = -?\\d+",
"%% k \\* j = -?\\d+",
"%% k % j = -?\\d+",
"%% j %= k = -?\\d+",
"%% v = -?\\d+\\.\\d+(E-?\\d)?",
"%% w = -?\\d+\\.\\d+(E-?\\d)?",
"%% v \\+ w = -?\\d+\\.\\d+(E-?\\d)??",
"%% v - w = -?\\d+\\.\\d+(E-?\\d)??",
"%% v \\* w = -?\\d+\\.\\d+(E-?\\d)??",
"%% v / w = -?\\d+\\.\\d+(E-?\\d)??",
"%% u \\+= v = -?\\d+\\.\\d+(E-?\\d)??",
"%% u -= v = -?\\d+\\.\\d+(E-?\\d)??",
"%% u \\*= v = -?\\d+\\.\\d+(E-?\\d)??",
"%% u /= v = -?\\d+\\.\\d+(E-?\\d)??"
});
}
} ///:~
The first thing you will see are some shorthand methods for printing: the printInt( ) prints a String followed by an int and the printFloat( ) prints a String followed by a float.
To generate numbers, the program first creates a Random object. Because no arguments are passed during creation, Java uses the current time as a seed for the random number generator. The program generates a number of different types of random numbers with the Random object simply by calling the methods: nextInt( ) and nextFloat( ) (you can also call nextLong( ) or nextDouble( )).
The modulus operator, when used with the result of the random number generator, limits the result to an upper bound of the operand minus 1 (99 in this case).
Regular expressions
Since random numbers are used to generate the output for this program, the expect( ) statement can’t just show literal output as it did before, since the output will vary from one run to the next. To solve this problem, regular expressions, a new feature introduced in Java JDK 1.4 (but an old feature in languages like Perl and Python) will be used inside the expect( ) statement. Although coverage of this intensely powerful tool doesn’t occur until Chapter 12, to understand these statements you’ll need an introduction to regular expressions. Here, you’ll learn just enough to read the expect( ) statements, but if you want a full description, look up java.util.regex.Pattern in the downloadable JDK documentation.
A regular expression is a way to describe strings in general terms, so that you can say: “If a string has these things in it, then it matches what I’m looking for.” For example, to say that a number might or might not be preceded by a minus sign, you put in the minus sign followed by a question mark, like this:
-?
To describe an integer, you say that it’s one or more digits. In regular expressions, a digit is ‘\d’, but in a Java String you have to “escape” the backslash by putting in a second backslash: ‘\\d’. To indicate “one or more of the preceding expression” in regular expressions, you use the ‘+’. So to say “possibly a minus sign, followed by one or more digits,” you write:
-?\\d+
Which you can see in the first lines of the expect( ) statement in the preceding code.
One thing that is not part of the regular expression syntax is the ‘%%’ (note the space included for readability) at the beginning of the lines in the expect( ) statement. This is a flag used by simpletest to indicate that the rest of the line is a regular expression. So you won’t see it in normal regular expressions, only in simpletest expect( ) statements.
Any other characters that are not special characters to regular expression searches are treated as exact matches. So in the first line:
%% j = -?\\d+
The ‘j = ’ is matched exactly. However, in the third line, the ‘+’ in ‘j + k’ must be escaped because it is a special regular expression character, as is ‘*’. The rest of the lines should be understandable from this introduction. Later in the book, when additional features of regular expressions are used inside expect( ) statements, they will be explained.
Unary minus and plus operators
The unary minus (-)and unary plus (+) are the same operators as binary minus and plus. The compiler figures out which use is intended by the way you write the expression. For instance, the statement
x = -a;
has an obvious meaning. The compiler is able to figure out:
x = a * -b;
but the reader might get confused, so it is clearer to say:
x = a * (-b);
Unary minus inverts the sign on the data. Unary plus provides symmetry with unary minus, although it doesn’t have any effect.