[fpc-pascal] Division by Zero: EDivByZero and EZeroDivide

Jonas Maebe jonas.maebe at elis.ugent.be
Mon Oct 19 14:36:40 CEST 2009


On 19 Oct 2009, at 14:14, Tom Verhoeff wrote:

> On Mon, Oct 19, 2009 at 10:21:01AM +0200, Jonas Maebe wrote:
>>
>
>> http://www.freepascal.org/docs-html/rtl/math/setexceptionmask.html
>>
>> Fully cross-platform, even.
>
> How new is that?

Not very. I think it exists at least since 2.0.0.

> It works 'partly'.  Consider the program
>
> program DivideByZero;
>  { to see whether division by zero can result in Infinite values }
>
> uses Math;
>
> var one, zero, result: Double;
>
> begin
>  SetExceptionMask ( [ exZeroDivide{, exPrecision} ] );
>  one := 1.0;
>  zero := 0.0;
>  result := one / zero;
>  writeln ( result ); { Expected output: +Inf }
>  result := one / result;
>  writeln ( result ); { Expected output: +0.0 }
> end.
>
> Outputs:
>                  +Inf
> An unhandled exception occurred at $000060B0 :
> EDivByZero : Division by zero
>  $000060B0
>  $00005850
>  $0001889B
>
> In order to allow 1 / +Inf, you also need to mask exPrecision
> (i.e. uncomment it from the set passed to SetExceptionMask).
> I am surprised that division by an Infinity raises EDivByZero:  
> Division by zero

It probably depends on your platform. In case it's Mac OS X on x86:  
floating point exception reporting via Unix signals isn't exactly its  
forte. The Darwin signal handler contains code to decode the  
instructions where a floating point exception occurs, because the  
system generates a "generic" floating point exception on integer div- 
by-zero. Maybe the above operation also causes a generic floating  
point exception which is then wrongly classified by us as div-by-zero.

In general, relying on these exceptions to return a particular value  
is a bad idea though. Using Unix signals for this purpose is not  
supported at all on Mac OS X (we should actually use Mach exceptions  
instead), because the state you get in the Unix signal handler is  
transient (if another exception happens at the same time in another  
thread, you may lose one exception, you may get a state that contains  
a mix of both exceptions, etc). Moreover, both the format of the  
context parameter of Unix signals and the interface for Mach  
exceptions are still considered SPI (system private interface) by  
Apple, so at this point there is no way to implement either in a way  
that's guaranteed to be forward compatible.


Jonas



More information about the fpc-pascal mailing list