{: test that exp(ln(x)*y) causes a fatal error if x & y are large enough
   this tests for very large x and y just large enough to overflow }

#include "sys.inc.pas"

program d08a( output );

var
   e : real;
   k : real;
   x : real;
   y : real;
   z : real;

function side : real;
begin
   side := k;
   k := k+1;
end; { side }

begin {d08a}

   k := 1;
   x := exp(ln(side)*1);
   if abs(x-1) > 1.0e-37 then begin
      writeln( 'unexpected value of exp(ln(1)) is ', x);
   end;
   if k <> 2 then
      writeln( 'ln(x) in exp(ln(x)*y) has side effects' );

   k := 1;
   x := exp(ln(1)*side);
   if abs(x-1) > 1.0e-37 then begin
      writeln( 'unexpected value of exp(ln(1)) is ', x);
   end;
   if k <> 2 then
      writeln( 'y in exp(ln(x)*y) for debug has side effects' );

   {find y, the smallest number > 1}
   e := REAL_EPSILON;
   y := 1+e;
   writeln( 'e is ', e, ', 1+e = 1 is ', y=y+e );

   {write( 'checking for underflow or denormalise ... ' );}
   x := REAL_MIN;
   writeln('min real is ', x);

   {find z, the largest number < 1}
   k := REAL_EPSILON/2;
   z := 1 - k;
   writeln( 'k is ', k, ', 1-k = 1 is ', z = z-k );

   x := REAL_MAX;
   writeln('max real is ', x);

   { this shouldn't overflow ... }
   writeln('exp(ln(', x, ')*(1-', 1-z, ')) is ', exp(ln(x)*z));

   writeln( 'checking for overflow, expecting to generate a fatal error' );
   writeln('exp(ln(', x, ')*(1+', y-1, ')) is ', exp(ln(x)*y));

   writeln( 'fails: exp(ln(x)*y) overflow not detected for large x' );
end. { d08a }
