# Java Puzzlers

Onze verontschuldigingen, dit bericht is alleen beschikbaar in Amerikaans Engels. Voor het gemak van de kijker, is de inhoud hieronder weergegeven in de alternatieve taal. Je kunt klikken op de link om naar de actieve taal over te schakelen.

As we all know, there is no system that works perfectly… never mind, Java is that kind of system too. Every system has his own crutches, errors and unexpected shutdowns (sometimes without explaining the reason, yeah, iPhone users, I am talking about you!).

Today we will talk about Java pitfalls, corner cases and traps.

To be honest, I was inspired by the Joshua Bloch & Neal Gafter book to write this article, Java Puzzlers: Traps, Pitfalls, and Corner Cases. I was reading it and got an idea that this can be not only interesting to read, but also worth sharing.

#### Oddity check

The first situation that I would like to explain, it’s about the oddity check.

How do we usually check if a number is odd? Easy, if the division by 2 gives us a remainder of 1, then the number is odd, isn’t it? Below is the method that does this.

```public static boolean isOdd(int i){
return i % 2 == 1;
}

public static void main(String[] args){
System.out.println(isOdd(11));
System.out.println(isOdd(-11));
}

```

After running this code, here’s what we will see in the output:

```>>>> true
>>>> false

```

Wait, what?

Unfortunately, it doesn’t work as we expected it to. This method returns a wrong answer one quarter of the time. Why one quarter? Because half of all int values are negative, and the `isOdd` method fails for all negative odd values. It returns false when invoked on any negative value, whether even or odd.

Let’s dig deeper, how does Java remainder operator work?

`a - ( (a/b) * b ) == a`

Okay. How can we fix it? Let’s see…

```public static boolean isOdd(int i){
return i % 2 != 0;
}

```

Now, running that code again will give us the following output:

```>>>> true
>>>> true

```

It’s fixed, we are brilliant!

#### Decimal place accuracy

All right, let’s move on! Imagine you are on your way home from a volleyball game and suddenly one of your car’s headlights burned out. Sad. You stop at the closest gas station to buy a new one. Luckily they cost only \$1.10 and you got \$2 bill. So you expect to get your 90 cents back.

```public static void main(String[] args){
System.out.println(2.00 - 1.10);
}

```

After executing the code above we get this:

```>>>> 0.8999999999999999

```

Hmm, it doesn’t look good? You were too naive to expect 0.90 in this article. Anyway, how could it know that you wanted two digits after the decimal point?

If you would’ve read about the rules of converting double values to strings, which are specified in the documentation of `Double.toString()` method, you would know that the program prints the shortest decimal fraction sufficient to distinguish the double value from its nearest neighbor, with at least one digit before and after the decimal point. The problem is that the number 1.1 can’t be represented exactly as a double, so it is represented by the closest double value. More generally, the problem is that not all decimals can be represented accurately using binary floating-point.

One of the solutions is to use `printf`:

```System.out.printf("%.2f%n", 2.00 - 1.10);

```

Another option would be to make use of `BigDecimal`s:

```System.out.println(new BigDecimal("2.00").
subtract(new BigDecimal("1.10")));

```

Regardless of what you will choose, you’ll get your 0.90 cents.

#### Division of large numbers

Next case! Have you ever had to divide two really big numbers, for instance to divide the amount of microseconds in a day by the amount of milliseconds in a day? I guess not, but imagine there is a task to code that or you are doing it just for fun.

As far as we have already covered two pitfalls, we are sure that we’ll do it right this time. At least we hope so…

We write a nice, clean and really straightforward code.

```public static void main(String[] args){
final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;
final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;

System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY);
}

```

The output that we are expecting is 24 hours/day · 60 minutes/hour · 60 seconds/minute · 1,000 milliseconds/second · 1,000 microseconds/millisecond divided by amount of miliseconds. So, we are expecting 1000 but it prints…

```>>>> 5

```

Again???

So, what exactly went wrong? The problem is that `MICROS PER DAY` does overflow. We are multiplying all `int` values.

How can we fix it?

```public static void main(String[] args){
final long MICROS_PER_DAY = 24L * 60 * 60 * 1000 * 1000;
final long MILLIS_PER_DAY = 24L * 60 * 60 * 1000;

System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY);
}

>>>> 1000

```

Yeah, got it now (notice the L next to 24).

#### String concatenation

Here’s another situation, tricky but not less interesting – it’s all about concatenation!

Let’s say we would like to check if the length of two strings is equal (why not?) Okay, now we feel really confident, we know about AT LEAST four Java traps. Let’s do it!

```public static void main(String[] args){
final String firstString= "length: 10";
final String secondString= "length: " + firstString.length();

System.out.println("Strings are equal: " + firstString == secondString);
}

```

What are we expecting?

```>>>> Strings are equal: false

```

Of course they are not, but wait…

```>>>> false

```

What’s wrong this time? The `+` operator, whether used for addition or string concatenation, binds more tightly than the `==` operator.

So, the rule for string concatenation is : “always parenthesize non-trivial operands”.

How to fix it? Check it out!

```System.out.println("Strings are equal: " + (firstString == secondString));

>>>> Strings are equal: false

```

We did it again!

#### Working with Integer.MAX_VALUE

Do you remember what Integer’s max value is? Or maybe something around it? So you are being really careful right now writing a smart piece of code that will find this number, here we go:

```public static final int END = Integer.MAX_VALUE;
public static final int START = END - 10;

public static void main(String[] args){

for(int i = START; i <= END; i++)
System.out.println(i);
}

```

And what do we expect? Right – 2147483638, 2147483639, 2147483640 etc.!

But… it looks like this code won’t stop and will loop forever or until you won’t kill it. What’s the problem? The thing is that the loop continues as long as the loop index `i` is less than or equal to `Integer.MAX_VALUE`, but all `int` variables are always less than or equal to `Integer.MAX_VALUE`. It is, after all, defined to be the highest `int` value in Java. When it reaches `Integer.MAX_VALUE` and performs the incrementation, it silently wraps around to `Integer.MIN_VALUE`.

How can we fix it? Take a look:

```for(long i = START; i <= END; i++)
System.out.println(i);

>>>> 2147483638
2147483639
2147483640
2147483641
2147483642
2147483643
2147483644
2147483645
2147483646
2147483647

```

Amazing, we are awesome!

Now you know that you have to be really careful and check your code several times before saying with certainty that it works correctly. Sometimes these little hidden “bugs” might make your program work unexpectedly and cause you trouble later on.

Hope you enjoyed it!

Share this article:

Alexandru M.
Java Developer