Divide by Zero Detection

From Rosetta Code

Jump to: navigation, search

Programming Task
This is a programming task. It lays out a problem which Rosetta Code users are encouraged to solve, using languages they know.

Code examples should be formatted along the lines of one of the existing prototypes.
Write a function to detect a divide by zero error without checking if the denominator is zero.

Contents

[edit] 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;
 

Results:

Integer divide by zero: Division by zero detected.
Floating point divide by zero: Division by zero detected (infinite value).

[edit] 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.

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)) ;  
}
 

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

[edit] Forth

: safe-/ ( x y -- x/y )
  ['] / catch -55 = if cr ." divide by zero!" 0 then ;

[edit] Haskell

maybe:

let check x y = isInfinite (x / y)

[edit] IDL

if not finite( expression ) then ...

[edit] 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:

public static boolean infinity(double numer, double denom){
	return Double.isInfinite(numer/denom);
}

Another way is to use the ArithmeticException as a check (which is not preferred because it expects an exception):

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

[edit] MAXScript

if not bit.isFinite (expression) then...

[edit] OCaml

Detection on integers by catching an exception:

let div_check x y =
  try
    ignore (x / y);
    false
  with Division_by_zero ->
    true

Detection on floats by checking for infiniteness:

let div_check x y =
  classify_float (x /. y) = FP_infinite

[edit] Perl

This function returns true iff its second argument is zero.

sub div_check
 {local $@;
  eval {$_[0] / $_[1]};
  $@ and $@ =~ /division by zero/;}

[edit] Python

def div_check(x, y):
  try:
    x / y
  except ZeroDivisionError:
    return True
  else:
    return False
Personal tools