29

I have an I2C device that wants two inputs: a denominator and a numerator. Both are written to separate addresses, so no actual calculation (numerator/denominator) is done. The problem with this is that a divide by zero could occur on the I2C device, so a divide by zero error needs to be checked for. Ideally, exactly the same thing would happen if the dividing were done by the java code.

At the moment, I've bodged an unused variable that does the division, but I'm worried it'll get optimized out:

public void setKp(int numerator, int divisor)
{
    int zeroCheck = numerator / divisor;
    //... doesn't use zeroCheck
}

Surely there's a better way!

Eric
  • 95,302
  • 53
  • 242
  • 374
  • The answers suggesting checking divisor directly seem better, but I can't imagine this getting optimized away. Sure the zeroCheck might not get assigned, but the division has a potential to throw an exception, so I can't imagine it actually being optimized away. – Yishai Nov 01 '09 at 18:35

5 Answers5

55

You should not throw an ArithmeticException. Since the error is in the supplied arguments, throw an IllegalArgumentException. As the documentation says:

Thrown to indicate that a method has been passed an illegal or inappropriate argument.

Which is exactly what is going on here.

if (divisor == 0) {
    throw new IllegalArgumentException("Argument 'divisor' is 0");
}
Joren
  • 14,472
  • 3
  • 50
  • 54
  • The OP specified: "Ideally, exactly the same thing would happen if the dividing were done by the java code." – Yishai Nov 01 '09 at 18:43
  • I concur. My answer was only addressing how to get the same behavior as you would if you actually divided by zero, not whether you should. – uckelman Nov 01 '09 at 18:44
  • 1
    Yishai, yes, but felt it was appropriate to second-guess that assertion. – Joren Nov 01 '09 at 19:07
  • There is some debate about this view. For example, some feel (as you would, I assume) that a null argument given to a method that doesn't accept null should cause an IllegalArgumentException to be thrown, while others believe that a NullPointerException should be thrown in this situation. – Laurence Gonsalves Nov 01 '09 at 19:27
  • 5
    I think NullPointerException should never be thrown manually, instead throwing IllegalArgumentException whenever a null is incorrectly passed to a method. If that's done, and you get a NullPointerException from a method, you are sure there is a bug in that code. If the method throws an IllegalArgumentException, you know that there is a bug in *your* code. I think that's an incredibly useful distinction. That said, I usually program in C#, and the distinction between NullReferenceException and ArgumentNullException is pretty clear on .NET. In Java I'm not so sure the intended design is the same – Joren Nov 01 '09 at 19:37
  • +1 The IllegalArgumentException is much more clear and specific. Especially if setKp(int numerator, int divisor) is a part of a public API. I second Joren on the NullPointerException not to be thrown manually (even though standard usage is disagrees). See this question http://stackoverflow.com/questions/3881/illegalargumentexception-or-nullpointerexception-for-a-null-parameter – Fedearne Nov 02 '09 at 09:36
  • `ArithmeticException` and `NullPointerException` are perfectly fine to throw. See Effective Java Item 38 https://books.google.nl/books?id=ka2VUBqHiWkC&pg=PA182&lpg=PA182&dq=effective+java+page+182&source=bl&sa=X Also in item 60 it describes `NullPointerException` as "Parameter value is null where prohibited", not "Null pointer accessed". Moreover Java 7 introduces `Objects.requireNonNull()` meant for method parameter checking, and it throws `NullPointerException` – Mark Jeronimus Sep 11 '15 at 09:30
  • As long as where you throw `NullPointerException` cannot cause a NPE some other way I think it is fine. For anybody analyzing the stacktrace it will be immediately clear that it came from the null check. – Daniel Bickler May 15 '17 at 15:51
19

Do this:

if (denominator == 0) throw new ArithmeticException("denominator == 0");

ArithmeticException is the exception which is normally thrown when you divide by 0.

Rob R.
  • 85
  • 2
  • 11
uckelman
  • 25,298
  • 8
  • 64
  • 82
8
public class ZeroDivisionException extends ArithmeticException {
    // ...
}

if (denominator == 0) {
    throw new ZeroDivisionException();
}
João Silva
  • 89,303
  • 29
  • 152
  • 158
  • 2
    How come people extend ArithmeticException and not Exceptions? Isn't that 'wastefull' to extend a class that take up more space when all it needs is the Message instance variable from Exceptions? Does it also lend object data about the type of excpetion ( Arithmetic) for more information and that is why it extends ArithmeticException? – Chris Okyen Nov 28 '12 at 22:58
8

There are two ways you could do this. Either create your own custom exception class to represent a divide by zero error or throw the same type of exception the java runtime would throw in this situation.

Define custom exception

public class DivideByZeroException() extends ArithmeticException {
}

Then in your code you would check for a divide by zero and throw this exception:

if (divisor == 0) throw new DivideByZeroException();

Throw ArithmeticException

Add to your code the check for a divide by zero and throw an arithmetic exception:

if (divisor == 0) throw new java.lang.ArithmeticException("/ by zero");

Additionally, you could consider throwing an illegal argument exception since a divisor of zero is an incorrect argument to pass to your setKp() method:

if (divisor == 0) throw new java.lang.IllegalArgumentException("divisor == 0");
slangevi
  • 81
  • 2
3

Something like:

if(divisor == 0) {
  throw new ArithmeticException("Division by zero!");
}
Bart Kiers
  • 166,582
  • 36
  • 299
  • 288