Showing posts with label CALCULATIONS. Show all posts
Showing posts with label CALCULATIONS. Show all posts

Friday, 21 September 2012

Java's Assignment Operators

An assignment operator is a way of putting a new value into a variable.

I covered these briefly in Doing Math in Java, Part 1. Now I'll go into a bit more detail.

The Simple Assignment Operator

The simple assignment operator is =.

It places the value from the expression on its right side into the variable on its left.
This is covered in detail in Left Becomes Right.

Also see the Java Language Specification: The Simple Assignment Operator.

The Compound Assignment Operators

The compound assignment operators are:
+=, "plus-equals",
-=, "minus-equals",
*=, "times-equals" or "star-equals",
/=, "divided by-equals" or "slash-equals",
%=, "remainder-equals" or "percent-equals",
&=, "and-equals",
|=, "or-equals",
^=, "exor-equals" or "caret-equals",
>>=, "signed-shift-right-equals",
<<=, "shift-left-equals",
>>>=, "unsigned-shift-right-equals".

Commonality
Each of these operators has a variable to assign a value to before it, and an expression that results in a value after it:
variable operator expression

The expression has to result in a value that is compatible with variable's type.

Java will calculate the value of expression,

perform the calculation variable optype expression, where optype is the assignment operator without the equals sign.

Then it will place the result of that calculation into variable.

+=, "Plus-Equals"
Plus-equals adds the value after += to the original value of the variable, then puts the result into the variable.

-=, "Minus-Equals"
This subtracts the value after the operator from the original value in the variable, then stores the result in the variable.

*=, "Times-Equals"
Multiply the variable by the value on the right of the operator, put the result in variable.

/=, "Divided by-Equals"
Same as the above, but for division.

%=, "Remainder-Equals"
This finds the remainder of the variable's initial value divided by the value after the operator. That remainder is then put into the variable.

See Java's Modulo Operator--Wrapping Around for more information on how the remainder (or modulo) operator % works.

&=, "And-Equals"
And-equals does a bit-wise AND of the value after the assignment operator with the original value of the variable, then puts the results in the variable.

|=, "Or-Equals"
Or-equals does a bit-wise OR of the variable and the value after the operator. The result is placed in the variable.

^=, "Exor-Equals"
Exor-equals is short of Exclusive-Or Equals (and it is often written xor-equals). It does a bitwise exclusive-or of the variable and the value after the assignment operator, then puts the result into the variable.

>>=, "Signed-Shift-Right-Equals"
This does a signed right shift of the variable a number of times equal to the expression after the assignment operator. The result is placed in variable.

<<=, "Shift-Left-Equals"
This does the same thing as signed-shift-right-equals, except it does a signed left shift (each bit in the variable gets moved to the left expression times.

>>>=, "Unsigned-Shift-Right-Equals"
This one moves all the bits, unlike the signed shifts which leave the sign bit (highest order bit) alone.

Not Quite the Whole Story
That covers how these operators behave with numerical and other simple values. These operators have other behaviors when used with Strings, Arrays, and other complex value types. That goes beyond the scope of this article, however, more on that can be found at the links given under "Additional Information".

Additional Information
See the Java Language Specification: Compound Assignment Operators, Multiplicative Operators, Additive Operators, Bit-wise and Logical Operators.

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;
}

Doing Math in Java part 2:Functions

The basics of math in Java using operators was covered in Part 1: Operators. There I went over the standard operations built into the language itself, rather than in its APIs (libraries).

But that's hardly the end of useful math operations. Especially when doing graphics, where all those geometric and trigonometric functions come in so useful. Square root, cosine, absolute values, etc.

If you're wandering into the Java APIs unguided, the java.math package might catch your eye right away. Unfortunately, it's a false trail when what you're looking for is a simple general purpose math package (it's a nice special-purpose math package for particular sorts of calculation, however.)

What you really want is the java.lang.Math class, in the java.lang package.

This has most of the standard math functions you're used to. They're defined as static methods, so you don't need to create a Math object to use them. You just call them like this:

    float distance = Math.sqrt(dx*dx + dy*dy);
    float speed = Math.abs(velocity);


These call the square root function Math.sqrt() and absolute value function Math.abs(). There are a slew of others like degree to radian conversion, the standard trig functions, and so on.

Date Calculations

Calculations with dates are another standard sort of math that's not covered by standard operators. In the package java.util we've got the Calendar class. The Calendar class itself is an abstract class. This means that it's a class used to build other classes with, not to use directly. The GregorianCalendar class is a concrete implementation of Calendar that you can use directly. The Calendar object's add() method will add or subtract some amount of time--days, minutes, hours, etc.--to or from a given date (the date that the object is set to:

  1. Create a GregorianCalendar Object

  2. Set its date

  3. Use its add() method to add or subtract the time difference.

Example:
GregorianCalendar myDate;
myDate = new GregorianCalendar(2011, 6, 7); //set the date to 07 June 2011.
myDate.add(Calendar.Date, 165); // add 165 days to that date.


before(), after() and compareTo will return whether one date occurs before or after another. Computing the number of days between two dates is a bit more complex, unfortunately, as are similar calculations. Basically, the procedure is to use getTime() to convert both dates to time values, get the difference, then divide that by the time units you want to see the difference in (e.g. divide by 24 hours periods to get the difference in days.)

Unfortunately, the Calendar class demonstrates one of the problems with much of Java. It's an overly generalized class that prevents simple solutions to many simple and obvious problems. The older Date class took a more direct approach, but it has been deprecated in favor of the Calendar based classes. Unfortunately, even obtaining a printable date value according to the system's current locale takes a fair bit of set up in Java. A better solution would have been a very general class like Calendar behind a more usable class for solving conventional problems, but Java's development got it backward. We got the simple class first, it's inflexibility for solving certain problems resulted in criticism, then came a general class, which is no good at doing simple and obvious things for most users. The extra layer that we should have to make Calendar more usable has not yet appeared in the standard API (and possibly never will.)

So it takes a lot of code to do what should only take a line or two, when working with dates.

Still, give the Calendar and GregorianCalendar class a look-over. Even though it takes some extra code and set-up to do some simple tasks, the solutions to these problems are well established and many examples are available. It's just not as simple as System.out.println(myDate);

I'll be adding articles dealing specifically with dates myself at a future date.