Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# unable to catch DivideByZeroException

Tags:

f#

I atempt to catch an exception when dividing by 0 is performed but, no mater the implementation, code shows nothing of substance, always claiming that the result is "infinity" (meaning, from what I get, that it just performed the division and ignored everything else)

What is the reason for this and how to remedy it?

open System

type instruction = 
  | ADD
  | SUB
  | MUL
  | SQR
  | DIV
  | PUSH of float
type stack = float list

exception BLEDNY_PROGRAM of (instruction * stack)
exception DivideByZeroException

let intInstr (x, y) = 
        match x, y with
        | ADD, a::b::ys -> (b + a) :: ys : stack
        | SUB, a::b::ys -> (b-a)::ys
        | MUL, a::b::ys -> (b*a)::ys
        | SQR, a::ys -> (a * a)::ys
        | DIV, a::b::ys -> try (b/a)::ys with | :? System.DivideByZeroException -> (printf "Błąd: dzielenie przez zero"; ys)
        | PUSH x, ys -> x::ys
        | _ , _ -> raise (BLEDNY_PROGRAM(x, y));

let intpProg(is) =
   let rec iPS = function
           | ([],x::xs) -> x
           | (i::is, xs) -> iPS(is, intInstr(i, xs))
   iPS(is,[])

let il3 = [PUSH 3.0; PUSH 0.0; DIV];
let e = intpProg(il3)
printfn "%A" e
like image 963
Daractive Avatar asked Jan 26 '23 04:01

Daractive


1 Answers

A float in F# is a 64-bit IEEE 754 double-precision number. They have well-defined values for ±zero, ±infinity, and NaN.

For all floating point divisions by zero (except decimal), a DivideByZeroException is not thrown, but rather, the type's special representation is used.

> let ``+∞``, ``-∞`` = 1.0 / 0.0, -1.0 / 0.0;;
val ( -∞ ) : float = -infinity
val ( +∞ ) : float = infinity

In your example, dividing by zero would give you Double.PositiveInfinity. Integer values (int, long, uint, etc.,) all throw a divide by zero as you'd expect.

like image 138
Asti Avatar answered Feb 01 '23 20:02

Asti