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