------------------------->  GNU Sather - sourcefile  <-------------------------
-- Copyright (C) 199x by International Computer Science Institute            --
-- This file is part of the GNU Sather library. It is free software; you may --
-- redistribute  and/or modify it under the terms of the GNU Library General --
-- Public  License (LGPL)  as published  by the  Free  Software  Foundation; --
-- either version 2 of the license, or (at your option) any later version.   --
-- This  library  is distributed  in the  hope that it will  be  useful, but --
-- WITHOUT ANY WARRANTY without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See Doc/LGPL for more details.       --
-- The license text is also available from:  Free Software Foundation, Inc., --
-- 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA                     --
-------------->  Please email comments to <bug-sather@gnu.org>  <--------------

-- Author: Alex Cozzi <cozzi@neurop2.ruhr-uni-bochum.de>

class MATH_TEST{T < $REAL_NUMBER{T} } is
   include TEST;
   -- some basic tests on floating point classes

   basic(name:STR) is
      class_name(name);
      -------------------------------------------------------------
      -- first obtain some constants
      -- some normal ones, but we test them anyway,
      -- maybe it a little paranoic, though.
      zero:T :=#T(0.0);
      test("0",zero.str,"0");
      one:T :=#T(1.0);
      test("1",one.str,"1");
      ------------------------------------------------------------
      -- now some strange beasts:
      -- negative zero
      -- this one fails, because RATs are used in the compiler
      -- for floating point, and RATs don't have a signed zero.
      unchecked_test("#T(-0.0)",(#T(-0.0)).str,"-0");
      -- this one works
      nzero:T :=-zero;
      test("-0",nzero.str,"-0");
      -- infinity
      inf:T :=#T(1.0/0.0);
      test("1.0/0.0",inf.str,"Inf");
      -- negative infinity
      ninf:T :=#T(-1.0/0.0);
      test("-1.0/0.0",ninf.str,"-Inf");
      ------------------------------------------------------------
      -- an even more strange beast, a NaN, 
      -- this gives me some funny problems.
      -- Let's show something:
      -- this first test is allright
      test("0.0/0.0 with variables",(zero/zero).str,"NaN");
      -- this expression is allright too.
      -- Specialized the following functions due to hassles
      -- with the typebound (ben)
      nan:FLT :=FLT::zero/FLT::zero;
      test("0.0/0.0",nan.str,"NaN");
      nan2:FLTD :=FLTD::zero/FLTD::zero;
      test("0.0/0.0",nan2.str,"NaN");
      -- instead, this one dumps core
      test("0.0/0.0 with constants. May dump core",(0.0/0.0).str,"NaN");
      -- and this expression too
      -- nan3:T :=#T(0.0/0.0); test("0.0/0.0",nan2.str,"NaN");
      -----------------------------------------------------------
      -- Now some fun, let's test equality
      -- an easy one
      test("1=1",(one=one).str,"true");
      -- in IEEE -0 = +0
      test("-0=0",(zero=nzero).str,"true");
      -- let's test extreme cases
      test("Inf=Inf",(inf=inf).str,"true");
      test("-Inf=-Inf",(ninf=ninf).str,"true");
      test("Inf=-Inf",(inf=ninf).str,"false");
      -- in IEEE NaN /= NaN
      test("NaN=NaN",(nan=nan).str,"false");
      -----------------------------------------------------------
      -- now let's test inequality
      -- an easy one
      test("1/=1",(one/=one).str,"false");
      -- in IEEE -0 = +0
      test("-0/=0",(zero/=nzero).str,"false");
      -- let's test extreme cases
      test("Inf/=Inf",(inf/=inf).str,"false");
      test("-Inf/=-Inf",(ninf/=ninf).str,"false");
      test("Inf/=-Inf",(inf/=ninf).str,"true");
      -- in IEEE NaN /= NaN
      test("NaN/=NaN",(nan/=nan).str,"true");
      -----------------------------------------------------------
      -- testing of IEEE classification functions: is_nan
      -- All of these dump core
      test("0.0.is_nan. May dump core",zero.is_nan.str,"false");
      test("-0.0.is_nan. May dump core",nzero.is_nan.str,"false");
      test("NaN.is_nan. May dump core",nan.is_nan.str,"true");
      test("Inf.is_nan. May dump core",inf.is_nan.str,"false");
      test("-Inf.is_nan. May dump core",ninf.is_nan.str,"false");
      -----------------------------------------------------------
      -- testing of math lib functions, sqrt
      test("sqrt(0.0)",zero.sqrt.str,"0");
      -- I'm not sure about the following,
      test("sqrt(-0.0)",(-zero).sqrt.str,"-0");
      test("sqrt(-1.0)",(-one).sqrt.str,"NaN");
      ----------------------------------------------------------
      -- testing of trascendental function, log
      -- Solaris at least does the wrong thing by default,
      -- so these are unchecked.  :-(
      unchecked_test("log(0.0)",zero.log.str,"-Inf");
      unchecked_test("log(-0.0)",(-zero).log.str,"NaN");
      unchecked_test("log(-1.0)",(-one).log.str,"NaN");

      finish;
   end;
end; 

-------------------------------------------------------------------

class FLT_TEST is
    main is
        MATH_TEST{FLT}::basic("FLT");
    end;
end;
-------------------------------------------------------------------
class FLTD_TEST is
    main is
	MATH_TEST{FLTD}::basic("FLTD");
    end;
end; 

-------------------------------------------------------------------
