|Did you know ...||Search Documentation:|
Arithmetic functions are terms which are evaluated by the arithmetic predicates described in section 4.27.2. There are four types of arguments to functions:
|Expr||Arbitrary expression, returning either a floating point value or an integer.|
|IntExpr||Arbitrary expression that must evaluate to an integer.|
|RatExpr||Arbitrary expression that must evaluate to a rational number.|
|FloatExpr||Arbitrary expression that must evaluate to a floating point.|
For systems using bounded integer arithmetic (default is unbounded, see section 184.108.40.206 for details), integer operations that would cause overflow automatically convert to floating point arithmetic.
SWI-Prolog provides many extensions to the set of floating point functions defined by the ISO standard. The current policy is to provide such functions on‘as-needed' basis if the function is widely supported elsewhere and notably if it is part of the C99 mathematical library. In addition, we try to maintain compatibility with other Prolog implementations.
is followed by a number, the parser discards the
trueor one of the arguments is a float, both arguments are converted to float and the return value is a float. Otherwise the result type depends on the Prolog flag prefer_rationals. If
true, the result is always a rational number. If
falsethe result is rational if at least one of the arguments is rational. Otherwise (both arguments are integer) the result is integer if the division is exact and float otherwise. See also section 220.127.116.11, ///2, and rdiv/2.
The current default for the Prolog flag prefer_rationals
false. Future version may switch this to
providing precise results when possible. The pitfall is that in general
rational arithmetic is slower and can become very slow and produce huge
numbers that require a lot of (global stack) memory. Code for which the
exact results provided by rational numbers is not needed should force
float results by making one of the operants float, for example by
10.0 rather than
10 or by using float/1.
Note that when one of the arguments is forced to a float the division is
a float operation while if the result is forced to the float the
division is done using rational arithmetic.
divis floored division.
towards_zero.124Future versions might guarantee rounding towards zero.
Y =\= 0.
Q is div(X, Y), M is mod(X, Y), X =:= Y*Q+M.
nan. See also minr/2 amd maxr/2.
This function relates to the Prolog numerical comparison predicates >/2, =:=/2, etc. The Prolog numerical comparison converts the rational in a mixed rational/float comparison to a float, possibly rounding the value. This function converts the float to a rational, comparing the exact values.
?- epsilon =:= nexttoward(1,2)-1. true.
Note that floating point arithmetic is provided by the C compiler and C runtime library. Unfortunately most C libraries do not correctly implement the rounding modes for notably the trigonometry and exponential functions. There exist correct libraries such as crlibm, but these libraries are large, most of them are poorly maintained or have an incompatible license. C runtime libraries do a better job using the default to nearest rounding mode. SWI-Prolog now assumes this mode is correct and translates upward rounding to be the nexttoward/2 infinity and downward rounding nexttoward/2 -infinity. If the “to nearest'' rounding mode is correct, this ensures that the true value is between the downward and upward rounded values, although the generated interval is larger than needed. Unfortunately this is not the case as shown in Accuracy of Mathematical Functions in Single, Double, Extended Double and Quadruple Precision by Vincenzo Innocente and Paul Zimmermann.
nanand one of the arguments evaluates to NaN, the result is NaN.
The function maxr/2 is similar, but uses exact (rational) comparision if Expr1 and Expr2 have a different type, propagate the rational (integer) rather and the float if the two compare equal and propagate the non-NaN value in case one is NaN.
max(1,1.0)evaluates to 1.0 while
maxr(1,1.0)evaluates to 1. This also means that 0 is preferred over 0.0 or -0.0; -0.0 is still considered smaller than 0.0.
maxr/2 also treats
NaN's as missing values so
maxr(1,nan) evaluates to 1.
. Using SWI-Prolog v7 and later the actual functor is
. This implies
"a"evaluates to the character code of the letter‘a' (97) using the traditional mapping of double quoted string to a list of character codes. Char is either a valid code point (non-negative integer up to the Prolog flag max_char_code) or a one-character atom. Arithmetic evaluation also translates a string object (see section 5.2) of one character length into the character code for that character. This implies that expression
"a"works if the Prolog flag double_quotes is set to one of
Getting access to character codes this way originates from DEC10
Prolog. ISO has the
0'a syntax and the predicate char_code/2.
Future versions may drop support for
X is "a".
/dev/random.126On Windows the state is initialised from CryptGenRandom(). Otherwise it is set from the system clock. If unbounded arithmetic is not supported, random numbers are shared between threads and the seed is initialised from the clock when SWI-Prolog was started. The predicate set_random/1 can be used to control the random number generator.
Warning! Although properly seeded (if supported on the OS),
the Mersenne Twister algorithm does not produce
cryptographically secure random numbers. To generate cryptographically
secure random numbers, use crypto_n_random_bytes/2
library(crypto) provided by the
floor(Expr+1/2), i.e., rounding down. This is an unconventional choice under which the relation
round(Expr) == -round(-Expr)does not hold. SWI-Prolog rounds outward, e.g.,
round(1.5) =:= 2and
round(-1.5) =:= -2.
rational(0.1). The function rationalize/1 remedies this. See section 18.104.22.168 for more information on rational number support.
?- A is rational(0.25). A is 1r4 ?- A is rational(0.1). A = 3602879701896397r36028797018963968
For every normal float X the relation
This function raises an
evaluation_error(undefined) if Expr
is NaN and
evaluation_error(rational_overflow) if Expr
?- A is rationalize(0.25). A = 1r4 ?- A is rationalize(0.1). A = 1r10
For every normal float X the relation
This function raises the same exceptions as rational/1 on non-normal floating point numbers.
X =:= numerator(X)/denominator(X).
X =:= numerator(X)/denominator(X).
floor(Expr). For Expr < 0 this is the same as
ceil(Expr). That is, truncate/1 rounds towards zero.
Note that the ISO Prolog standard demands
to raise an evaluation error, whereas the C99 and POSIX standards demand
this to evaluate to 0.0. SWI-Prolog follows C99 and POSIX.
resourceerror if the result does not fit in memory.
The ISO standard demands a float result for all inputs and introduces ^/2 for integer exponentiation. The function float/1 can be used on one or both arguments to force a floating point result. Note that casting the input result in a floating point computation, while casting the output performs integer exponentiation followed by a conversion to float.
In SWI-Prolog, ^/2 is
equivalent to **/2. The
ISO version is similar, except that it produces a evaluation error if
Expr1 and Expr2 are integers and the result is not
an integer. The table below illustrates the behaviour of the
exponentiation functions in ISO and SWI. Note that if the exponent is
negative the behavior of Int
depends on the flag
producing either a rational number or a floating point number.
|Int||Int||**/2||Int or Rational||Float|
|Int||Int||^/2||Int or Rational||Int or error|
The functions below are not covered by the standard. The
msb/1 function also
appears in hProlog and SICStus Prolog. The getbit/2
function also appears in ECLiPSe, which also provides
clrbit(Vector,Index). The others are SWI-Prolog
extensions that improve handling of ---unbounded--- integers as
(IntExpr >> N) /\ 1 =:= 1. This is the (zero-origin) index of the most significant 1 bit in the value of IntExpr, which must evaluate to a positive integer. Errors for 0, negative integers, and non-integers.
(IntExpr >> N) /\ 1 =:= 1. This is the (zero-origin) index of the least significant 1 bit in the value of IntExpr, which must evaluate to a positive integer. Errors for 0, negative integers, and non-integers.
(IntExprV >> IntExprI)/\1, but more efficient because materialization of the shifted value is avoided. Future versions will optimise
(IntExprV >> IntExprI)/\1to a call to getbit/2, providing both portability and performance.133This issue was fiercely debated at the ISO standard mailinglist. The name getbit was selected for compatibility with ECLiPSe, the only system providing this support. Richard O'Keefe disliked the name and argued that efficient handling of the above implementation is the best choice for this functionality.