Division by zero - why no exception?

bearophile bearophileHUGS at lycos.com
Sun Jan 10 02:35:14 PST 2010


A Bothe:
> double a=0.0;
> double f=1/a;
> writeln(f);
> ... prints 2.66825e-284

To me this code prints "nan" (I am using the latest D2 compiler, but D1 too prints nan):

import std.stdio: writeln;
void main() {
    double a = 0.0;
    double f = 1 / a;
    writeln(f);
}

If you want the division by zero error you have to activate it (but be careful, this works only in the main(), probably to keep tidy the semantics of pure functions):

import std.stdio: writeln;
import std.math: FloatingPointControl;

void main() {
    FloatingPointControl fpc;
    fpc.enableExceptions(FloatingPointControl.severeExceptions);

    double a = 0.0;
    double f = 1 / a;
    writeln(f);
}

Prints at run time:
object.Error: Float Divide by Zero

But be careful, that works at run time only, so if you use compile time constants:

import std.stdio: writeln;
import std.math: FloatingPointControl;

void main() {
    FloatingPointControl fpc;
    fpc.enableExceptions(FloatingPointControl.severeExceptions);

    enum double a = 0.0;
    enum double f = 1 / a;
    writeln(f);
}

It prints nan again. Eventually the behaviour of D floating point operations at compile time will need to become much more similar to their run-time behaviour, to simplify language semantics and to have more "deterministic" results. You can see a similar problem here, some floating point circus, that I've recently shown in D.learn:

import std.math: sqrt, PI;
import std.stdio: writefln;

void main() {
  const double x1 = 3.0 * PI / 16.0;
  writefln("%.17f", sqrt(1.0 / x1));

  double x2 = 3.0 * PI / 16.0;
  writefln("%.17f", sqrt(1.0 / x2));

  real x3 = 3.0 * PI / 16.0;
  writefln("%.17f", sqrt(1.0 / x3));

  real x4 = 3.0L * PI / 16.0L;
  writefln("%.17f", sqrt(1.0L / x4));
}

Output with various D compilers:

DMD1:
1.30294003174111994
1.30294003174111972
1.30294003174111979
1.30294003174111979

DMD2:
1.30294003174111972
1.30294003174111972
1.30294003174111979
1.30294003174111979

LDC:
1.30294003174111994
1.30294003174111994
1.30294003174111972
1.30294003174111972

Bye,
bearophile



More information about the Digitalmars-d mailing list