2

Why can't java gracefully return some value with a division by zero and instead has to throw an Exception?

I am getting an ArrayIndexOutOfBoundsException:0 This is because because damageTaken is actually an array of values that stores many different 'damages'.

In java I'm trying to create a progress bar. Our example: damage incurred, in a racing game, by setting the value for height as a percentage of maxmimum damage allowed before gameover.

At the start of the program damageTaken = 0;

(damageTaken / maximumDamage)

will give numbers between 0 - 1.

Then I just multiply that by the height of the progress bar, to create a fill bar of the appropriate height.

The program crashes. I want the progress bar to be of zero height!

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
Arif Driessen
  • 587
  • 2
  • 6
  • 8

5 Answers5

14

You are not dividing by zero, you are dividing zero by something.

It is completely allowed to take two halves of zero. The answer is zero. Say you have zero apples. You split your zero apples between Alice and Bob. Alice and Bob now both have zero apples.

But, you cannot divide by zero. Say you have two apples. Now, you want to give these apples to zero people. How many apples does each person get? The answer is undefined, and so division by zero is impossible.

Thomas O
  • 6,026
  • 12
  • 42
  • 60
  • 2
    Much simpler is, suppose if there existed an x such that 0*x = 1, then we have an immediate contradiction since 0 = 0*x = 1. – ldog Sep 28 '10 at 22:51
  • 1
    Yes. If division by zero was allowed then a multiplicative inverse must exist. For example if you claim 6 divided by 2 equals 3, you can prove it because 3*2 = 6. But you cannot say 6 divided by 0 equals 3 because 3*0 = 6 is never true. In calculus you might regard the limit of 1/x as going to infinity but this doesn't work in the real world. – Thomas O Sep 28 '10 at 23:00
  • 1
    Even in calculus it doesn't work unless you're very particular about the limit you take. Every direction of approach in the complex plane yields a different limit, assuming your topology can distinguish them. Which opens a whole new can of worms. – mokus Sep 29 '10 at 01:49
6
(damageTaken / maximumDamage)

This gives you a division by zero exception only if maximumDamage is zero.

If damageTaken is zero, there is no problem.

Eric Leschinski
  • 146,994
  • 96
  • 417
  • 335
abelenky
  • 63,815
  • 23
  • 109
  • 159
  • 3
    congratulations on being the only answerer to know the difference between a numerator and a denominator. – anthony Sep 28 '10 at 22:39
4

Just add a special case for 0;

private int getProgress()
    if (damageTaken == 0) {
        return 0;
    } else {
        return (damageTaken / maximumDamage) * progress.getHeight();
    }
}

However, (and it's a big however) the reason you are getting divide by 0 is because maximumDamage is 0, not damageTaken. So, what you probably really want is:

private int getProgress()
    if (maximumDamage== 0) {
        return 0;
    } else {
        return (damageTaken / maximumDamage) * progress.getHeight();
    }
}
jjnguy
  • 136,852
  • 53
  • 295
  • 323
  • Why are you multiplicating with the progress bar's height? I understood it the way that he wants to set the progress bar's height based on the percental value (so it's a vertical progress bar). – poke Sep 28 '10 at 22:38
  • @poke, he wants to find out how far the progress needs to be based on the percent of damage and the current height of the entire bar. – jjnguy Sep 28 '10 at 22:39
  • The first suggested technique 'special case for 0' adds nothing to what already happens if you just evaluate the expression. The result is zero in either case. – user207421 Jan 22 '14 at 00:20
1

Conceptually, having 4/0 yield some arbitrary number would be no worse than having an attempt to double a count of 2000000000 yield a count of -294967296. Most processors, however, will ignore most kinds of arithmetic overflow unless one explicitly checks for it, but cannot ignore an attempt to divide by zero unless one explicitly checks the operands beforehand (and skips the operation if they are invalid). Given that many processors have "overflow" flags, nothing would prevent a processor from specifying that an attempted divide-by-zero should simply do nothing but set the overflow flag (a successful divide operation should clear it); code which wants to trigger an exception in such a case could do so.

I suspect the reason for the distinct behavior stems from the early days of computing; the hardware for a division instruction could judge that it was complete when the remainder was less than the divisor. If that never happened, the instruction could get stalled until a general supervisory clock circuit (designed to signal a fault if for whatever reason instructions stop being executed) shut things down. Hardware to detect the problem and exit without stalling the CPU would have been trivial by today's standards, but in the days when computers were built from discrete transistors it was cheaper, and almost as effective, to tell programmers do not attempt to divide by zero, ever.

supercat
  • 77,689
  • 9
  • 166
  • 211
0

Let's stop talking about illegality, as though uniformed mathematics police were about to storm the room. ;) For the mathematical reasoning behind this, this related question is useful.

It is fair to ask why, after all this time, modern programming platforms don't handle division-by-zero errors for us in some standard way - but to answer the question: Java, like most any other platform, throws an error when division by zero occurs. In general, you can either:

  • Handle before: check the variable to be used as your denominator for zero before doing the division
  • Handle after: you can catch the exception thrown when the division by zero occurs and handle it gracefully.

Note that, as good practice, the second method is only appropriate when you wouldn't expect the variable to ever be zero under normal system operation.

So yes, you need a special case to handle this situation. Welcome to programming. ;)

Community
  • 1
  • 1
Dan J
  • 16,319
  • 7
  • 50
  • 82