Mixing Things Up
Managing Mathematical Differences.
Remember the examples from the previous topic.
totalDrinkPrice = ( LemonadeDrinkers * priceOfLemonade )
+ ( numberOfColaDrinkers * priceOfCola );
priceDifference = ( LemonadeDrinkers * priceOfLemonade )
– ( numberOfColaDrinkers * priceOfCola );
Getting promoted. These examples might make you want to think about how the Java programming language works with differing data types. Consider the following: For numberOfColaDrinkers, the appropriate data type to use would be an integer, since you cannot have a fractional cola drinker. Sure, some cola drinkers are small, but they are still considered whole human beings, so a "counting number" or a non-fractional data type such as the integer should be used. On the other hand, for the price of the cola, which comes in dollars and cents, there is obviously a need for a data type that can manage fractional quantities, such as the double data type.
The problem arises when one starts using them together, as was done in the example above. This is really not much of an issue because you expect a programming language to let its data types play well together. However, there may be some unexpected results if you do not understand the whole process. The action that occurs when you blend, for example, an integer and a double, is called mixed mode mathematics and it commonly leads to a process called promotion or coercion. This can also be called implicit casting, which will be discussed soon.
Promotion or coercion means that all of the data types used in an expression will be temporarily changed into the highest level data type in the expression only for the duration of the mathematical operation. When an integer and a double are used together, the Java compiler promotes the integer up so it looks like a double, then conducts the arithmetic. This allows the processing to be correct, and helps you get to the appropriate answer.
However, consider the following issue. What if you have to feed 72 people with 15 pans of lasagna. You would like to calculate how much lasagna will be served per person, and since you need a fractional result, you create a double variable called lasagnaPerPerson. You also (appropriately) create integer variables for your people and pans as shown.
int people = 72;
int lasagnaPans = 15;
double lasagnaPerPerson;
Then you implement the mathematical expression as shown.
lasagnaPerPerson = lasagnaPans / people;
You would expect the result to be something like .21 or about 1/5 of each pan per person. The result that comes from your calculation however is zero. Why would this happen? Consider the two variables with which the arithmetic was conducted. people and lasagnaPans are both integers. For that reason, the program implements integer arithmetic with them, and for that reason, the value .21 is truncated from the integer value 0.21 (i.e., the fractional part is cut off).
The way to resolve this is not particularly difficult, but you must learn a new keyword and term. If you think about TV or movies, you know that they cast certain people in certain roles. Pierce Brosnan was never really a spy, but he was cast as one in a couple of movies. In other words, the movie industry made him act like a spy to get their task completed.
You will be doing the same thing with your integers. You are going to cast at least one of your integers as a double so that it can act like a double long enough to get the task completed. And note that this is also called explicit casting as opposed to the implicit casting that is actually conducted by the compiler. This is the same process as getting promoted, but since the compiler does not always know when to promote things, you are forcing it to take the action. Here is how it works.
lasagnaPerPerson = (double)lasagnaPans / people;
Notice that only one of the two variables (i.e., lasagnaPans) was cast as a double. This will work fine since the compiler now will know to promote (or implicitly cast) the other variable (i.e., people), and the appropriate floating point arithmetic will be implemented. Now, consider the following code:
lasagnaPerPerson = lasagnaPans / (double)people;
lasagnaPerPerson = (double)lasagnaPans / people;
Either of these operations will provide a correct result. No matter how you work it, if one of the components in multiplication or division is a double, all of the elements will be coerced (or promoted, or implicitly cast) to a double, and from there the result will be correct.Make sure you understand what happens in this kind of operation, and more importantly, why.
This brief topic shows you how to get your data types to play well together, and to get to your goals when you are writing your programs. You must use the appropriate data types as you program, but you must also manage their limitations and characteristics as well. The next topic will show you how to implement some shortcuts for incrementing, decrementing, and mathematically modifying individual values.
Watch this video to see the concepts in this chapter tested. Again, make sure you can write the program that was used. At this point, you should be able to write programs like these in a few minutes.