Next: , Previous: fat_sparse_bitset, Up: Top


27 float

     %--------------------------------------------------%
     % vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
     %--------------------------------------------------%
     % Copyright (C) 1994-1998,2001-2008,2010, 2012 The University of Melbourne.
     % This file may only be copied under the terms of the GNU Library General
     % Public License - see the file COPYING.LIB in the Mercury distribution.
     %--------------------------------------------------%
     %
     % File: float.m.
     % Main author: fjh.
     % Stability: medium.
     %
     % Floating point support.
     %
     % Floats are double precision, except in .spf grades where they
     % are single precision.
     %
     % Note that implementations which support IEEE floating point
     % should ensure that in cases where the only valid answer is a "NaN"
     % (the IEEE float representation for "not a number"), the det
     % functions here will halt with a runtime error (or throw an exception)
     % rather than returning a NaN.  Quiet (non-signalling) NaNs have a
     % semantics which is not valid in Mercury, since they don't obey the
     % axiom "all [X] X = X".
     %
     % XXX Unfortunately the current Mercury implementation does not
     % do that on all platforms, since neither ANSI C nor POSIX provide
     % any portable way of ensuring that floating point operations
     % whose result is not representable will raise a signal rather
     % than returning a NaN.  (Maybe C9X will help...?)
     % The behaviour is correct on Linux and Digital Unix,
     % but not on Solaris, for example.
     %
     % IEEE floating point also specifies that some functions should
     % return different results for +0.0 and -0.0, but that +0.0 and -0.0
     % should compare equal.  This semantics is not valid in Mercury,
     % since it doesn't obey the axiom `all [F, X, Y] X = Y => F(X) = F(Y)'.
     % Again, the resolution is that in Mercury, functions which would
     % return different results for +0.0 and -0.0 should instead halt
     % execution with a run-time error (or throw an exception).
     %
     % XXX Here too the current Mercury implementation does not
     % implement the intended semantics correctly on all platforms.
     %
     % XXX On machines such as x86 which support extra precision
     % for intermediate results, the results may depend on the
     % level of optimization, in particular inlining and evaluation
     % of constant expressions.
     % For example, the goal `1.0/9.0 = std_util.id(1.0)/9.0' may fail.
     %
     %--------------------------------------------------%
     %--------------------------------------------------%
     
     :- module float.
     :- interface.
     
     :- import_module pretty_printer.
     
     %--------------------------------------------------%
     %
     % Arithmetic functions
     %
     
     	% addition
     	%
     :- func (float::in) + (float::in) = (float::uo) is det.
     
     	% subtraction
     	%
     :- func (float::in) - (float::in) = (float::uo) is det.
     
     	% multiplication
     	%
     :- func (float::in) * (float::in) = (float::uo) is det.
     
     	% division
     	% Throws a `math.domain_error' exception if the right operand is zero.
         % See the comments at the top of math.m to find out how to disable
         % this check.
     	%
     :- func (float::in) / (float::in) = (float::uo) is det.
     
     	% unchecked_quotient(X, Y) is the same as X / Y, but the behaviour
         % is undefined if the right operand is zero.
     	%
     :- func unchecked_quotient(float::in, float::in) = (float::uo) is det.
     
     	% unary plus
     	%
     :- func + (float::in) = (float::uo) is det.
     
     	% unary minus
     	%
     :- func - (float::in) = (float::uo) is det.
     
     %--------------------------------------------------%
     %
     % Comparison predicates
     %
     
     	% less than, greater than, less than or equal, greater than or equal.
     	%
     :- pred (float::in)  < (float::in) is semidet.
     :- pred (float::in) =< (float::in) is semidet.
     :- pred (float::in) >= (float::in) is semidet.
     :- pred (float::in) >  (float::in) is semidet.
     
     %--------------------------------------------------%
     %
     % Conversion functions
     %
     
     	% Convert int to float
     	%
     :- func float(int) = float.
     
     	% ceiling_to_int(X) returns the smallest integer not less than X.
     	%
     :- func ceiling_to_int(float) = int.
     
     	% floor_to_int(X) returns the largest integer not greater than X.
     	%
     :- func floor_to_int(float) = int.
     
     	% round_to_int(X) returns the integer closest to X.
     	% If X has a fractional value of 0.5, it is rounded up.
     	%
     :- func round_to_int(float) = int.
     
     	% truncate_to_int(X) returns
     	% the integer closest to X such that |truncate_to_int(X)| =< |X|.
     	%
     :- func truncate_to_int(float) = int.
     
     %--------------------------------------------------%
     %
     % Miscellaneous functions
     %
     
     	% absolute value
     	%
     :- func abs(float) = float.
     
     	% maximum
     	%
     :- func max(float, float) = float.
     
     	% minimum
     	%
     :- func min(float, float) = float.
     
     	% pow(Base, Exponent) returns Base raised to the power Exponent.
     	% Fewer domain restrictions than math.pow: works for negative Base,
     	% and float.pow(B, 0) = 1.0 for all B, even B=0.0.
     	% Only pow(0, <negative>) throws a `math.domain_error' exception.
     	%
     :- func pow(float, int) = float.
     
     	% Compute a non-negative integer hash value for a float.
     	%
     :- func hash(float) = int.
     
     	% Is the float point number not a number or infinite?
     	%
     :- pred is_nan_or_inf(float::in) is semidet.
     
     	% Is the floating point number not a number?
     	%
     :- pred is_nan(float::in) is semidet.
     
     	% Is the floating point number infinite?
     	%
     :- pred is_inf(float::in) is semidet.
     
     %--------------------------------------------------%
     %
     % System constants
     %
     
     	% Maximum finite floating-point number
     	%
     	% max = (1 - radix ** mantissa_digits) * radix ** max_exponent
     	%
     :- func float.max = float.
     
     	% Minimum normalised positive floating-point number
     	%
     	% min = radix ** (min_exponent - 1)
     	%
     :- func float.min = float.
     
     	% Smallest number x such that 1.0 + x \= 1.0
     	% This represents the largest relative spacing of two
     	% consecutive floating point numbers.
     	%
     	% epsilon = radix ** (1 - mantissa_digits)
     	%
     :- func float.epsilon = float.
     
     	% Radix of the floating-point representation.
     	% In the literature, this is sometimes referred to as `b'.
     	%
     :- func float.radix = int.
     
     	% The number of base-radix digits in the mantissa.  In the
     	% literature, this is sometimes referred to as `p' or `t'.
     	%
     :- func float.mantissa_digits = int.
     
     	% Minimum negative integer such that:
     	%	radix ** (min_exponent - 1)
     	% is a normalised floating-point number.  In the literature,
     	% this is sometimes referred to as `e_min'.
     	%
     :- func float.min_exponent = int.
     
     	% Maximum integer such that:
     	%	radix ** (max_exponent - 1)
     	% is a normalised floating-point number.  In the literature,
     	% this is sometimes referred to as `e_max'.
     	%
     :- func float.max_exponent = int.
     
         % Convert a float to a pretty_printer.doc for formatting.
         %
     :- func float.float_to_doc(float) = doc.
     
     %--------------------------------------------------%
     %--------------------------------------------------%