Showing posts with label comparison. Show all posts
Showing posts with label comparison. Show all posts

Monday, May 14, 2012

Java's Modulo Function--Wrapping Around

I've previously discussed operators in Java, where I gave a brief introduction to the modulo operator, %.

The percent sign is used in many computer languages as a brief, single-character symbol for the remainder of a division, not for a percentage of a number, as you might expect.

What's Left Over

In many calculations in normal day to day life, the remainder of a division is not very important. It's just the odd change left over at the end of doing division. With computer programs, however, modulos can be very useful and powerful.

One of its most important uses is to limit the range of a value. For example, if we're only interested in having a value be a number from 0 to 99, and any value over that is something we don't want, we can use modulo as a way of cutting any number we get down to size. Since the remainder of a division can never be as large or larger than the divisor, we know that any remainder from a division by 100 can never be more than 99 (in integers.) So we can take any number, find the modulo by some number that we want as an unreachable cap on our values, and never get a number that's too big.

limitedNumber = someNumber % 100

limitedNumber will never be higher than 99.

Real World Analogies

A real world version of this is a knob that you can turn around without a stop on it. The knob's setting can vary over a range of values all the way around it. But when you turn it past some point, it goes from its highest setting to its lowest setting.
Radio dial, image by John McComb of Oakland, CA.

For example, a radio dial that goes up in frequency until you hit the top of the radio band, then starts tuning over again from the bottom of the band.

Computer Applications

One of the most common uses of the modulo in computer programs uses that same ability with computer graphics. How many computer games have you seen where an object goes off one side of the computer's screen then reappears on the other side? That's an example of the modulo function. Let's look at an asteroid object that has its horizontal location on screen tracked by the member variable xLoc (short for x location):

Class Asteroid{
    int xLoc, yLoc, xSpeed, ySpeed, size;
    .
    .
    .
}


We'll assume the class has all the methods it needs to do what Asteroids do. Our instance is:

Asteroid asteroid = new Asteroid();
(If this is unfamiliar to you, you may want to read Creating a Java Variable, Two Steps.)

Now let's say our asteroid is presented on a screen area that is 800 pixels wide and 600 pixels high. That means our xLoc value can vary from 0 (the leftmost location on screen) to 799 (the rightmost location on screen) since we have a screen area 800 pixels wide. Remember, when we start counting at 0 our highest number is one less than the total number of pixels.

We can move our asteroid from left to right as follows:

xLoc = xLoc + xSpeed;

Where xSpeed is how fast we're moving across the screen.

The problem is, what do we do when we hit the right edge of the screen? That is, what do we do when xLoc is higher than 799?

If we want our asteroid to "wrap around" from the right side to the left side of our screen, the modulo operator is just what we want. We can do this to make it wrap around that way:

xLoc = xLoc + xSpeed;
xLoc = xLoc % 800; // Hard-coded screen width, for now.


That will make xLoc always be from 0 (when there is a zero remainder) to 799 (the highest possible remainder when dividing by 800.)

We might have a method in Asteroid like the following:

public int moveHoriz(int howFar){
  // Moves the Asteroid horizontally by howFar pixels on an 800 pixel wide screen.
  // returns the new pixel location.
  return (xLoc + howFar) % 800;
}


This glosses over a few other problems (like going from the left edge of the screen to the right), but illustrates the use of modulo to bring the object around from right to left again.


An Expanded Example

Here's a more developed example that deals with speeds higher than the screen width, and wraps both ways:

public int moveHoriz(int howFar){
  // Moves the Asteroid horizontally by howFar pixels on a screen.
  // It returns the new horizontal pixel location.

  // We have a screen width available to us in member variable xWidth,
  // and our x location in xLoc.
  // Wraps from right to left, or left to right.

  //Use modulo to trim speed if it's too high.
  if (howFar > xWidth) howFar %= xWidth;

  // Calculate the new x location and return it.
  return (xLoc + howFar + xWidth) % xWidth;
}


Radio Dial image by John McComb.
StumbleUpon

Wednesday, March 21, 2012

Java Introspection and Using Collections without Generics

In my prior article on Generics we looked at how to use Generics to associate at type with data stored in a Collection.

You might wonder why would anyone want to store information in a Collection without its type being preserved. Well, it's possible that you'd want to store many Objects of different types in one collection. In that case, the only parent those types might have in common is java.lang.Object. So using a Generic won't do you any good.

But, once you pull that data back out of the Collection, how do you find out what it was?

Fortunately, the object itself has that information stored with it.

There are two easy ways to find out what it is. instanceof can test if it is a specific type of Object:

if (anObject instanceof String) { aString = (String)anObject); }


You can also have an Object tell you its type:

Class myClass = anObject.getClass();

or

String myClassName = anObject.getClass().getName();


A look at the documentation for Object and Class gives all sorts of useful methods for dealing with classes of data objects in Java.

Here's some sample code:

import java.util.*;

public class NoGenerics2{
// This is an example of using introspection
// to determine types of Objects stored in a
// Collection without a Generic declaration.

public static void main(String[] arg){
ArrayList myList = new ArrayList(); // No Generic declaration.
String myString="Boss Moss";
String yourString="Snorkledorf";

// put the strings into the List
myList.add(myString);
myList.add(yourString);

for (Object anObject: myList){
System.out.println(anObject.getClass().getName());
if (anObject instanceof String){
String aString = (String)anObject;
}
else{
System.out.println("Not a String, Sheriff!");
}
}
}
}
StumbleUpon

Friday, June 24, 2011

Java Variable Value Assignment: Left Equals Right, Left Becomes Right

One of those things that vexes beginning programmers is assigning values to a variable in Java. Part of what makes it so vexing is that the problem is practically invisible to an experienced programmer. Another part of it is that we use the equals sign (=) to do the assignment.

Take a look at these statements:

int i = 1;
j=7;
7+count=c;
b+14=a+9;

The first two are fine (assuming that 7 is a valid value for whatever type of variable j is), but the last two are wrong.

Remember All That Algebra We Taught You? Well, We Broke It.

After you've gone to all the trouble to learn how to deal with things like 7+count=c and b+14=a+9 in algebra class, now we take what you know and turn it on its ear in programming class. Sweet, eh?

The problem is that the = we use in programming has pretty much nothing to do with the = that you use in math. It's just close enough to be confusing. In Java, the equals sign is an assignment operator, not an indicator of equality between values as it is in math. There is a comparison operator for equality in Java, it's ==, and we'll talk about it shortly. First, let's talk assignment.

Assignment

In computers, we use the term assignment to describe sticking a value into the computer's memory so that we can get it back later. It's like using the memory in a programmable calculator. We put some number into our calculator's memory so that we can get it back later for another part of our calculation. It's pretty much the same thing with computers.

With Java, we can store all kinds of values, not just numbers. We can store sections of text, called strings in a String variable, for example. (Java prefers the term "member" over variable, in general. For what we're talking about now, the two terms are interchangeable.) We can also store more than one thing at a time, like all the information about a bicycle in a Bicycle object that keeps track of a bicycle's color, frame size, tire size, gear ratios, etc., all together in one object.

But we're here to just look at assignment today, not the wide variety of things we can assign as values.

To store a value on a calculator, you use some key sequence like M+ or STO 00 to store the value in the calculator's display to memory. With Java, we use the equals sign to store some value on the right into whatever is on the left side of the equals sign. We read from left to right like this:

count = a;
"count equals a"

This means we take the value of a and place it in count. But a better way to read that equals sign is to use the word "becomes" instead of "equals":

count = 9;
"count becomes nine"

This makes it more obvious that we're putting in a new value that changes the value of count. In this case, we're putting in a value of 9. The statement up above would be "count becomes a" or, better yet, "count becomes a's value." Because what we're doing in count= a; is taking the value in variable a and copying it into count. If we then print the value in count, it will be the same as whatever is in a at that time.

We can also compute a value to put into our variable.

count = a + 1;
"count becomes a plus one"

This makes the value in count be one more than the current value of a.

What we can't do is change sides around the equals sign. In algebra, c = a + 1 is the same as a + 1 = c. But in Java that doesn't work:

a + 1 = count
This is wrong in Java. Does not compute. Norman, Norman, help me Norman!

We would be trying to make a+1 become the value in count. The problem is, you can't have a storage location named "a+1". Java doesn't see this the way your algebra trained eyes do.

Comparisons

In normal math, when we use the equals sign we are making a comparison. We are stating that what's on one side of the equals sign is the same as what's on the other side. For most algebra problems, we assume that the statement is true and try to find values for the variables that result in that.

Another use of equals in some math problems is to state that two things are equal when they may or may not be, then determine whether that statement is true or not. You remember those problems, they looked something like this:

State whether each of the following is true or false.
1. 11 = 6 + 5
2. 14 = 3 x 7
3 65 - 14 = 17 x 3


In Java, the equals sign is already used for assigning values to variables. How do we do a comparison to see whether it's true or not?

The == Operator

In some languages, = does both jobs. But in Java, there's a second operator for doing equality comparisons, ==, "equals equals". When we want to see if two values are the same, we compare them using a statement something like this:

if (count == 100) then stop();

This compares count to the value 100, and executes the method stop() if the result of the comparison is true.


The Dangers of the = Operator

Something to look out for is using = by accident in such a situation. Like this:

if (count = 100) then stop();
Don't do this if you want to compare count to 100!

What this does is assign the value 100 to count. If the assignment is successful (which it almost certainly will be, if the program compiles), the program will then do stop() every time it hits this statement! Because the assignment was successful, so the result is considered to be true.

Summary

The equals sign makes the variable on the left equal the computed value from the right side of the equals sign:

name = "Mergatroyd";
"name becomes Mergatroyd"

It doesn't work the other way around (putting something from the left into the variable on the right.)

If you want to compare to values to see if they're equal, use "equals equals":
if (state == "done") then exit();
"if state equals equals done then exit" or
"if state is equal to done then exit"
StumbleUpon