|
Spring Semester 2002 |
if statements.
After each statement we list the correct version annotated in blue.
Condition must be enclosed in parens, and there is noif quarters > 0 then System.out.println(quarters + "quarters"); if (quarters > 0)thenSystem.out.println(quarters + "quarters");
then keyword in Java.
Condition must be enclosed in parens, and one parenthesis was missing.if (1 + x > Math.pow(x, Math.sqrt(2)) y = y + x; if (1 + x > Math.pow(x, Math.sqrt(2))) y = y + x;
We should always remember to useif (x = 1) y++; else if (x = 2) y = y + 2; if (x == 1) y++; else if (x == 2) y = y + 2;
== to test for equality
as = is used exclusively for assignment.
Presumably we want the condition to mean "both x and y are zero". But in that case we need to write a syntactically correct expression in which we refer to each variable in part: "(x is zero) and (y is zero)". The fact that later x is used as a coordinate eliminates all doubts that x might actually be a boolean variable (in which case the condition, as written originally, was correct).if (x && y == 0) p = new Point2D.Double(x, y); if (x == 0 && y == 0) p = new Point2D.Double(x, y);
if (1 <= x <= 10)
{ System.out.println("Enter y:");
y = console.readDouble();
}
if (1 <= x && x <= 10)
{ System.out.println("Enter y:");
y = console.readDouble();
}
Just like in the previous exercise we need to properly assemble a boolean expression
by putting together something that reads as follows: "(x is greater than or equal to 1) and (x is smaller
than or equal to 10)"
if (s != "nickels" || s != "pennies"
|| s != "dimes" || s != "quarters")
System.out.print("Input error!");
if ( !s.equals("nickels" ) &&
!s.equals("pennies" ) &&
!s.equals("dimes" ) &&
!s.equals("quarters") )
System.out.print("Input error!");
Remember to use equals when comparing Strings.
(!= is the negation of == ). Also, overall the code was supposed to implement an input error detection mechanism. If you think carefully about it, the error message should only appear if
s is not "nickels" and s
is not "pennies" and s is not "dimes"
and s is not "quarters". So that was another error in the code, that has been fixed in the solution posted above; and you can simplify this even further with DeMorgan, if you want to.
if (input.equalsIgnoreCase("N") || "NO")
return;
if (input.equalsIgnoreCase("N") ||
input.equalsIgnoreCase("NO") )
return;
The syntax of an OR operator requires a boolean expression
on its left and another boolean expression on its right. There's no factoring out
any common expression or part thereof.
First offint x = console.readDouble(); if (x != null) y = y + x; double x = console.readDouble(); y = y + x;
readDouble returns a
floating point number so the receiving variable should be able to hold the
fractional part. Then, a number cannot be compared with null
because their types are different: primitive vs. reference type. Finally, to fix the code you have two options: either drop the
if
statement (which is what we did above) or turn the code around by using
try and catch instead (as
explained in chapter 2), to specify what needs to be done if the user does
not enter a number at all, and just presses Return
(which presumably the original code was trying to do too).
language = "English";
if (country.equals("USA"))
if (state.equals("PR")) language = "Spanish";
else if (country.equals("China"))
language = "Chinese";
language = "English";
if (country.equals("USA")) {
if (state.equals("PR")) language = "Spanish";
} else if (country.equals("China"))
language = "Chinese";
The original code was missing a pair of braces. Without them the sequence of
decisions will never reach a situation where the country variable will be checked
for being "China" as the else statement is actually attached
to the second if (the one that checks if state is "PR") which is reached when
the String variable by the name of country is
"USA" already).
A syntactical construct that is made up of constants,
variables, method calls, and operators combining them:(a.length() >= 6)
An expression whose type (or final value) is boolean (and we have already
given an example of that above).
A syntactical unit in a program.
In Java a statement is either a simple statement, a compound statement, or a block.
x = x + 1;
Simple statements are atomic (more or less).
System.out.println("Atoms are complicated.");
Compound statements contain (are composed of) simple statements but not the
other way around. Compound statements can contain other compound statements as well.
if (x != 0) x = 0;
Compound statement that contains
one or more statements inside it (simple or compound) and
groups them together with the help of curly braces.
Advanced topic 6.1 (on page 230, in chapter 6, next chapter) contains extremely
important information about blocks. Meanwhile we have seen blocks being used here in
{ x = 10;
x += 1;
x += 1;
} if statements to avoid the dangling else
problem.
if/else /else statement and
nested if statements. Give an example for each.
The first is a particular case of the second. The particular aspect of the first one is its linear structure: the structure is in fact identical to the one that theswitchstatement has, except theswitchis not nearly as powerful. (Why?)As for examples, see pages 195-198 for details.
if/else /else statement where the order
of the tests does not matter. Give an example where the order of the tests matter.
The problem asks for one and the same structure so in our examples the two structures are identical. But if we move the conditions (and their corresponding alternatives, of course) around (for example by first checking for anif (score >= 96 ) grade = "A+"; if (score >= 96) grade = "A+"; else if (score >= 90 && score < 96) else if (score >= 90) grade = "A" ; grade = "A" ; else if (score >= 88 && score < 90) else if (score >= 88) grade = "A-"; grade = "A-"; else grade = "B" ; else grade = "B" ;
A-) then the first of the two examples will
still produce the right result, whereas the second one will produce only A-'s
and B's. The difference between the two implementations, of course, is that in the first one the conditions are distinct, disjoint, non-overlapping, whereas in the second one they're not.
The question is, of course, why -- because the actual answers can be easily checked with the help of a computer:"Tom" , "Dick" "Tom" , "Tomato" "church" , "Churchill" "car manufacturer", "carburetor" "Harry" , "hairy" "C++" , "Car" "Tom" , "Tom" "Car" , "Carl" "car" , "bar"
frilled.cs.indiana.edu%cat Check.java
public class Check {
public static void main(String[] args) {
System.out.println(
"Tom vs. Dick " +
"Tom".compareTo("Dick"));
System.out.println(
"Tom vs. Tomato " +
"Tom".compareTo("Tomato"));
System.out.println(
"church vs. Churchill " +
"church".compareTo("Churchill"));
System.out.println(
"\"car manufacturer\" vs. carburetor " +
"car manufacturer".compareTo("carburetor"));
System.out.println(
"Harry vs. hairy " +
"Harry".compareTo("hairy"));
System.out.println(
"C++ vs. Car " +
"C++".compareTo("Car"));
System.out.println(
"Tom vs. Tom " +
"Tom".compareTo("Tom"));
System.out.println(
"Car vs. Carl " +
"Car".compareTo("Carl"));
System.out.println(
"car vs. bar " +
"car".compareTo("bar"));
}
}
frilled.cs.indiana.edu%javac Check.java
frilled.cs.indiana.edu%java Check
Tom vs. Dick 16
Tom vs. Tomato -3
church vs. Churchill 32
"car manufacturer" vs. carburetor -66
Harry vs. hairy -32
C++ vs. Car -54
Tom vs. Tom 0
Car vs. Carl -1
car vs. bar 1
frilled.cs.indiana.edu%
For the why of it check pp. 191-192 in the book.
p, q,
and r.
p |
q |
r |
(p && q) || !r |
!(p && (q || !r)) |
|---|---|---|---|---|
| false | false | false | true | true |
| false | false | true | false | true |
| false | true | false | true | true |
| false | true | true | false | true |
| true | false | false | true | false |
| true | false | true | false | true |
| true | true | false | true | false |
| true | true | true | true | false |
How do we check if we are right or wrong? We ask the computer:
frilled.cs.indiana.edu%cat Boole.java
public class Boole {
public static void main(String[] args) {
boolean p, q, r;
p = false; q = false; r = false;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
p = false; q = false; r = true;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
p = false; q = true; r = false;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
p = false; q = true; r = true;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
p = true; q = false; r = false;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
p = true; q = false; r = true;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
p = true; q = true; r = false;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
p = true; q = true; r = true;
System.out.println( ((p && q) || !r) + " " + (!(p && (q || !r))) );
}
}
frilled.cs.indiana.edu%javac Boole.java
frilled.cs.indiana.edu%java Boole
true true
false true
true true
false true
true false
false true
true false
true false
frilled.cs.indiana.edu%
A && B is the same as B && A for any Boolean
conditions A and B?
For all practical purposes in this class: yes, but check at the bottom of page 208 for "lazy evaluation". We will revisit this question later, in chapter 7.
ands = 0; if (x > 0) s++; if (y > 0) s++;
The first of the two contains three statements one after another. The second one only two. For x > 0 and y > 0 the first code sets s to 2, while the second one to 1, incrementing only once. Draw the diagrams to see the effect of thes = 0; if (x > 0) s++; else if (y > 0) s++;
else alternative.
!(x > 0 && y > 0) x <= 0 || y <= 0
!(x != 0 || y != 0) x == 0 && y == 0
!(country.equals("USA") && !state.equals("HI") && !state.equals("AK")) !country.equals("USA") || state.equals("HI") || state.equals("AK")
!(x % 4 != 0 || !(x % 100 == 0 && x % 400 == 0)) x % 4 == 0 && (x % 100 == 0 && x % 400 == 0) This can be further simplified tox % 400 == 0
-else
problem, using the following statement. A student with a GPA of at least 1.5, but less
than 2, is on probation. With less than 1.5, the student is failing.
if (gpa > 1.5) {
if (gpa < 2)
System.out.println("Probation.");
} else System.out.println("Failing.");
Without the curly braces the else would migrate (change position).
== operator and the
equals method when comparing strings.
The first operator checks if the two
Also see sections 5.2.3 and 5.2.4 in the book.
Strings are
stored in the same place (which means that they are in fact one and the same object). The other
one checks to see if they would look the same if printed (case sensitive). You should always use
the second one over the first.
andr == s
where bothr.equals(s)
r and s are of type Rectangle.
The first operator checks if the two
Also see sections 5.2.3 and 5.2.4 in the book.
Rectangles are
stored in the same place (which means that they are one and the same object). The other one checks
to see if you knew you drew more than one if you were to draw them (if one equals
the other they'd be drawn on top of each other and as such you wouldn't be able to tell two have
been drawn instead of one).
r is null?
What happens when this code runs?
If the variable does not get initialized before the test we would get an error message at compile time. Otherwise it depends how theRectangle r; ... if (r.equals(null)) r = new Rectangle(5, 10, 20, 30);
equals method is implemented in class Rectangle and you would find that here. (If the variable
r points to a real Rectangle the result can only be false).
To check if r is null or not use the == operator.
Write Java code to test whether two objects of type
Line2D.Double represent the same line when displayed
on the graphics screen. Do not use a.equals(b).
Line2D.Double a;
Line2D.Double b;
if (a.getP1().equals(b.getP1()) && a.getP2().equals(b.getP2()) ||
a.getP1().equals(b.getP2()) && a.getP2().equals(b.getP1()) ||
)
g2.drawString("They look the same!", x, y);
Hint: If p and q are
points, then Line2D.Double(p, q) and
Line2D.Double(q, p) look the same.
Check the API for accessors used in the condition above (which is implementing the hint).
n equals
10 and whether a floating-point number x equals 10.
Inevitable lack of precision, with floating-point numbers.
For an integern this would be a good test:
For a floating-point number n == 10
x this would be a good test:
Also see section 5.2.2 in the book and the following (next) exercise in this quiz.
Math.abs(x - 10) <= 1E-14 * Math.max(Math.abs(x), Math.abs(y))
x and y
such that Math.abs(x - y) is larger than 1000, but x and
y are still identical except for a roundoff error.
For example
vs.
1E18
To see how this could happen consider the following:
(1E18 + 1001)
frilled.cs.indiana.edu%cat Test.java
class Test{
public static void main(String[] args) {
double x = 10.0; // original value
double y = Math.sqrt(x); // compute square root
double z = y * y; // recover the original number (hopefully)
System.out.println("x = " + x + " y = " + y + " z = " + z);
// so z and x are "the same" now -- hopefully we agree on that
double result = (x - z);
// but result is > 0 (though small enough)
// so yes, x and z are one and the same (really)
System.out.println(x + " - " + z + " = " + result);
// so x and z are equal (approximately)
x = x * 1E18;
z = z * 1E18;
// they're still equal, aren't they - multiplied by the same number
System.out.println(x + " is a roundoff error of\n" + z);
System.out.println("Their difference: " + (x - z));
// so look at their difference now, equal as x and z are
// difference is now 2,048 but absolute value means nothing
// it's the ratio of this error to the magnitude of the two
// numbers that really counts 2,048/1e18 is still 1e-14...
}
}
frilled.cs.indiana.edu%javac Test.java
frilled.cs.indiana.edu%java Test
x = 10.0 y = 3.1622776601683795 z = 10.000000000000002
10.0 - 10.000000000000002 = -1.7763568394002505E-15
1.0E19 is a roundoff error of
1.0000000000000002E19
Their difference: -2048.0
frilled.cs.indiana.edu%
Consider the following test to see whether a point falls inside a rectangle.
Point2D.Double p = ...
boolean xInside = false;
if (x1 <= p.getX() && p.getX() <= x2)
xInside = true;
boolean yInside = false;
if (y1 <= p.getY() && p.getY() <= y2)
yInside = true;
if (xInside && yInside)
g2.drawString("p is inside the rectangle.", x1, y1);
Rewrite this code to eliminate the explicit true and false values,
by setting xInside and yInside to the values of Boolean expressions.
Point2D.Double p = ...
boolean xInside = (x1 <= p.getX() && p.getX() <= x2);
boolean yInside = (y1 <= p.getY() && p.getY() <= y2);
if (xInside && yInside)
g2.drawString("p is inside the rectangle.", x1, y1);
We mentioned in class that
<condition>) a = true; else a = false; is equivalent toboolean a; if (
<condition>; always. So we can often simplify, as needed.boolean a =