flt.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>  <--------------


partial class FLT_COMMON{ATP}

partial class FLT_COMMON{ATP} is -- This partial class implements those routines and iters the code of -- which is common to both the class FLT and FLTD. -- 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 ANGLE 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. -- Version 1.1 Oct 98. Copyright K Hopper, U of Waikato -- Development History -- ------------------- -- Date Who By Detail -- ---- ------ ------ -- 7 Jan 97 kh Original from FLT -- 15 Oct 98 kh Separated out the text conversion. include AVAL{OCTET} ; include COMPARABLE ; include BINARY ; include FLOAT_STR{ATP} ; const is_limited : BOOL := true ; const is_signed : BOOL := true ; --?????private const asize : CARD := Num_Bits / OCTET::Octet_Bits ; build(cursor : BIN_CURSOR) : SAME pre ~void(cursor) and (cursor.remaining >= asize) post true -- a valid result may be zero - ie void!! is -- This creation routine builds a floating point number from the -- appropriate number of octets from the binary string indicated by the given cursor. res : SAME ; loop index : CARD := (asize - 1).downto!(0) ; res[index] := cursor.get_item end ; return res end ; nil : SAME is -- This routine returns the value used to represent NIL -- in this -- case the signalling NaN value! return signalling_NaN(0.int) end ; maxval : SAME is -- This routine returns the maximum representable value of an object in this class. return max_normal end ; minval : SAME is -- This routine returns the maximum representable value of an object in this class. return -max_normal end ; negatable : BOOL is -- This predicate returns true if and only if this class is numeric and -- negatable -- trivially true! return true end ; is_neg : BOOL is -- This predicate returns true if and only if the value of self is less than zero. return self < ATP::zero end ; is_zero : BOOL is -- This predicate returns true if and only if the value of self is exactly zero. return self = ATP::zero end ; is_pos : BOOL is -- This predicate returns true if and only if the value of self is -- greater than zero. return self > ATP::zero end ; is_non_pos : BOOL is return is_pos.not; end; is_non_neg : BOOL is return is_neg.not; end; is_non_zero : BOOL is return is_zero.not; end; in_range(lower, upper : SAME) : BOOL is -- This predicate returns true if and only if self has a value between -- lower and upper inclusive. return ((lower <= self) and (self <= upper)) or ((upper <= self) and (self <= lower)) end ; in_range(rng : $RANGE{ATP}) : BOOL is -- This predicate returns true if and only if self has a value within the given range. return rng.contains(self) end ; in_tolerance(tolerance, val : SAME) : BOOL is -- This predicate returns true if and only if self is within the given tolerance of val. return (self - val).abs <= tolerance end ; -- Properties of the object is_nil : BOOL is -- This predicate returns true if and only if self is the nil value. -- This implementatioin makes use of the fact that in the IEEE arithmetic -- model the only value which will not compare with anything is the -- signalling NaN. return ~(self = self) end ; is_exact : BOOL is -- This predicate returns true if and only if self is an exact integral value. return self = truncate end ; is_nan : BOOL is -- This predicate returns true if and only if self is the NaN value. -- This implementatioin makes use of the fact that in the IEEE arithmetic -- model the only value which will not compare with anything is the -- signalling NaN. return ~(self = self) end ; -- Additional operations. sign : NUM_SIGNS pre ~self.is_nan and ~self.is_inf post ((self > zero) and (result = NUM_SIGNS::Positive)) or ((self = zero) and (result = NUM_SIGNS::Zero)) or (result = NUM_SIGNS::Negative) is -- This routine returns the state of the sign of self dependent upon -- whether the sign of self is negative, zero, or positive. if self < zero then return NUM_SIGNS::Negative elsif self > zero then return NUM_SIGNS::Positive else return NUM_SIGNS::Zero end end ; sgn : SAME pre ~self.is_nan and ~self.is_inf is -- return one/zero/-one if self.is_neg then return -one; elsif self.is_pos then return one; else return zero; end end; square : SAME pre ~self.is_nan and ~self.is_inf and infinity.square_root >= self.abs post result = self * self is -- This routine returns the square of self. return self * self end ; cube : SAME pre ~self.is_nan and ~self.is_inf and infinity.cuberoot >= self post result = self * self * self is -- This routine returns the cube of self. return self * self * self end ; max(other : SAME) : SAME pre ~self.is_nan and ~self.is_inf and ~other.is_nan and ~other.is_inf post ((self > other) and (result = self)) or (result = other) is -- This routine returns the larger of self and arg. if self < other then return other else return self end end ; min(other : SAME) : SAME pre ~self.is_nan and ~self.is_inf and ~other.is_nan and ~other.is_inf post ((self > other) and (result = other)) or (result = self) is -- This routine returns the smaller of self and arg. if self < other then return self else return other end end ; hash : CARD pre true -- no matter what self is post true -- no matter what result is is -- This routine returns a hash value computed from self by successive -- shifts and xors of the bit-pattern forming the numeric value. Because this -- hashing is done on the value as a bit-pattern it does not matter if the -- value is not a number or even infinity! return (NUM_BITS::create(self)).hash end ; binstr : BINSTR pre true post result.size = asize is -- This routine is provided to convert from a FLT/FLTD class value -- to a binary string. res : BINSTR := BINSTR::create ; loop index : CARD := (asize - 1).downto!(0) ; res := res + [index] end ; return res end ; -- Iters sum!(val : SAME) : SAME pre ~val.is_nan and ~val.is_inf post true -- could be anything! is -- This iter yields the sum of all previous values of val. -- Note that other is re-evaluated on each re-entry of the iter. -- Dependent on the value provided this iter may result in an out of bounds value arising which -- will cause an exception to be raised. res : SAME := zero ; loop res := res + val ; yield res end end ; product!(val : SAME) : SAME pre ~val.is_nan and ~val.is_inf post true -- could be anything! is -- This iter yields the product of all previous values of val. Note that -- other is re-evaluated on each re-entry of the iter. Dependent on the -- value provided this iter may result in an out of bounds value arising which -- will cause an exception to be raised. res : SAME := one ; loop res := res * val ; yield res end end ; end ; -- class FLT_COMMON

immutable class FLT < $REAL{FLT}, $OPTION, $FLT_FMT

immutable class FLT < $REAL{FLT}, $OPTION, $FLT_FMT is -- This class embodies normal arithmetic (NOT including trigonometric) -- operations on a floating point approximate number representation. This -- has been chosen 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. -- -- NOTE 1. The class ANGLE 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 FLTD 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 Factored out common code to FLT_COMMON -- 11 Dec 00 kh Revised inheritance/inclusion! include FLT_COMMON{FLT} ; -- - - - - - - - - - - OPTIONAL INCLUSION!! FROM MATHS Library - - - - - - - include LOG_EXP_FUNCTIONS ; include MATH_FUNCTIONS ; -- - - - - - - - - - - END OF OPTIONAL INCLUSION! private const asize : CARD := 4 ; -----------------???????? FUDGE!! const pi : SAME := FLTD::pi.flt ; -- approximately! const e : SAME := FLTD::e.flt ; -- approximately const sqrt_2 : SAME := FLTD::sqrt_2.flt ; -- Approx 2.sqrt. const log_2 : SAME := FLTD::log_2.flt ; -- Approx 2.log. const log2_e : SAME := FLTD::log2_e.flt ; -- Approx e.log2. const log10_e : SAME := FLTD::log10_e.flt ; -- Approx e.log10. const log_10 : SAME := FLTD::log_10.flt ; -- Approx 10.log. const half_pi : SAME := FLTD::half_pi.flt ; -- Approx pi/2. const quarter_pi : SAME := FLTD::quarter_pi.flt ; -- Approx pi/4. const inv_sqrt_2 : SAME := FLTD::inv_sqrt_2.flt ; -- Approx 1/(2.sqrt). const inv_pi : SAME := FLTD::inv_pi.flt ; -- Approx 1/pi. const double_inv_pi : SAME := FLTD::double_inv_pi.flt ; -- Approx 2/pi const double_sqrt_pi : SAME := FLTD::double_sqrt_pi.flt ; -- App 2*(pi.sqrt) const min_exp : INT := -125 ; -- The minimum negative integer x such that b^(x-1) is in the range -- of normalized floating point numbers. const min_exp10 : INT := -37 ; -- The minimum x such that 10^x is in the range of normalized floating point numbers. const max_exp : INT := 128 ; -- maximum permissible exponent const max_exp10 : INT := 38 ; -- max x s.t 10^x is in range. const epsilon : SAME := 1.19209290e-07 ; -- min x > 0.0 s.t, 1.0+x/=x const digits : INT := 6 ; -- No of decimal digits of precn const mantissa_bits : INT := 24 ; -- No of bits in the significand, -- including an implied bit. const zero : SAME := 0.0 ; -- See $NFE. const half : SAME := 0.5 ; -- used in rounding! const one : SAME := 1.0 ; const Decimal_Multiplier : SAME := 10.0 ; const Max_Precision : CARD := 6 ; -- digits before rounding problems const Num_Bits : CARD := 32 ; -- IEEE Single 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 FLT_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 FLT_SIGNALLING_NAN end ; infinity : SAME is -- This routine returns the representation of infinity -- which is -- implementation-dependent. Built-in to this implementation. builtin FLT_INFINITY end ; min_normal : SAME is -- This routine returns the smallest normalized positive number -- in this class. Built-in to this implementation. builtin MIN_NORMAL end ; max_normal : SAME is -- This routine returns the largest normalized positive number -- in this class. Built-in to this implementation. builtin 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 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 MAX_SUBNORMAL end ; create(val : CARD) : SAME is -- This routine returns the value of val converted to a floating point representation. return val.flt end ; create(val : FIELD) : SAME is -- This routine returns the value of val converted to a floating point representation. return val.flt end ; create(val : INT) : SAME is -- This routine returns the value of val converted to a floating point representation. return val.flt 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.flt 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.flt end ; create(val : FLT) : SAME is -- This routine returns the value of val since this routine is provided -- for symmetry between numeric conversion/creation routines. return val end ; create(val : FLTD) : SAME pre (val < maxval.fltd) and (val > minval.fltd) post true is -- This routine returns the value of val converted to double length -- floating point representation. return val.flt end ; -- Standard numeric value conversion operations card : CARD pre ~self.is_nan and ~self.is_inf and self.is_exact and (CARD::maxval.flt >= self) post true is -- This routine returns an exact number version of self. This facility -- is a compiler primitive in this implementation. builtin FLT_CARD end ; field : FIELD pre ~self.is_nan and ~self.is_inf and self.is_exact and (FIELD::maxval.flt >= self) post true is -- This routine returns an exact number version of self. This facility -- is a compiler primitive in this implementation. builtin FLT_FIELD end ; int : INT pre ~self.is_nan and ~self.is_inf and self.is_exact and (INT::maxval.flt >= self) and (INT::minval.flt <= self) post true is -- This routine returns an exact number version of self. This facility -- is a compiler primitive in this implementation. builtin FLT_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 provided that it is a number and is integral. return INTI::create(self); end ; rat : RAT pre ~self.is_nan and ~self.is_inf post create(result) = truncate is -- This routine returns the value of self as an infinite precision -- integer provided that it is a number and is integral. return RAT::create(self) end ; flt : FLT pre ~self.is_nan and ~self.is_inf post result = self is -- This routine produces a copy of self. It is included for symmetry -- between numeric conversion routines. return self end ; fltd : FLTD pre ~self.is_nan and ~self.is_inf post result.flt = self is -- This routine returns the value of self as a double length IEEE -- representation. Built-in to this implementation. builtin FLT_FLTD 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)) post true 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 FLT_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 FLT_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 FLT_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 FLT_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 FLT_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 FLT_POW end ; exp : SAME is -- This routine returns the exponential e^self. Built-in. builtin FLT_EXP end ; log : SAME is -- This routine returns the natural logarithm of self. Built-in. builtin FLT_LOG end ; sin:SAME is return fltd.sin.flt; end; cos:SAME is return fltd.cos.flt; end; tan:SAME is return fltd.tan.flt; end; -- Relations between objects is_eq(other : SAME) : BOOL is -- This predicate returns tru if and only if self and other have the same value. -- Built-in to this implementation. builtin FLT_IS_EQ end ; is_lt(other : SAME ) : BOOL is -- This predicate returns true if and only if other is less than self. -- Built-in to this implementation. builtin FLT_IS_LT end ; is_normal : BOOL is -- This predicate returns true if and only if self is a normalised -- number. Built-in to this implementation. builtin FLT_ISNORMAL end ; is_subnormal : BOOL is -- This predicate returns true if and only if self is an un-normalised -- number. Built-in to this implementation. builtin FLT_ISSUBNORMAL end ; is_zero : BOOL is -- This predicate returns true if and only if self is zero. Built-in to -- this implementation. builtin FLT_ISZERO end ; signbit_set : BOOL is -- This predicate returns true if and only if the sign bit of self is -- set. Built-in to this implementation. builtin FLT_SIGNBIT end ; is_finite : BOOL is -- This predicate returns true if and only if self is zero, subnormal -- or normal. return fltd.is_finite end ; is_inf : BOOL is -- This predicate returns true if and only if self is infinite. return fltd.is_inf 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 FLT_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 FLT_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 FLT_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 FLT_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 ; private scale_by_builtin(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) -- -- Thos operation is performed by exponent manipulation rather than -- by actually performing the exponentiation or multiplication. Built-in to -- this implementation. builtin FLT_SCALBN end ; scale_by(exp : INT) : SAME pre ~self.is_nan and ~self.is_inf is -- This routine returns the result of computing -- self * 2.pow(exp) if is_pos then return scale_by_builtin(exp); elsif (-self).is_pos then return -((-self).scale_by_builtin(exp)); else return self; end; end; get_representation(out sign : BOOL, out exp : INT, out mantissa : INT) 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 FLT_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 FLT_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 FLT_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 FLT_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 FLT_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 self 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. -- -- NOTE self.remainder(0), self.mod(0), infinity.remainder(other), -- and infinity.mod(other) are invalid operations that produce -- a NaN. builtin FLT_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 also be read in -- relation to this routine. Built-in to this implementation. builtin FLT_FMOD end ; abs : SAME pre ~self.is_nan and ~self.is_inf post (result.is_non_neg) and(result=self or result=-self) is -- This routine returns the absolute value of self. Built-in to this -- implementation. builtin FLT_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 FLT_SQRT end ; sqrt : SAME pre (self >= zero) post true -- (result.square - self).abs <= Delta is -- This routine returns the square root of self. It makes use of the -- routine above which has no pre-conditions in order to do this. 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 ; -- FLT

class FLTX

class FLTX is -- THIS IS A DUMMY PENDING COMPILER BUG FIX!! end ;

class FLTDX

class FLTDX is -- THIS IS A DUMMY PENDING COMPILER BUG FIX!! end ;