Observation, Knowledge and the Decimal Point

Java knowledge and observation - image of spectacles on keyboard

In the last two posts (“RTFM” and “RTFS”) I looked at the importance of reading the manual and the screen.

In this post, I want to emphasize the importance of knowledge and observation. 

Knowledge — knowing the rules of the Java language. 

Observation — really seeing what you’re looking at while you’re coding and debugging.

Example 1

Let’s look at a small example:

public class Example {

    public static void main (String args[]) {

        System.out.println("7/4  = " + 7/4);   // line 1.
        System.out.println("7./4 = " + 7./4);  // line 2.

    }

} // end of class

What happens when you run the program? What gets printed?

The output will be the following:

7/4  = 1
7./4 = 1.75

Why two different values? Did you expect that? We all know that in real life when we divide seven by four we get 1.75. But here we get two different results. Why?

We know that Java is a strongly typed language. Every variable, literal and expression has a type. When mixing compatible types in an expression, we must be aware of the rules of type promotion and the type of the resulting value.

Java language rules say that a literal number containing only digits and no decimal point has the default type of int. If a literal number contains digits and a decimal point it defaults to type double.

So the expression 7/4 in line 1 contains an int divided by another int. This can only result in another int, i.e. the value of 1.

However, the expression 7./4 in line 2 has a decimal point after the 7. The expression then contains a double divided by an int. The int literal is then promoted to a double to balance the operation. The expression becomes a double divided by an double resulting in a double with the value of 1.75.

The single decimal point is easy to miss when debugging your code, so an eagle eye is needed. Two sets of eyes are better than one, so enlist the help of a colleague if you’re battling when debugging.

Example 2

Let’s add three more lines to the previous code:

public class Example {

    public static void main (String args[]) {

        System.out.println("7/4  = " + 7/4);   // line 1.
        System.out.println("7./4 = " + 7./4);  // line 2.

        int value = 42;
        System.out.println("value/0.0  = " + value/0.0);   // line 3.
        System.out.println("value/0    = " + value/0);     // line 4.
    }

} // end of class

What happens when you run the program?

The output is now:

7/4  = 1
7./4 = 1.75
value/0.0 = Infinity
Exception in thread "main" java.lang.ArithmeticException: / by zero
        at Example.main(Example.java:10)

Another “What?” Was that expected? Again we get two different results.

This was caused by a decimal point in the number in line 3, but no decimal point in line 4. This is the same cause as the different values in example 1, but here there is a very different end result with a more complicated explanation.

We know that in mathematics if we divide anything by zero, we get infinity as a result. So the output from line 3 should have been expected. But line 4 throws an ArithmeticException: / by zero? What happened there?

The answer is that floating point types and integral types are represented internally in computer memory in different ways.

Integral data types are stored in positional notation where each bit represents a power of two. The leftmost bit of the number is used as the sign bit (0 for positive numbers; 1 for negative numbers). Negative numbers are represented using two’s complement arithmetic. Integral data types have no representation of infinity.

Floating point data types are stored in mantissa and exponent form where the number and the exponent are stored separately in different bytes of the double and float. Floating point numbers follow the IEEE–754 Standard for Floating-Point Arithmetic. This was established in 1985 by the Institute of Electrical and Electronics Engineers (IEEE) to solve problems and promote portability across the many different floating-point implementations at the time.

Not only are floating point and integral data types represented differently in memory, but they are processed by different parts of the computer’s CPU (central processing unit). An ALU (arithmetic logic unit) performs arithmetic and bitwise operations on integral binary numbers. An FPU (floating-point unit) operates on floating point numbers. Most hardware FPUs use the IEEE 754 standard.

Compiler Warnings

We can get some help from the Java compiler to help us catch at least one of the problems we came across in this post.

The compiler has a number of options (some standard; some non-standard) that we can use when compiling code. A very useful option is the -Xlint non-standard option. This can warn us of a variety of potential problems.

We can use -Xlint:divzero to warn us of dividing by a integral literal zero.

Running javac -Xlint:divzero Example.java would give us the following output:

Example.java:10: warning: [divzero] division by zero
        System.out.println("value/0   = " + value/0);

Both -Xlint and -Xlint:all can be used to enable all the available compiler warnings. Enabling warnings is highly recommended.

Ending Off

These two simple examples stress the importance of having sharp eyes, reading the screen carefully and knowing the Java language rules well.

I hope you’ll share your comments and Java experiences. And if you found this post useful, please share it with others.


1 thought on “Observation, Knowledge and the Decimal Point”

  1. Pingback: NaN - Not a Number • 2022 • Incus Data Programming Courses

Leave a Comment

Your email address will not be published. Required fields are marked *

Code like a Java Guru!

Thank You

We're Excited!

Thank you for completing the form. We're excited that you have chosen to contact us about training. We will process the information as soon as we can, and we will do our best to contact you within 1 working day. (Please note that our offices are closed over weekends and public holidays.)

Don't Worry

Our privacy policy ensures your data is safe: Incus Data does not sell or otherwise distribute email addresses. We will not divulge your personal information to anyone unless specifically authorised by you.

If you need any further information, please contact us on tel: (27) 12-666-2020 or email info@incusdata.com

How can we help you?

Let us contact you about your training requirements. Just fill in a few details, and we’ll get right back to you.

Your Java tip is on its way!

Check that incusdata.com is an approved sender, so that your Java tips don’t land up in the spam folder.

Our privacy policy means your data is safe. You can unsubscribe from these tips at any time.