Detect division by zero
You are encouraged to solve this task according to the task description, using any language you may know.
Write a function to detect a divide by zero error without checking if the denominator is zero.
Ada
<lang ada>-- Divide By Zero Detection
with Ada.Text_Io; use Ada.Text_Io; with Ada.Float_Text_Io; use Ada.Float_Text_Io; with Ada.Integer_Text_Io; use Ada.Integer_Text_Io;
procedure Divide_By_Zero is
Fnum : Float := 1.0; Fdenom : Float := 0.0; Fresult : Float; Inum : Integer := 1; Idenom : Integer := 0; Iresult : Integer;
begin
begin Put("Integer divide by zero: "); Iresult := Inum / Idenom; Put(Item => Iresult); exception when Constraint_Error => Put("Division by zero detected."); end; New_Line; Put("Floating point divide by zero: "); Fresult := Fnum / Fdenom; if Fresult > Float'Last then Put("Division by zero detected (infinite value)."); else Put(Item => Fresult, Aft => 9, Exp => 0); end if; New_Line;
end Divide_By_Zero;</lang> Results:
Integer divide by zero: Division by zero detected. Floating point divide by zero: Division by zero detected (infinite value).
ALGOL 68
The USSR's ALGOL 68 had a "GOST 27975-88 Programming language ALGOL 68 extended (Язык программирования АЛГОЛ 68 расширенный)" that included additional keywords on, exception, raise. This was an extension, and probably made only an appearance in the Leningrad compiler (Алгола 68 Ленинград).
The following code sample implements zero division, without using language extensions or access to hardware interrupts.
<lang algol68>PROC raise exception= ([]STRING args)VOID: (
put(stand error, ("Exception: ",args, newline)); stop
);
PROC raise zero division error := VOID:
raise exception("integer division or modulo by zero");
PROC int div = (INT a,b)REAL: a/b; PROC int over = (INT a,b)INT: a%b; PROC int mod = (INT a,b)INT: a%*b;
BEGIN
OP / = (INT a,b)REAL: ( b = 0 | raise zero division error; SKIP | int div (a,b) ); OP % = (INT a,b)INT: ( b = 0 | raise zero division error; SKIP | int over(a,b) ); OP %* = (INT a,b)INT: ( b = 0 | raise zero division error; SKIP | int mod (a,b) );
PROC a different handler = VOID: ( put(stand error,("caught division by zero",new line)); stop ); INT x:=1, y:=0; raise zero division error := a different handler; print(x/y)
END</lang> Output:
caught division by zero
AutoHotkey
<lang AutoHotkey>ZeroDiv(num1, num2) {
If ((num1/num2) != "") MsgBox % num1/num2 Else MsgBox, 48, Warning, The result is not valid (Divide By Zero).
} ZeroDiv(0, 3) ; is ok ZeroDiv(3, 0) ; divize by zero alert</lang>
C
<lang c>#include <stdio.h>
- include <stdlib.h>
- include <signal.h>
- include <unistd.h>
void handler(int signal, siginfo_t *w, void *a) {
if ( (w->si_code == FPE_INTDIV) || (w->si_code == FPE_FLTDIV) ) { fprintf(stderr,"caught division by zero!\n"); } exit(1);
}
int main() {
int x=1, y=0; struct sigaction signaldiv; signaldiv.sa_sigaction = handler; sigemptyset (&signaldiv.sa_mask); signaldiv.sa_flags = SA_SIGINFO; sigaction(SIGFPE, &signaldiv, NULL); printf("%d\n", x/y);
}</lang>
C#
The floating point types (float, double) don't raise an exception, but return the values Infinity or NaN as appropriate.
<lang csharp>using System;
namespace RosettaCode {
class Program { static void Main(string[] args) { int x = 1; int y = 0; try { int z = x / y; } catch (DivideByZeroException e) { Console.WriteLine(e); } } }
}</lang>
Clojure
After catching the ArithmeticException, print the error message, and then try and recover by returning some meaningful value. In this case, if x > 0, return +inf, if 0, NaN, otherwise -inf.
<lang lisp>(defn safe-/ [x y]
(try (/ x y) (catch ArithmeticException _ (println "Division by zero caught!") (cond (> x 0) Double/POSITIVE_INFINITY (zero? x) Double/NaN :else Double/NEGATIVE_INFINITY) )))</lang>
Common Lisp
<lang lisp>(handler-case (/ x y)
(division-by-zero () (format t "division by zero caught!~%")))</lang>
D
The following checks a floating number's normality by Floating Point Comparisons in D.
For integral types, it traps an exception thrown by the division.
<lang d>module divzero ;
import std.stdio ;
import std.format ;
// check if a is unordered (NaN) bool isNaN(T)(T a) { return a !<>= T.min ; } // check for +ve & -ve infinity bool isInf(T)(T a) { return a == T.infinity || -a == T.infinity ; } // check if neither NaN nor Inf bool isNormal(T)(T a) { return !(a !<> T.infinity || -a !<> T.infinity) ; }
string divCheck(T)(T numer, T denom) {
T result ; string msg = "" ; static if (is(T : long)) { // Integral Type try { result = numer / denom ; } catch(Exception e) { msg = "! " ~ e.msg ~"(by Exception)" ; result = T.max ; } } else { // Float Type result = numer / denom ; if(isNormal(numer) && isInf(result)) msg = "! Division by Zero" ; else if (!isNormal(result)) { if (isNaN(numer)) msg = "! NaN numerator" ; else if(isNaN(denom)) msg = "! NaN denominator" ; else if(isInf(numer)) msg = "! Inf numerator" ; else msg = "! NaN(Zero Division by Zero)" ; } } return std.format.format("%5s %s", std.format.format("%1.1g", cast(real)result), msg) ;
}
void main() {
writefln("Div with Check") ; writefln("int 1/ 0 : %s", divCheck(1, 0)) ; writefln("ubyte 1/ 0 : %s", divCheck(cast(ubyte)1, cast(ubyte)0)) ; writefln("real 1/ 0 : %s", divCheck(1.0L, 0.0L)) ; writefln("real -1/ 0 : %s", divCheck(-1.0L, 0.0L)) ; writefln("real 0/ 0 : %s", divCheck(0.0L, 0.0L)) ; writefln() ; writefln("real -4/-2 : %s", divCheck(-4.0L,-2.0L)) ; real inf = -1.0L / 0.0L ; // make an infinity writefln("real 2/-inf: %s", divCheck(2.0L, inf)) ; writefln() ; writefln("real -inf/-2 : %s", divCheck(inf, -2.0L)) ; writefln("real +inf/-2 : %s", divCheck(real.infinity, -2.0L)) ; writefln("real nan/-2 : %s", divCheck(real.nan, -2.0L)) ; writefln("real -2/ nan: %s", divCheck(-2.0L, real.nan)) ; writefln("real nan/ 0 : %s", divCheck(real.nan, 0.0L)) ; writefln("real inf/ inf: %s", divCheck(real.infinity, real.infinity)) ; writefln("real nan/ nan: %s", divCheck(real.nan, real.nan)) ;
}</lang> Output:
Div with Check int 1/ 0 : 2e+09 ! Integer Divide by Zero(by Exception) ubyte 1/ 0 : 3e+02 ! Integer Divide by Zero(by Exception) real 1/ 0 : inf ! Division by Zero real -1/ 0 : -inf ! Division by Zero real 0/ 0 : -nan ! NaN(Zero Division by Zero) real -4/-2 : 2 real 2/-inf: -0 real -inf/-2 : inf ! Inf numerator real +inf/-2 : -inf ! Inf numerator real nan/-2 : nan ! NaN numerator real -2/ nan: nan ! NaN denominator real nan/ 0 : nan ! NaN numerator real inf/ inf: -nan ! Inf numerator real nan/ nan: nan ! NaN numerator
E
<lang e>def divide(numerator, denominator) {
def floatQuotient := numerator / denominator if (floatQuotient.isNaN() || floatQuotient.isInfinite()) { return ["zero denominator"] } else { return ["ok", floatQuotient] }
}</lang>
Eiffel
version 2.4
In a file called main.e: <lang eiffel>class MAIN
creation main feature main is local x, y: INTEGER; retried: BOOLEAN; do x := 42; y := 0;
if not retried then io.put_real(x / y); else print("NaN%N"); end rescue print("Caught division by zero!%N"); retried := True; retry end
end</lang> Note: The "rescue" statement catches every exception.
Erlang
<lang erlang>div_check(X,Y) ->
case catch X/Y of {'EXIT',_} -> true; _ -> false end.</lang>
Factor
<lang factor>USE: math.floats.env
- try-div ( a b -- )
'[ { +fp-zero-divide+ } [ _ _ /f . ] with-fp-traps ] try ;</lang>
( scratchpad ) 1 2 try-div 0.5 ( scratchpad ) 1 0 try-div Floating point trap Type :help for debugging help.
Forth
<lang forth>: safe-/ ( x y -- x/y )
['] / catch -55 = if cr ." divide by zero!" 2drop 0 then ;</lang>
Go
Detection on integers by recovering from a panic: <lang go>func div_check(x, y int) (err bool) {
defer func() { if x := recover(); x != nil { err = true } }() dummy := x / y dummy++ // to avoid "unused" errors return
} </lang>
Groovy
In Groovy, the float and double types follow IEEE numeric formats and rules. Here is a solution for double: <lang groovy>def dividesByZero = { double n, double d ->
assert ! n.infinite : 'Algorithm fails if the numerator is already infinite.' (n/d).infinite || (n/d).naN
}</lang>
Test program: <lang groovy>((3d)..(0d)).each { i ->
((2d)..(0d)).each { j -> println "${i}/${j} divides by zero? " + dividesByZero(i,j) }
}</lang>
Output:
3.0/2.0 divides by zero? false 3.0/1.0 divides by zero? false 3.0/0.0 divides by zero? true 2.0/2.0 divides by zero? false 2.0/1.0 divides by zero? false 2.0/0.0 divides by zero? true 1.0/2.0 divides by zero? false 1.0/1.0 divides by zero? false 1.0/0.0 divides by zero? true 0.0/2.0 divides by zero? false 0.0/1.0 divides by zero? false 0.0/0.0 divides by zero? true
Haskell
<lang haskell>import qualified Control.Exception as C check x y = C.catch (x `div` y `seq` return False)
(\_ -> return True)</lang>
HicEst
<lang hicest>FUNCTION zero_divide(num, denom)
XEQ( num// "/" // denom, *99) ! on error jump to label 99 zero_divide = 0 ! division OK RETURN
99 zero_divide = 1
END</lang> <lang hicest>zero_divide(0, 1) returns 0 (false) zero_divide( 1, 3-2-1 ) returns 1 (true)</lang>
IDL
<lang idl>if not finite( expression ) then ...</lang>
Icon and Unicon
Setting &error to a non-zero number traps errors and converts then to failures. Division by zero generates error 201
Icon
<lang Icon>procedure main() &error := 1 udef := 1 / 0 | stop("Run-time error ", &errornumber, " : ", &errortext," in line #",&line," - converted to failure") end</lang>
Sample Output:
Run-time error 201 : division by zero in line #3 - converted to failure
Unicon
The Icon solution works in Unicon.
J
Divide by zero is not an error in J. It results in infinity which is represented by an underscore ( _
), except that 0 divided by 0 is defined to have the result zero (mathematically speaking any number is a valid result for 0 divided by 0, because 0 times any number is zero).
See also the J Dictionary page on infinity
The boolean expression:<lang j>_ = NUM % DEN</lang> is usually true for DEN = 0
. If you want to unconditionally test whether the denominator is zero, you should explicitly test the denominator.
Java
Two ways to accomplish this task are presented here. They each return true if there is a division by zero or if Double.POSITIVE_INFINITY is used as a numerator.
One way to do this check in Java is to use the isInfinite function from the Double class: <lang java>public static boolean infinity(double numer, double denom){ return Double.isInfinite(numer/denom); }</lang> Another way is to use the ArithmeticException as a check (which is not preferred because it expects an exception): <lang java>public static boolean except(double numer, double denom){ try{ int dummy = (int)numer / (int)denom;//ArithmeticException is only thrown from integer math return false; }catch(ArithmeticException e){return true;} }</lang>
JavaScript
JavaScript does not give an error on division by 0, and this is more useful than it is Mathematically correct. However, 0 divided by 0 will yield NaN, which is actually correct, since 0/0 is defined as "indeterminate". It may be better to return 0 or false in these situations, though, depending on the application (in JavaScript, 0 and false are the same thing): <lang JavaScript>function divByZero(dividend,divisor) { var quotient=dividend/divisor;
if(isNaN(quotient)) return 0; //Can be changed to whatever is desired by the programmer to be 0, false, or Infinity return quotient; //Will return Infinity or -Infinity in cases of, for example, 5/0 or -7/0 respectively
} alert(divByZero(0,0));</lang> This will output "0" instead of "NaN". In this case, when checking against for true, the condition needs to be explicit ("===" rather than "==") because if divByZero(5,5) is used, this will return 1, which is the same as true when using "==".
Liberty BASIC
<lang lb>result = DetectDividebyZero(1, 0)
Function DetectDividebyZero(a, b)
On Error GoTo [Error] DetectDividebyZero= (a/ b) Exit Function [Error] If Err = 11 Then '11 is the error number raised when divide by zero occurs Notice "Divide by Zero Detected!" End If
End Function</lang>
Lua
Lua, like Javascript, does not error on DIVIDE-BY-ZERO, but returns infinity. So:
<lang lua>function div(a,b)
quot = a/b if quot == 1/0 then error() end return quot
end</lang>
M4
<lang M4>ifelse(eval(2/0),`',`detected divide by zero or some other error of some kind')</lang>
Output, with standard output labeled "==>" and error output labeled "error==>":
error==>divideby0.m4:1: m4: Divide by zero in eval: 2/0 ==>detected divide by zero or some other error of some kind
MATLAB
<lang Matlab>function [isDividedByZero] = dividebyzero(numerator, denomenator)
isDividedByZero = isinf( numerator/denomenator ); % If isDividedByZero equals 1, divide by zero occured.</lang>
MAXScript
<lang maxscript>if not bit.isFinite (expression) then...</lang>
MUMPS
<lang MUMPS>DIV(A,B) ;Divide A by B, and watch for division by zero
;The ANSI error code for division by zero is "M9". ;$ECODE errors are surrounded by commas when set. NEW $ETRAP SET $ETRAP="GOTO DIVFIX^ROSETTA" SET D=(A/B) SET $ETRAP="" QUIT D
DIVFIX
IF $FIND($ECODE,",M9,")>1 WRITE !,"Error: Division by zero" SET $ECODE="" QUIT "" QUIT "" ; Fall through for other errors</lang>
Output:
USER>W $$DIV^ROSETTA(1,2) .5 USER>W $$DIV^ROSETTA(1,4) .25 USER>W $$DIV^ROSETTA(1,0) Error: Division by zero USER>W $$DIV^ROSETTA(1,C) W $$DIV^ROSETTA(1,C) ^ <UNDEFINED> *C
OCaml
Detection on integers by catching an exception: <lang ocaml>let div_check x y =
try ignore (x / y); false with Division_by_zero -> true</lang>
Detection on floats by checking for infiniteness: <lang ocaml>let div_check x y =
classify_float (x /. y) = FP_infinite</lang>
Octave
Dividing by zero raises a warning (a warning does not stop the execution), not an error (and the given answer is Infinity), so it's not possible to use a try-catch construct; we can however check for the lastwarn if the answer is Inf.
<lang octave>d = 5/0; if ( isinf(d) )
if ( index(lastwarn(), "division by zero") > 0 ) error("division by zero") endif
endif</lang>
Oz
For integer division only. <lang oz>try
{Show 42 div 0}
catch error(kernel(div0 ...) ...) then
{System.showInfo "Division by zero detected."}
end</lang>
Perl
This function returns true iff its second argument is zero. <lang perl>sub div_check
{local $@; eval {$_[0] / $_[1]}; $@ and $@ =~ /division by zero/;}</lang>
PHP
This function returns true iff its second argument is zero. <lang php>function div_check($x, $y) {
@trigger_error(); // a dummy to detect when error didn't occur @($x / $y); $e = error_get_last(); return $e['message'] != ;
}</lang>
<lang php>function div_check($x, $y) {
return @($x / $y) === FALSE; // works at least in PHP/5.2.6-3ubuntu4.5
}</lang>
PicoLisp
<lang PicoLisp>(catch '("Div/0") (/ A B))</lang>
PL/I
<lang PL/I> /* A function is not required to detect division by zero. */ /* The following statement is executed anywhere prior to */ /* executing the statement containing the division by zero. */
on zerodivide snap go to trap_zerodivide;
</lang>
Pure
There is no need in Pure to handle division by zero, as it is handled properly: <lang pure>> 1 / 0; inf > -1 * (1 / 0); -inf > 0 / 0; nan ></lang>
PureBasic
PureBasic can be compiled with the OnError library included which gives a way to track program errors without losing speed, doing so gives support for the following functions;
- ErrorAddress()
- ErrorCode()
- ErrorFile()
- ErrorLine()
- ErrorMessage()
- ErrorRegister()
- ErrorTargetAddress()
- ExamineAssembly()
- InstructionAddress()
- InstructionString()
- NextInstruction()
- OnErrorCall()
- OnErrorDefault()
- OnErrorExit()
- OnErrorGoto()
- RaiseError()
This way the final version of a program can still intercept program errors and provide some function, or information about the error to the user so he can report it back to the developer.
With Integers & OnError Library
<lang PureBasic>;Set up a Procedure to handle any Error
Procedure MyErrorHandler()
Define txt$="The following error happened."+#CRLF$+ ErrorMessage()+"at line "+Str(ErrorLine()) MessageRequester("OnError test", txt$)
EndProcedure
- Tell where to go if an Error happens
OnErrorCall(@MyErrorHandler())
- Now, do something very stupid so that we may see an Error...
Repeat
A=Random(100)/Random(100)
With Floats, and without OnError library
<lang PureBasic>Define.d a, b
Debug a/b</lang>
Results in;
-1.#IND
Python
<lang python>def div_check(x, y):
try: x / y except ZeroDivisionError: return True else: return False</lang>
R
Division by zero does not raise an error nor a warning; the result can be checked against infinity: <lang R>d <- 5/0 if ( is.infinite(d) ) {
# it is Inf or -Inf
}</lang>
REBOL
<lang REBOL>REBOL [
Title: "Detect Divide by Zero" Date: 2009-12-16 Author: oofoe URL: http://rosettacode.org/wiki/Divide_by_Zero_Detection
]
- The 'try' word returns an error object if the operation fails for
- whatever reason. The 'error?' word detects an error object and
- 'disarm' keeps it from triggering so I can analyze it to print the
- appropriate message. Otherwise, any reference to the error object
- will stop the program.
div-check: func [ "Attempt to divide two numbers, report result or errors as needed." x y /local result ] [ either error? result: try [x / y][ result: disarm result print ["Caught" result/type "error:" result/id] ] [ print [x "/" y "=" result] ] ]
div-check 12 2 ; An ordinary calculation. div-check 6 0 ; This will detect divide by zero. div-check "7" 0.0001 ; Other errors can be caught as well.</lang>
Output:
12 / 2 = 6 Caught math error: zero-divide Caught script error: cannot-use
Ruby
<lang ruby>def div_check(x, y)
begin x / y rescue ZeroDivisionError true else false end
end</lang>
Scala
Without the "println(result)" line, the result would not get calculated as it is not needed. The method would get optimized to always return false. <lang scala>object DivideByZero extends Application {
def check(x: Int, y: Int): Boolean = { try { val result = x / y println(result) return false } catch { case x: ArithmeticException => { return true } } } println("divided by zero = " + check(1, 0))
}</lang>
Slate
<lang slate>[ 1 / 0 ] on: Error do: [|:err| err return: PositiveInfinity].</lang>
Smalltalk
<lang smalltalk>zeroDivide := [:aBlock | [aBlock value. false] on: ZeroDivide do: [true]. ].
"Testing" zeroDivide value: [2/1] "------> false" zeroDivide value: [2/0] "------> true" </lang>
Standard ML
Detection on integers by catching an exception: <lang sml>fun div_check (x, y) = (
ignore (x div y); false
) handle Div => true</lang>
Detection on floats by checking for infiniteness: <lang sml>fun div_check (x, y) =
not (Real.isFinite (x / y))</lang>
Tcl
<lang tcl>proc div_check {x y} {
if {[catch {expr {$x/$y}} result] == 0} { puts "valid division: $x/$y=$result" } else { if {$result eq "divide by zero"} { puts "caught division by zero: $x/$y -> $result" } else { puts "caught another error: $x/$y -> $result" } }
}
foreach denom {1 0 foo} {
div_check 42 $denom
}</lang> Outputs:
valid division: 42/1=42 caught division by zero: 42/0 -> divide by zero caught another error: 42/foo -> can't use non-numeric string as operand of "/"
It is easier to trap such errors in Tcl 8.6, which has an additional control structure for exception processing: <lang tcl>proc div_check {x y} {
try { puts "valid division: $x/$y=[expr {$x/$y}]" } trap {ARITH DIVZERO} msg { puts "caught division by zero: $x/$y -> $msg" } trap {ARITH DOMAIN} msg { puts "caught bad division: $x/$y -> $msg" } on error msg { puts "caught another error: $x/$y -> $msg" }
}
foreach {num denom} {42 1 42 0 42.0 0.0 0 0 0.0 0.0 0 foo} {
div_check $num $denom
}</lang> which produces the output:
valid division: 42/1=42 caught division by zero: 42/0 -> divide by zero valid division: 42.0/0.0=Inf caught division by zero: 0/0 -> divide by zero caught bad division: 0.0/0.0 -> domain error: argument not in valid range caught another error: 0/foo -> can't use non-numeric string as operand of "/"
As can be seen, division-by-zero is only signaled when performing integer division. Similarly, separate detection of values that would otherwise be IEEE NaN is only performed when doing floating-point division.
TI-89 BASIC
1/0 = undef
is true.
- Programming Tasks
- Solutions by Programming Task
- Ada
- ALGOL 68
- AutoHotkey
- C
- C sharp
- Clojure
- Common Lisp
- D
- E
- Eiffel
- Erlang
- Factor
- Forth
- Go
- Groovy
- Haskell
- HicEst
- IDL
- Icon
- Unicon
- J
- Java
- JavaScript
- Liberty BASIC
- Lua
- M4
- MATLAB
- MAXScript
- MUMPS
- OCaml
- Octave
- Oz
- Perl
- PHP
- PicoLisp
- PL/I
- Pure
- PureBasic
- Python
- R
- REBOL
- Ruby
- Scala
- Slate
- Smalltalk
- Standard ML
- Tcl
- TI-89 BASIC