fltd.sa
Generated by gen_html_sa_files from ICSI. Contact gomes@icsi.berkeley.edu for details
-------------------------> GNU Sather - sourcefile <-------------------------
-- Copyright (C) 2000 by K Hopper, University of Waikato, New Zealand --
-- 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> <--------------
immutable class FLTD < $REAL{FLTD}, $FLT_FMT
immutable class FLTD < $REAL{FLTD}, $FLT_FMT is
-- This class embodies normal arithmetic (NOT including trigonometric)
-- operations on a floating point approximate number representation. This
-- has been chosn to be the single 32-bit IEEE 754-1984 standard
-- representation. For convenience of implementation, most of the operations
-- are done in terms of the double length version operations for portability.
--
-- This source text provides for optional inclusion of logarithmic
-- and exponential functions as a group using the LOG_EXP_FUNCTIONS partial
-- class. Bessel, gamma and erf functions may additionally be included
-- from the partial class MATH_FUNCTIONS.
--
-- NOTE 1. The class ANGLED in the Geometric section of this library has
-- been extracted from here since the (inverse) trigonometric operations
-- are conversions between an angle domain and the domain of numbers
-- or factors.
--
-- 2. This class and FLT are exceptions to the general rule in
-- the required library that immutable classes all inherit from $BINARY.
-- Version 1.3 Dec 2000. Copyright K Hopper, U of Waikato
-- Development History
-- -------------------
-- Date Who By Detail
-- ---- ------ ------
-- 7 Jan 97 kh Original from standard Sather distribution.
-- 15 Sep 98 kh Representation moved out to FLOAT_STR
-- 8 Oct 98 kh Common routines factored out to FLT_COMMON
-- 11 Dec 00 kh Revised inheritance/inclusion
include FLT_COMMON{FLTD} ;
-- - - - - - - - - - - OPTIONAL INCLUSION!! FROM MATHS Library - - - - - - - -
include DLOG_EXP_FUNCTIONS ;
include DMATH_FUNCTIONS ;
-- - - - - - - - - - - END OF OPTIONAL INCLUSION!
private const asize : CARD := 8 ; -----------------???????? FUDGE!!
pi : SAME is
-- This is a 'routine' returning the implementation-dependent
-- approximation to the mathematical number pi. Built-in to this
-- implementation.
builtin FLTD_PI
end ;
e : SAME is
-- This is a 'routine' returning the implementation-dependent
-- approximation to the mathematical natural logarithm base. Built-in to
-- this implementation.
builtin FLTD_E
end ;
sqrt_2 : SAME is
-- This is a 'routine' returning the implementation-dependent
-- approximation to the square root of 2. Built-in to this implementation.
builtin FLTD_SQRT_2
end ;
log_2 : SAME is
-- This is a 'routine' returning the implementation-dependent
-- approximation to the natural logarithm of 2.
builtin FLTD_LOG_2
end ;
log2_e : SAME is
-- This is a 'routine' returning the implementation-dependent
-- approximation to e.log2.
builtin FLTD_LOG2_E
end ;
log10_e : SAME is
-- This is a 'routine' returning the implementation-dependent
-- approximation to e.log10.
builtin FLTD_LOG10_E
end ;
log_10 : SAME is
-- This is a 'routine' returning the implementation-dependent
-- approximation to the natural logarithm of 10.
builtin FLTD_LOG_10
end ;
half_pi : SAME is
-- This is a 'routine' returning the implementation-dependent
-- approximation to pi/2. Built-in to this implementation.
builtin FLTD_HALF_PI
end ;
quarter_pi : SAME is
-- This is a 'routine' returning the implementation-dependent
-- approximation to pi/4. Built-in to this implementation.
builtin FLTD_QUARTER_PI
end ;
inv_sqrt_2 : SAME is
-- This is a 'routine' returning the implementation-dependent
-- approximation to one divided by the square-root of 2. Built-in to this
-- implementation.
builtin FLTD_INV_SQRT_2
end ;
inv_pi : SAME is
-- This is a 'routine' returning the implementation-dependent
-- approximation to the inverse of pi. Built-in to this implementation.
builtin FLTD_INV_PI
end ;
double_inv_pi : SAME is
-- This is a 'routine' returning the implementation-dependent
-- approximation to twice the inverse of pi. Built-in to this
-- implementation.
builtin FLTD_DOUBLE_INV_PI
end ;
double_sqrt_pi : SAME is
-- This is a 'routine' returning the implementation-dependent
-- approximation to twice the inverse of the square root of pi. Built-in to
-- this implementation.
builtin FLTD_DOUBLE_SQRT_PI
end ;
-- The minimum negative integer x such that b^(x-1) is in the range
-- of normalized floating point numbers.
const min_exp : INT := -1021 ;
const min_exp10 : INT := -307 ;
-- The minimum x such that 10^x is in the range of normalized floating
-- point numbers.
const max_exp : INT := 1024 ; -- maximum permissible exponent
const max_exp10 : INT := 308 ; -- max x s.t 10^x is in range.
const epsilon : SAME := 2.2204460492503131e-16d ; -- min x > 0.0 s.t, 1.0+x/=x
const digits : INT := 15 ; -- No of decimal digits of precn
const mantissa_bits : INT := 53 ; -- No of bits in the significand, including an implied bit.
const zero : SAME := 0.0d ; -- See $NFE.
const half : SAME := 0.5d ; -- used in rounding!
const one : SAME := 1.0d ;
const Decimal_Multiplier : SAME := 10.0d ;
const Max_Precision : CARD := 16 ; -- digits for representation!
const Num_Bits : CARD := 64 ; -- IEEE double size numbers
-- The following two routines are IEEE representation specific.
quiet_NaN(sig : INT) : SAME is
-- This routine returns the representation which is interpreted by
-- the IEEE arithmetic model as being a quiet (ie non-interrupting) NaN.
-- The argument is not used in this implementation.
-- Built-in to this implementation.
builtin FLTD_QUIET_NAN
end ;
signalling_NaN(sig : INT) : SAME is
-- This routine returns the representation which is interpreted by
-- the IEEE arithmetic model as a signalling (ie interrupt generating) NaN.
-- The argument is unused in this implementation. Built-in to this
-- implementation.
builtin FLTD_SIGNALLING_NAN
end ;
infinity : SAME is
-- This routine returns the representation of infinity -- which is
-- implementation-dependent. Built-in to this implementation.
builtin FLTD_INFINITY
end ;
min_normal : SAME is
-- This routine returns the smallest normalized positive number
-- in this class. Built-in to this implementation.
builtin FLTD_MIN_NORMAL
end ;
max_normal : SAME is
-- This routine returns the largest normalized positive number
-- in this class. Built-in to this implementation.
builtin FLTD_MAX_NORMAL
end ;
min_subnormal : SAME is
-- This routine returns the smallest un-normalized positive number
-- in this class. Built-in to this implementation.
builtin FLTD_MIN_SUBNORMAL
end ;
max_subnormal : SAME is
-- This routine returns the largest un-normalized positive number
-- in this class. Built-in to this implementation.
builtin FLTD_MAX_SUBNORMAL
end ;
create(val : CARD) : SAME is
-- This routine returns the value of val converted to a floating point
-- representation.
return val.fltd
end ;
create(val : FIELD) : SAME is
-- This routine returns the value of val converted to a floating point
-- representation.
return val.fltd
end ;
create(val : INT) : SAME is
-- This routine returns the value of val converted to a floating point
-- representation.
return val.fltd
end ;
create(val : INTI) : SAME
pre (val < maxval.round.inti) and (val > minval.round.inti)
post true
is
-- This routine returns the value of val converted to a floating point
-- representation.
return val.fltd
end ;
create(val : RAT) : SAME
pre (val < maxval.round.rat) and (val > minval.round.rat)
post true
is
-- This routine returns the value of val converted to a floating point
-- representation.
return val.fltd
end ;
create(val : FLT) : SAME is
--This routine returns the value of val converted to a floating point representation.
return val.fltd
end ;
create(val : FLTD) : SAME is
-- This routine returns the value of val. It is provided to ensure
-- symmetry of arithmetic conversion/creation routines.
return val
end ;
-- Standard numeric value conversion operations
card : CARD
pre ~self.is_nan
and ~self.is_inf
and self.is_exact
and (CARD::maxval.fltd >= self)
post true
is
-- This routine returns an exact number version of self. This is a
-- compiler primitive in this implementation.
builtin FLTD_CARD
end ;
field : FIELD
pre ~self.is_nan
and ~self.is_inf
and self.is_exact
and (FLT::maxval.fltd >= self)
post true
is
--This routine returns an exact number version of self. This is a
-- compiler primitive in this implementation.
builtin FLTD_FIELD
end ;
int : INT
pre ~self.is_nan
and ~self.is_inf
and self.is_exact
and (INT::maxval.fltd >= self)
and (INT::minval.fltd <= self)
post true
is
-- This routine returns an exact number version of self. This is a
-- compiler primitive in this implementation.
builtin FLTD_INT
end ;
inti : INTI
pre ~self.is_nan
and ~self.is_inf
and self.is_exact
-- post create(result) = truncate
is
-- This routine returns the value of self as an infinite precision integer.
return INTI::create(self)
end ;
rat : RAT
pre ~self.is_nan
and ~self.is_inf
post create(result) = self
is
-- This routine returns the value of self as an infinite precision integer.
return RAT::create(self)
end ;
flt : FLT
pre ~self.is_nan
and ~self.is_inf
and (FLT::maxval.fltd >= abs)
post result.fltd = self
is
-- This routine produces a copy of self as a single-precision floating
-- point number. This is a compiler primitive in this implementation.
builtin FLTD_FLT
end ;
fltd : FLTD
pre ~self.is_nan
and ~self.is_inf
post result = self
is
-- This routine returns the value of self!
return self
end ;
-- The standard arithmetic operations.
plus(other : SAME) : SAME
pre ~self.is_nan
and ~self.is_inf
and ~other.is_nan
and ~other.is_inf
and (((self >= zero)
and (other < (maxval - self)))
or ((other >= zero)
and (self < (maxval - other)))
or (self.sign /= other.sign))
is
--This routine returns the result of adding self to other providing
-- that this is representable in the value domain. Built-in to this
-- implementation.
builtin FLTD_PLUS
end ;
minus(other : SAME) : SAME
pre ~self.is_nan
and ~self.is_inf
and ~other.is_nan
and ~other.is_inf
and (((self >= zero)
and (other < (maxval - self)))
or ((other >= zero)
and (self < (maxval - other)))
or (self.sign /= other.sign))
post true
is
--This routine returns the result of subtracting other from self
-- provided that this is representable in the value domain. Built-in to
-- this implementation.
builtin FLTD_MINUS
end ;
negate : SAME
pre ~self.is_nan
and ~self.is_inf
post true
is
--This routine returns the negation of self. While the mathematical
-- number model dictates that this should be the same as subtracting self
-- from zero, the IEEE model differs in doing different things depending
-- on the sign bit and rounding mode. Built-in to this implementation.
builtin FLTD_NEGATE
end ;
times(other : SAME) : SAME
pre ~self.is_nan
and ~self.is_inf
and ~other.is_nan
and ~other.is_inf
and ((maxval / other).abs <= self.abs)
post true
is
--This routine returns the signed product of self and other. Built-in
-- to this implementation.
builtin FLTD_TIMES
end ;
div(other : SAME) : SAME
pre ~self.is_nan
and ~self.is_inf
and ~other.is_nan
and ~other.is_inf
and (other /= zero)
post true
is
--This routine returns the signed quotient of self and other.
-- Built-in to this implementation.
builtin FLTD_DIV
end ;
pow(arg : SAME) : SAME is
--This routine returns self raised to the arg'th power. Note that
-- self.pow(0.0) = 1.0 for all self. Built-in.
builtin FLTD_POW
end ;
exp : SAME is
--This routine returns the exponential e^self. Built-in.
builtin FLTD_EXP
end ;
log : SAME is
--This routine returns the natural logarithm of self. Built-in.
builtin FLTD_LOG
end ;
private sin_approx(x2, xn:SAME, n:CARD):SAME is
-- n+2-th and later terms of Tayler series.
-- x2=x^2, xn=(+-1) x^n/n!
xn:=-xn*x2/((n+1)*(n+2)).fltd;
if self.is_eq(self+xn) then return xn;
else return xn+sin_approx(x2,xn,n+2);
end
end;
private sin_approx:SAME is return self+sin_approx(self*self,self,1); end;
private cos_approx(x2, xn:SAME, n:CARD):SAME is
-- n+2-th and later terms of Tayler series.
-- x2=x^2, xn=(+-1) x^n/n!
xn:=-xn*x2/((n+1)*(n+2)).fltd;
if one.is_eq(one+xn) then return xn;
else return xn+cos_approx(x2,xn,n+2);
end
end;
private cos_approx:SAME is return one+cos_approx(self*self,one,0); end;
sin:SAME is
a::=self;
x:SAME;
if a.is_neg then x := -a; else x := a; end;
pi2::=pi+pi;
loop while!(x>pi2); x:=x-pi2; end;
if x>pi then a := -a; x := x-pi; end;
if x>half_pi then x := pi-x; end;
if x<=quarter_pi then x:=x.sin_approx; else x:=(half_pi-x).cos_approx; end;
if a.is_neg then return -x; else return x; end;
end;
cos:SAME is return (self+half_pi).sin; end;
tan:SAME is return sin/cos; end;
-- Relations between objects
is_eq(other : SAME) : BOOL is
--This routine returns tru if and only if self and other have the same
-- value. Built-in to this implementation.
builtin FLTD_IS_EQ
end ;
is_lt(other : SAME) : BOOL is
--This rouitne returns true if and only if other is less than self.
-- Built-in to this implementation.
builtin FLTD_IS_LT
end ;
-- Properties of the object
is_normal : BOOL is
--This routine returns true if and only if self is a normalised number.
-- Built-in to this implementation.
builtin FLTD_ISNORMAL
end ;
is_subnormal : BOOL is
--This routine returns true if and only if self is an un-normalised
-- number. Built-in to this implementation.
builtin FLTD_ISSUBNORMAL
end ;
is_zero : BOOL is
--This routine returns true if and only if self is zero. Built-in to
-- this implementation.
builtin FLTD_ISZERO
end ;
signbit_set : BOOL is
--This routine returns true if and only if the sign bit of self is
-- set. Built-in to this implementation.
builtin FLTD_SIGNBIT
end ;
is_finite : BOOL is
--This routine returns true if and only if self is zero, subnormal
-- or normal. Built-in to this implementation.
builtin FLTD_FINITE
end ;
is_inf : BOOL is
--This routine returns true if and only if self is infinite. Built-in
-- to this implementation.
builtin FLTD_ISINF
end ;
-- Representation components and values, etc.
unbiassed_exponent : INT
pre ~self.is_nan
and ~self.is_inf
post true
is
--This routine returns the unbiased exponent of self. Built-in to
-- this implementation.
--
-- NOTE For zero this is INT::maxint.negate, for an infinite value it is
-- INT::maxint. If subnormal, normalization occurs first.
builtin FLTD_ILOGB
end ;
copysign(other : SAME) : SAME
pre ~self.is_nan
and ~self.is_inf
and ~other.is_nan
and ~other.is_inf
post true
is
--This routine returns self with the sign bit set to be the same as
-- the sign bit of other. This routine is provided to overcome some of
-- the limitationns of certain IEEE 754 implementations which have two values
-- of 'zero' in order to make comparison for zero possible. Built-in to
-- this implementation.
builtin FLTD_COPYSIGN
end ;
private next_up : SAME is
--This private routine returns the next higher representable number
-- from self. Note that this version has NO pre_requisites in order to
-- prevent circularity between the public versions of nextup and nextdown.
-- Built-in to this implementation.
builtin FLTD_NEXTUP
end ;
nextup : SAME
pre ~self.is_nan
and ~self.is_inf
and maxval.next_down >= self
post result.next_down = self
is
--This routine returns the next higher representable number from self
-- using the routine which has no pre-requisites.
return next_up
end ;
private next_down : SAME is
--This routine returns the next lower representable number from self.
-- Note that this version has NO pre_requisites in order to prevent
-- circularity between the public versions of nextup and nextdown. Built-in
-- to this implementation.
builtin FLTD_NEXTDOWN
end ;
nextdown : SAME
pre ~self.is_nan
and ~self.is_inf
and -maxval.next_up <= self
post result.next_up = self
is
--This routine returns the next lower representable number from self.
-- Built-in to this implementation.
return next_down
end ;
scale_by(exp : INT) : SAME
pre ~self.is_nan
and ~self.is_inf
and (self > zero)
post true-- Should be some kind of log relation??
is
--This routine returns the result of computing self * 2.pow(exp)
-- This operation is performed by exponent manipulation rather than
-- by actually performing the exponentiation or multiplication. Built-in to
-- this implementation.
builtin FLTD_SCALBN
end ;
get_representation(out sign : BOOL,out exp : INT,out mantissa_lo,out mantissa_hi : CARD)
pre ~self.is_nan
and ~self.is_inf
post true
is
-- This routine splits up the floating point coding into its sign,
-- exponent and mantissa components which are returned in the arguments.
-- Built-in to this implementation.
builtin FLTD_GET_REP
end ;
truncate : SAME
pre ~self.is_nan
and ~self.is_inf
post (result - self).abs < one
is
--This routine returns the value of the nearest integer toward zero.
-- Built-in to this implementation.
builtin FLTD_TRUNCATE
end ;
floor : SAME
pre ~self.is_nan
and ~self.is_inf
post (self - result) < one
is
--This routine returns the largest integral value not greater than
-- self. Built-in to this implementation.
builtin FLTD_FLOOR
end ;
ceiling : SAME
pre ~self.is_nan
and ~self.is_inf
post (result - self) < one
is
--This routine returns the smallest integer not less than self.
-- Built-in to this implementation.
builtin FLTD_CEIL
end ;
round : SAME
pre ~self.is_nan
and ~self.is_inf
post ((result - self.truncate).abs <= (one / (one + one)))
is
--This routine returns the closest integer to self. Built-in to this
-- implementation.
builtin FLTD_ROUND
end ;
remainder(other : SAME) : SAME
pre ~self.is_nan
and ~self.is_inf
and ~other.is_nan
and ~other.is_inf
post ((result * self) - self.abs) < other
is
--This routine returns a remainder of self with respect to other; that
-- is, the result is one of the numbers that differ from slef by an integral
-- multiple of other.
-- Thus (self - result)/other is an integral value, even though it might
-- exceed INT::maxint if it were explicitly computed as an integer.
--
-- This routine and the mod(other) routine return one of the two such
-- results smallest in magnitude. This routine is the operation specified in
-- ANSI/IEEE Std 754-1985; the result of self.mod(other) may differ from
-- remainder's result by +-other. The magnitude of remainder's result can
-- not exceed half that of other; its sign might not agree with either the
-- sign of self or of other. The magnitude of mod's result is less than that
-- of other; its sign agrees with that of self. Neither function will raise
-- an exception as long as both arguments are normal or subnormal. Built-in
-- to this implementation.
-- self.remainder(0), self.mod(0), infinity.remainder(other),
-- and infinity.mod(other) are invalid operations that produce a NaN.
builtin FLTD_REMAINDER
end ;
mod(other : SAME) : SAME
pre ~self.is_nan
and ~self.is_inf
and ~other.is_nan
and ~other.is_inf
post ((result * self) - self.abs) < other
is
--This routine returns the modulus of self with respect to other. The
-- comment above with regard to the remainder routine should be read in
-- conjunction with this routine. Built-in to this implementation.
builtin FLTD_FMOD
end ;
abs : SAME
pre ~self.is_nan
and ~self.is_inf
post ((self < zero)
and (result = -self))
or (result = self)
is
--This routine returns the absolute value of self. Built-in to this
-- implementation.
builtin FLTD_FABS
end ;
private square_root : SAME is
--This private routine returns the square root of self. It is provided
-- to avoid the circularity in square and square-root pre-requisites!
-- Built-in to this implementation.
builtin FLTD_SQRT
end ;
sqrt : SAME
pre (self >= zero)
post true -- (result.square - self).abs <= Delta
is
--This routine returns the square root of self. Built-in to this
-- implementation.
return square_root
end ;
private cuberoot : SAME is
--This routine returns the cube root of self. It is provided
-- to avoid the circularity in cube and cube-root pre-requisites! Built-in
-- to this implementation.
builtin FLT_CBRT
end ;
cube_root : SAME
pre (self >= zero)
post true -- (result.cube - self).abs <= Delta
is
--This routine returns the cube root of self. Built-in to this
-- implementation.
return cuberoot
end ;
end ; -- class FLTD