# What is the cleanest way to prevent divide-by-zero warnings?

If I evaluate {1, 2, 3, 4}/{5, 6, 0, 8}, obviously I get one warning:

Power::infy: Infinite expression 1/0 encountered. >>


and one entry of ComplexInfinity in the third position of the result. I'd like to eliminate the warnings and get the output with instances of ComplexInfinity deleted.

So far,

DeleteCases[Quiet[{1, 2, 3, 4}/{5, 6, 0, 8}], ComplexInfinity]


is the best way I have to do this. But I'd rather not suppress all messages with Quiet, in case I'm operating on something more complicated than this example.

Rather than cleaning up the mess it causes, is there a clean way to prevent the divide-by-zero operation from happening in the first place?

-
Maybe DeleteCases[ Quiet[{1, 2, 0, 0}/{5, 6, 0, 8}, {Power::"infy", General::"indet"}], ComplexInfinity | Indeterminate] – Daniel Lichtblau May 10 '12 at 22:51

You could remove the zero from the denominator, and the corresponding entry from the numerator:

a = {1, 2, 3, 4};
b = {5, 6, 0, 8};

Pick[a, Positive[b]]/Pick[b, Positive[b]]

(*
==> {1/5, 1/3, 1/2}
*)

-
What about negative numbers? Shouldn't you use something like PossibleZeroQ? – Mr.Wizard May 11 '12 at 3:03
@Mr.Wizard Sure, if that's a concern. It all depends on what you know about the lists. – Brett Champion May 11 '12 at 3:26
This one is most in the spirit of preventing the error instead of handling it. Thanks. – ArgentoSapiens May 11 '12 at 16:33

You can switch off the 1/0 messages with

Off[Power::infy]


Now 1/0 only returns ComplexInfinity.

If you want to intercept that (your "prevent the divide-by-zero operation from happening in the first place" seems to imply that) you'd have to redefine Power[0,-1]:

Unprotect[Power]
Power[0, -1] = ...;
Protect[Power]


with '...' a definition of your choice. I would strongly advice against modifying a common built-in function like that, though.

-
Never ever modify built-in commands, the side effects of doing so aren't only often severe, but also very unpredictable. I wouldn't even recommend this as part of an answer. – David May 11 '12 at 1:55
If you want to redefine built-ins for some particular piece of code, you can use block to avoid undefined behavior and have that definition only apply to your particular code. – jVincent May 11 '12 at 9:35
@jVincent A particular ingenious version of this can be found in this contribution to the MMA toolbag. But generally, completely Blocking a built-in functions means you have to provide most of its functionality yourself which could be a problem. – Sjoerd C. de Vries May 11 '12 at 11:44

As Daniel commented, you can restrict the scope of Quiet with its second argument:

Quiet[{1, 2, 3, 4}/{5, 6, 0, 8}, Power::infy]


Other messages are still printed:

Quiet[Divide[1, 2, 3], Power::infy]


During evaluation of In[2]:= Divide::argrx: Divide called with 3 arguments; 2 arguments are expected. >>

-

Since you are asking for "a way to prevent the divide by zero operation from happening in the first place," let me suggest another approach that is just slightly more involved than the obvious answer (i.e., just don't include zeros in b):

Lets' pick two lists that cover various cases with zeros:

a = {1, 2, 3, 4, 0, 0};
b = {5, 6, 0, 8, 1, 0};


Now I'll define a replacement rule:

inertZero = {0|0. -> "0"};


Its purpose is to replace numerical zeros by a string "0". Strings can be used in calculations but don't trigger the errors you want to avoid. This allows you to do the division like so:

c = a/(b /. inertZero)


$\left\{\frac{1}{5},\frac{1}{3},\frac{3}{0},\frac{1}{2},0,0\right\}$

Depending on your needs, this could be the end of the story, showing you visually where the division by zero would have occurred. Note in particular the last entry, where we had a 0/0 division. Here, Mathematica makes a choice for us: instead of returning Indeterminate, it sets the result to zero. If you don't like this resolution, one could change the rule.

But maybe you want more, e.g., rescue the remaining divide-by-zero cases somehow. Not knowing exactly what you want to do with them, I'll just go on by assuming you want them to return Infinity. So obviously we'll need another replacement rule, and let Mathematica draw its own conclusions about where $\infty$ should appear:

Limit[c /. "0" -> ε, ε -> 0]


$\left\{\frac{1}{5},\frac{1}{3},\infty ,\frac{1}{2},0,0\right\}$

-
In the last entry, it seems confusing to say that Mathematica makes a choice for you. Mathematica returns indeterminate on 0/0, however you changed it to 0/"0", which returns 0. So it's your choice, not Mathematica's. – jVincent May 11 '12 at 9:41
But Mathematica chooses that 0 times an unknown object (here Power["0", -1]) is zero, instead of leaving it unevaluated. – Jens May 11 '12 at 13:33