Detect division by zero

From Rosetta Code
Revision as of 15:34, 26 August 2012 by Rdm (talk | contribs) (→‎{{header|J}})
Task
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.

ABAP

<lang ABAP>report zdiv_zero data x type i. try.

 x = 1 / 0.

catch CX_SY_ZERODIVIDE.

 write 'Divide by zero.'.

endtry. </lang>

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.

Translation of: C
Works with: ALGOL 68 version Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386

<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>

BBC BASIC

<lang bbcbasic> PROCdivide(-44, 0)

     PROCdivide(-44, 5)
     PROCdivide(0, 5)
     PROCdivide(5, 0)
     END
     
     DEF PROCdivide(numerator, denominator)
     ON ERROR LOCAL IF FALSE THEN
       REM 'Try' clause:
       PRINT numerator / denominator
     ELSE
       REM 'Catch' clause:
       CASE ERR OF
         WHEN 18: PRINT "Division by zero"
         WHEN 20: PRINT "Number too big"
         OTHERWISE RESTORE LOCAL : ERROR ERR, REPORT$
       ENDCASE
     ENDIF
     ENDPROC</lang>

C

Library: POSIX

Some systems will raise SIGFPE if a program divides by zero.

<lang c>#include <limits.h> /* INT_MIN */

  1. include <setjmp.h> /* siglongjmp(), sigsetjmp() */
  2. include <stdio.h> /* perror(), printf() */
  3. include <stdlib.h> /* exit() */
  4. include <signal.h> /* sigaction(), sigemptyset() */

static sigjmp_buf fpe_env;

/*

* This SIGFPE handler jumps to fpe_env.
*
* A SIGFPE handler must not return, because the program might retry
* the division, which might cause an infinite loop. The only safe
* options are to _exit() the program or to siglongjmp() out.
*/

static void fpe_handler(int signal, siginfo_t *w, void *a) { siglongjmp(fpe_env, w->si_code); /* NOTREACHED */ }

/*

* Try to do x / y, but catch attempts to divide by zero.
*/

void try_division(int x, int y) { struct sigaction act, old; int code; /* * The result must be volatile, else C compiler might delay * division until after sigaction() restores old handler. */ volatile int result;

/* * Save fpe_env so that fpe_handler() can jump back here. * sigsetjmp() returns zero. */ code = sigsetjmp(fpe_env, 1); if (code == 0) { /* Install fpe_handler() to trap SIGFPE. */ act.sa_sigaction = fpe_handler; sigemptyset(&act.sa_mask); act.sa_flags = SA_SIGINFO; if (sigaction(SIGFPE, &act, &old) < 0) { perror("sigaction"); exit(1); }

/* Do division. */ result = x / y;

/* * Restore old hander, so that SIGFPE cannot jump out * of a call to printf(), which might cause trouble. */ if (sigaction(SIGFPE, &old, NULL) < 0) { perror("sigaction"); exit(1); }

printf("%d / %d is %d\n", x, y, result); } else { /* * We caught SIGFPE. Our fpe_handler() jumped to our * sigsetjmp() and passes a nonzero code. * * But first, restore old handler. */ if (sigaction(SIGFPE, &old, NULL) < 0) { perror("sigaction"); exit(1); }

/* FPE_FLTDIV should never happen with integers. */ switch (code) { case FPE_INTDIV: /* integer division by zero */ case FPE_FLTDIV: /* float division by zero */ printf("%d / %d: caught division by zero!\n", x, y); break; default: printf("%d / %d: caught mysterious error!\n", x, y); break; } } }

/* Try some division. */ int main() { try_division(-44, 0); try_division(-44, 5); try_division(0, 5); try_division(0, 0); try_division(INT_MIN, -1); return 0; }</lang>

Output using OpenBSD/amd64:

-44 / 0: caught division by zero!
-44 / 5 is -8
0 / 5 is 0
0 / 0: caught division by zero!
-2147483648 / -1: caught division by zero!

The last line is a mistake: the system confused an overflow (INT_MIN / -1 would be INT_MAX + 1) with division by zero and raised SIGFPE. The system normally ignores overflow.

C#

Works with: int, long, decimal

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

Delphi

<lang Delphi>program DivideByZero;

{$APPTYPE CONSOLE}

uses SysUtils;

var

 a, b: Integer;

begin

 a := 1;
 b := 0;
 try
   WriteLn(a / b);
 except
   on e: EZeroDivide do
     Writeln(e.Message);
 end;

end.</lang>

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

Works with: SmartEiffel

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.

Ela

<lang ela>x /. y = try Some (x / y) with

            _ = None

(12 /. 2, 12 /. 0)</lang>

Output:

(Some 6, None)

Of course the cleanest way to implement the safe division function is through pattern matching:

<lang ela>x /. 0 = None x /. y = Some (x / y)</lang>

But it doesn't satisfy the task.

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.

Fancy

<lang fancy>def divide: x by: y {

 try {
   x / y
 } catch DivisionByZeroError => e {
   e message println # prints error message
 }

} </lang>

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>package main

import "fmt"

func divCheck(x, y int) (q int, ok bool) {

   defer func() {
       recover()
   }()
   q = x / y
   return q, true

}

func main() {

   fmt.Println(divCheck(3, 2))
   fmt.Println(divCheck(3, 0))

}</lang> Output:

1 true
0 false

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 <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

J

Divide by zero is not an error in J. It results in infinity which is represented by an underscore ( _ ) or negative infinity (represented by a double underescore) or complex values which can have infinities for the real and/or imaginary part., 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 (except when NUM was zero). The boolean expression 0 = DEN will always be true when DEN = 0, and should be the preferred way of testing for this issue (except when someone is requiring you to write bad code).

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 "==".

LabVIEW

This example is in need of improvement:

Clarify what happens with 0/0

This image is a VI Snippet, an executable image of LabVIEW code. The LabVIEW version is shown on the top-right hand corner. You can download it, then drag-and-drop it onto the LabVIEW block diagram from a file browser, and it will appear as runnable, editable code.

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>

Locomotive Basic

<lang locobasic>10 ON ERROR GOTO 60 20 PRINT 2/3 30 PRINT 3/5 40 PRINT 4/0 50 END 60 IF ERR=11 THEN PRINT "Division by zero in line"ERL:RESUME 50</lang>

Output:

 0.666666667 
 0.6 
Division by zero in line 40 

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

Mathematica

<lang Mathematica>Check[2/0, Print["division by 0"], Power::infy]</lang>

MATLAB

<lang Matlab>function [isDividedByZero] = dividebyzero(numerator, denomenator)

  isDividedByZero = isinf( numerator/denomenator );
  % If isDividedByZero equals 1, divide by zero occured.</lang>

Maxima

<lang maxima>f(a, b) := block([q: errcatch(a / b)], if emptyp(q) then 'error else q[1]);

f(5, 6); 5 / 6

f(5, 0;) 'error</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

<lang netlogo>;; Division by zero detection using CAREFULLY

The CAREFULLY clause exists in NetLogo since version 2.0
In prior versions of NetLogo, you must examine the divisor prior to performing the division.
The variables result, a, and b must all be previously created global, local, or agent -own'd variables.
NetLogo variables are dynamically typed, so we are assuming that a and b contain numbers.
(All numbers in NetLogo are double-precision floating-point numbers.)
However, even if not numbers, the result is still the same
the carefully clause will
supress the run-time error and run the "commands if error" block, setting result to false.
this false value can be detected, to alter the rest of the course of the code
This behavior is consistent with other NetLogo primitives, such as POSTIION, that report
FALSE, rather than a number, if the operation fails.

carefully [ ;; commands to try to run

 set result a / b

] [ ;; commands to run if an error occurs in the previous block.

 set result false

] ifelse is-number? result [ output-print (word a " / " b " = " result) ] [ output-print (word a " / " b " is not calculable" ]</lang>

NetRexx

<lang NetRexx>/* NetRexx */ options replace format comments java crossref symbols nobinary

method divide(dividend, divisor) public constant returns Rexx

 do
   quotient = dividend / divisor
 catch exu = DivideException
   exu.printStackTrace()
   quotient = 'undefined'
 catch exr = RuntimeException
   exr.printStackTrace()
   quotient = 'error'
 end
 return quotient

method main(args = String[]) public static

 -- process input arguments and set sensible defaults
 arg = Rexx(args)
 parse arg dividend .',' divisor .
 if dividend.length() = 0 then dividend = 1
 if divisor.length()  = 0 then divisor  = 0
 say dividend '/' divisor '=' divide(dividend, divisor)
 return

</lang>

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>

PARI/GP

<lang parigp>trap(,"division by 0",m/n)</lang>

Pascal

See Delphi

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>

Perl 6

<lang perl6>sub div($a, $b){

   my $r;
   try {
       $r = $a / $b;
       CATCH {
          say "tried to divide by zero !" if $! ~~ "Divide by zero";
       }
   }
   return $r // fail;

}

say div(10,2); # 5 say div(1,0); # Inf, 1/0 constants are substituted for Infinity say div(1, sin(0)); # undef, and prints "tried to divide by zero" </lang>

Using Multi Method Dispatch

<lang perl6>multi div($a, $b){ return $a / $b } multi div($a, $b where { $b == 0 }){

   say 'lolicheatsyou'; 
   return 1; 

}

say div(1, sin(0)); # prints "lolicheatsyou" newline "1" </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>

PL/SQL

<lang PL/SQL>FUNCTION divide(n1 IN NUMBER, n2 IN NUMBER) RETURN BOOLEAN IS

 result NUMBER;

BEGIN

 result := n1/n2;
 RETURN(FALSE);

EXCEPTION

 WHEN ZERO_DIVIDE THEN
   RETURN(true);

end divide;</lang>

<lang PL/SQL>divide(0,1) --false divide(1,0) --true, division by zero</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)

ForEver</lang>


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. Division of a non-zero value by zero returns infinity. Division of zero by zero returns NaN; Whether the result is not finite can be checked: <lang R>d <- 5/0 if ( !is.finite(d) ) {

 # it is Inf, -Inf, or NaN

}</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

REXX

The task's requirements are to write a function, but this example program was written to solve the spirit of the requirement.
This version isn't really a function so much as it is a method.
Also, a function and a subroutine doesn't have that much of a distinction in the REXX language. <lang rexx>/*REXX program demonstrates detects and handles division by zero. */

signal on syntax /*handle all REXX syntax errors. */ x = sourceline() /*being cute, x=size of this pgm.*/ y = x-x /*setting to zero the obtuse way.*/ z = x/y /*this'll do it, furrrr shurrre. */ exit /*We're kaput. Ja vohl ! */

/*───────────────────────────────error handling subroutines and others.─*/ err: if rc==42 then do; say; say /*1st, check for a specific error*/

                   say center(' division by zero is a no-no. ',79,'═')
                        say;  say
                   exit 130
                   end
    say; say; say center(' error! ',max(40,linesize()%2),"*"); say
              do j=1 for arg(); say arg(j); say; end; say;
              exit 13

novalue: syntax: call err 'REXX program' condition('C') "error",,

            condition('D'),'REXX source statement (line' sigl"):",,
            sourceline(sigl)</lang>

output


════════════════════════ division by zero is a no-no. ═════════════════════════

Ruby

This only checks integer division by zero.

<lang ruby>def div_check(x, y)

 begin
   x / y
 rescue ZeroDivisionError
   true
 else
   false
 end

end</lang>

Ruby allows division by zero if either operand is a Float.

<lang ruby>irb(main):010:0> div_check(5, 0) => true irb(main):011:0> div_check(5.0, 0) => false</lang>


Starting with Ruby 1.9, Numeric#div raises ZeroDivisionError, whether or not an operand is a Float.

Works with: Ruby version 1.9

<lang ruby>def div_check(x, y)

 begin
   x.div y
 rescue ZeroDivisionError
   true
 else
   false
 end

end</lang>

<lang ruby>irb(main):010:0> div_check(5, 0) => true irb(main):011:0> div_check(5.0, 0) => true</lang>

Run BASIC

<lang runbasic>on error goto [error] a = 1 / 0 wait

[error] ' error 11 is division by zero err number If err = 11 Then print "Division by Zero" wait</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>

Seed7

Integer division by zero raises NUMERIC_ERROR. Floating point division by zero returns Infinite or -Infinite. <lang seed7>$ include "seed7_05.s7i";

 include "float.s7i";

const proc: doDivide (in integer: numer, in integer: denom) is func

 begin
   block
     writeln(numer <& " div " <& denom <& " = " <& numer div denom);
   exception
     catch NUMERIC_ERROR:
       writeln("Division by zero detected.");
   end block;
 end func;

const proc: doDivide (in float: numer, in float: denom) is func

 local
   var float: quotient is 0.0;
 begin
   quotient := numer / denom;
   if quotient <> Infinity and quotient <> -Infinity then
     writeln(numer <& " / " <& denom <& " = " <& quotient);
   else
     writeln("Division by zero detected.");
   end if;
 end func;

const proc: main is func

 begin
   doDivide(10, 8);
   doDivide(1, 0);
   doDivide(10.0, 8.0);
   doDivide(1.0, 0.0);
 end func;</lang>

Output:

10 div 8 = 1
Division by zero detected.
10.0 / 8.0 = 1.25
Division by zero detected.

Slate

<lang slate>[ 1 / 0 ] on: Error do: [|:err| err return: PositiveInfinity].</lang>


Smalltalk

Works with: Squeak

<lang smalltalk>zeroDivide := [:aBlock | [aBlock value. false] on: ZeroDivide do: [true]. ].

"Testing" zeroDivide value: [2/1] "------> false" zeroDivide value: [2/0] "------> true" </lang>

SNOBOL4

Works with: Macro Spitbol

Using setexit( ) to trap and ignore division by zero.

<lang SNOBOL4> define('zdiv(x,y)') :(zdiv_end) zdiv &errlimit = 1; setexit(.ztrap)

       zdiv = x / y :(return)

ztrap zdiv = ?(&errtype ? (14 | 262)) 'Division by zero' :s(continue)f(abort) zdiv_end

  • # Test and display
       output = '1/1     = ' zdiv(1,1)      ;* Integers non-zero
       output = '1.0/1.0 = ' zdiv(1.0,1.0)  ;* Reals non-zero
       output = '1/0     = ' zdiv(1,0)      ;* Integers zero
       output = '1.0/0.0 = ' zdiv(1.0,0.0)  ;* Reals zero
       output = 'Zero checks complete'

end</lang>

Output:

1/1     = 1
1.0/1.0 = 1.
1/0     = Division by zero
1.0/0.0 = Division by zero
Zero checks complete

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 "/"
Works with: Tcl version 8.6

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.

Yorick

<lang yorick>func div_check(x, y) {

   if(catch(0x01))
       return 1;
   temp = x/y;
   return 0;

}</lang>