Data Types

The meaning of data type in programming

To properly define what is a data type in computer science, we must understand first what "type" means. After perusing the web for a definition, I found this:

-A category of people or things having common characteristics.

In computer science, in this case specifically for programming in Java, a data type is simply a categorization of things (objects) that have common characteristics. For illustration purposes, let us consider something we are all familiarized with: money. Since I am American, I am more familiarized with American currency. Therefore, I will use that for my first example.

American currency comes in bills or banknotes (generally referred as paper currency) and in metallic form called coins. Using the definition of data types, the generic data type known as "American Currency" can be further classified as "Paper Currency" and "Coin". Why do this? Because, although all forms of American currency have some common attributes, the truth is that a quarter and a one dollar bill have very little in common. However, a five dollar bill and a one dollar bill have much more in common.

Classifying objects by types

To model this for programming purposes, I need to understand how I need to categorize these different things in order to group like items. In this example, it makes sense to create two classes: One called "Coin" and the other one called "Bill" or "Banknote". All American coins are made of metal, but not the same metal. Therefore, I should add a data member that would hold the type of metal used to make this coin. Because the material doesn't change once the coin is made, I should make this data member a constant by adding the keyword "final" to the declaration of this data member. The same thing goes for the value of a coin. On the other hand, American banknotes are all made of paper. Although the type of paper can differ, let us assume it is the same for the sake of this illustration. Since "paper" is an inferred characteristic of a banknote that is identical regardless of value, the material doesn't need to be explicitly defined. Therefore, I will not include a data member to denote "material" in my paper currency class.

public class Coin
{
    private final double value; // final so value cannot be changed after creation
    private final String material;
    private final double size; // in millimeters
    ... (other properties omitted)

    public Coin(double value, String material, double size)
    {
        this.value = value;
        this.size = size;
        this.material = material;
    }

    public double getValue()
    {
        return value;
    }

    public String getMaterial()
    {
        return material;
    }

    public double getSize()
    {
        return size;
    }
}

public class Banknote
{
    private final int value; // int instead of double and material not included
    ... (other properties omitted)

    public Banknote(int value)
    {
        this.value = value;
    }

    public int getValue()
    {
        return value;
    }
}

Executable Example


public class CurrencyDemo
{
    public static void main(String[] args)
    {
        Coin penny = new Coin(0.01, "Copper-plated Zinc", 19.05);
        Coin nickel = new Coin(0.05, "Cupro-Nickel", 21.21);
        Coin dime = new Coin(0.1, "Cupro-Nickel", 17.91);
        Coin quarter = new Coin(0.25, "Cupro-Nickel", 24.26);

        Banknote oneDollar = new Banknote(1);
        Banknote fiveDollar = new Banknote(5);
        Banknote tenDollar = new Banknote(10);

        System.out.println("I have " + (oneDollar.getValue() + fiveDollar.getValue() + tenDollar.getValue()) + " dollars and " + (int)(100 * (penny.getValue()  + nickel.getValue() + dime.getValue()  + quarter.getValue())) + " cents.");
    }
}
To properly execute this, make sure you have both Coin and Banknote in your project's workspace.

This program outputs:


I have 16 dollars and 41 cents.

Due to the imprecise nature of primitive data types float and double, it is not recommended to use them when precision is required; for currency. According to Java Documentation, float or double should never be used when precision in calculation is required. Instead, the class BigDecimal should be used when calculation require a high degree of accuracy.

Primitives vs Reference types (objects)

In the previous section, I created two classes (reference types) called Coin and Banknote. Beginner programmers often struggle understanding what is a primitive data type and how they differ from reference types. Here are a few differences with a quick explanation for each one:
  1. A primitive type is predefined by the language and is named by a reserved keyword. Java has eight primitive data types: byte, char, short, int, long, float, double, and boolean.
  2. Primitive types have a specified size (determined by Java), with the exception of boolean. Reference types don't have a predetermined size. This is an advanced topic.

  3. Type Size
    byte 1 byte
    char 2 bytes
    short 2 bytes
    int 4 bytes
    long 8 bytes
    float 4 bytes
    double 8 bytes

  4. Reference types are stored in Heap memory and primitives are stored in Stack. This is also an advanced topic that will be discussed in a future blog.

Range of numeric primitives

There is one particular characteristic of Java numeric primitives that I neglected to mention when I first published this article and it is the concept of signed vs unsigned numbers. Unlike C++, there is no keyword to make a number unsigned. In Java, numeric primitives are signed all the time. The reason why this is important is because this fact affects the range of of values that can fit into a numeric primitive. This is because the Most Significant Bit (MSB) of a numeric primitive is reserved for the sign. A positive number will have a '0' as the MSB whereas a negative number will have a value of '1' in the MSB position. The remaining bits are used for the value. For example, a primitive byte is 8 bits in size where the lower 7 bits are used to hold the value. Therefore, a byte primitive in Java has a range of -128 to 127. The following table show the primitive data types and their respective range.

Type Min. Value Max. Value
byte -128 127
short -32,768 32,767
int -2,147,483,648 2,147,483,647
long -9,223,372,036,854,775,808 -9,223,372,036,854,775,807
float 1.40239846 x 10-45 3.40282347 x 1038
double 4.9406564584124654 x 10-324 1.7976931348623157 x 10308

Since primitive char is not a numeric data type, it does not follow the sign rule. Therefore, when typecast to a number, it is strictly unsigned. For that reason, its range it from Unicode '\u0000' (or 0) to '\uffff' (or 65,535).

A final note...

This illustration is good enough for a beginner programmer. Advanced programmers should know that I could've used an enumeration to model American currency instead of two classes. Or, I could've used abstract classes for Coin and Bill and children classes for the more specific types of coins and bills. Lastly, I could've demonstrated inheritance and polymorphism by creating a base class "Currency" from which "Coin" and "Banknote" could inherit the traits they both have in common (i.e. value).

Comments

  1. this blogs simply explains data type with the american mnoey so th author could explain it rally simple

    ReplyDelete
    Replies
    1. Thank you mac! I appreciate your endorsement. That was exactly my goal when I decided to use money to illustrate this concept. I am glad you liked it. Hopefully others did as well.

      Delete

Post a Comment

Popular posts from this blog

Combining State and Singleton Patterns to Create a State-Machine

The Beauty of the Null Object Pattern

Java Keywords (Part I): Creating Classes