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