%--------------------------------------------------% % vim: ft=mercury ts=4 sw=4 et %--------------------------------------------------% % Copyright (C) 1995-2007, 2011-2012 The University of Melbourne. % Copyright (C) 2014, 2016-2023 The Mercury team. % This file is distributed under the terms specified in COPYING.LIB. %--------------------------------------------------% % % File: math.m. % Main author: bromage. % Stability: high. % % Higher mathematical operations. (The basics are in float.m.) % % By default, domain errors are currently handled by throwing an exception. % For better performance, each operation in this module that can throw a domain % exception also has an unchecked version that omits the domain check. % % The unchecked operations are semantically safe, since the target math % library and/or floating point hardware perform these checks for you. % The benefit of having the Mercury library perform the checks instead is % that Mercury will tell you in which function or predicate the error % occurred, as well as giving you a stack trace if that is enabled; with % the unchecked operations you only have the information that the % floating-point exception signal handler gives you. % %--------------------------------------------------% %--------------------------------------------------% :- module math. :- interface. %--------------------------------------------------% % % Mathematical constants % % Pythagoras' number. % :- func pi = float. % Base of natural logarithms. % :- func e = float. %--------------------------------------------------% % % "Next integer" operations % % ceiling(X) = Ceil is true if Ceil is the smallest integer % not less than X. % If X is of infinite magnitude then Ceil = X. % :- func ceiling(float) = float. % floor(X) = Floor is true if Floor is the largest integer % not greater than X. % If X is of infinite magnitude then Floor = X. % :- func floor(float) = float. % round(X) = Round is true if Round is the integer closest to X. % If X has a fractional value of 0.5, it is rounded up. % If X is of infinite magnitude then Round = X. % :- func round(float) = float. % truncate(X) = Trunc is true if Trunc is the integer closest to X % such that |Trunc| =< |X|. % If X is of infinite magnitude then Trunc = X. % :- func truncate(float) = float. %--------------------------------------------------% % % Polynomial roots % % sqrt(X) = Sqrt is true if Sqrt is the positive square root of X. % % Domain restriction: X >= 0 % :- func sqrt(float) = float. :- func unchecked_sqrt(float) = float. :- type quadratic_roots ---> no_roots ; one_root(float) ; two_roots(float, float). % solve_quadratic(A, B, C) = Roots is true if Roots are % the solutions to the equation Ax^2 + Bx + C. % % Domain restriction: A \= 0 % :- func solve_quadratic(float, float, float) = quadratic_roots. %--------------------------------------------------% % % Power/logarithm operations % % pow(X, Y) = Res is true if Res is X raised to the power of Y. % % Domain restriction: X >= 0 and (X = 0 implies Y > 0) % :- func pow(float, float) = float. :- func unchecked_pow(float, float) = float. % exp(X) = Exp is true if Exp is e raised to the power of X. % :- func exp(float) = float. % ln(X) = Log is true if Log is the natural logarithm of X. % % Domain restriction: X > 0 % :- func ln(float) = float. :- func unchecked_ln(float) = float. % log10(X) = Log is true if Log is the logarithm to base 10 of X. % % Domain restriction: X > 0 % :- func log10(float) = float. :- func unchecked_log10(float) = float. % log2(X) = Log is true if Log is the logarithm to base 2 of X. % % Domain restriction: X > 0 % :- func log2(float) = float. :- func unchecked_log2(float) = float. % log(B, X) = Log is true if Log is the logarithm to base B of X. % % Domain restriction: X > 0 and B > 0 and B \= 1 % :- func log(float, float) = float. :- func unchecked_log(float, float) = float. %--------------------------------------------------% % % Trigonometric operations % % sin(X) = Sin is true if Sin is the sine of X. % :- func sin(float) = float. % cos(X) = Cos is true if Cos is the cosine of X. % :- func cos(float) = float. % tan(X) = Tan is true if Tan is the tangent of X. % :- func tan(float) = float. % asin(X) = ASin is true if ASin is the inverse sine of X, % where ASin is in the range [-pi/2,pi/2]. % % Domain restriction: X must be in the range [-1,1] % :- func asin(float) = float. :- func unchecked_asin(float) = float. % acos(X) = ACos is true if ACos is the inverse cosine of X, % where ACos is in the range [0, pi]. % % Domain restriction: X must be in the range [-1,1] % :- func acos(float) = float. :- func unchecked_acos(float) = float. % atan(X) = ATan is true if ATan is the inverse tangent of X, % where ATan is in the range [-pi/2,pi/2]. % :- func atan(float) = float. % atan2(Y, X) = ATan is true if ATan is the inverse tangent of Y/X, % where ATan is in the range [-pi,pi]. % :- func atan2(float, float) = float. %--------------------------------------------------% % % Hyperbolic functions % % sinh(X) = Sinh is true if Sinh is the hyperbolic sine of X. % :- func sinh(float) = float. % cosh(X) = Cosh is true if Cosh is the hyperbolic cosine of X. % :- func cosh(float) = float. % tanh(X) = Tanh is true if Tanh is the hyperbolic tangent of X. % :- func tanh(float) = float. %--------------------------------------------------% % % Fused multiply-add operation. % % Succeeds if this grade and platform provide the fused multiply-add % operation. % :- pred have_fma is semidet. % fma(X, Y, Z) = FMA is true if FMA = (X * Y) + Z, rounded as one % floating-point operation. % % This function is (currently) only available on the C backends and only if % the target math library supports it. % Use have_fma/0 to check whether it is supported. % :- func fma(float, float, float) = float. %--------------------------------------------------% %--------------------------------------------------%