|Did you know ...||Search Documentation:|
|General purpose arithmetic|
The general arithmetic predicates are optionally compiled (see set_prolog_flag/2 and the -O command line option). Compiled arithmetic reduces global stack requirements and improves performance. Unfortunately compiled arithmetic cannot be traced, which is why it is optional.
|Fails! sin(pi/2) evaluates to the float 1.0, which does not unify with the integer 1.|
|Succeeds as expected.|
SWI-Prolog defines the following numeric types:
Internally, SWI-Prolog has three integer representations. Small integers (defined by the Prolog flag max_tagged_integer) are encoded directly. Larger integers are represented as 64-bit values on the global stack. Integers that do not fit in 64 bits are represented as serialised GNU MPZ structures on the global stack.
rdiv(N,M). Rational numbers that are returned from is/2 are canonical, which means M is positive and N and M have no common divisors. Rational numbers are introduced in the computation using the rational/1, rationalize/1 or the rdiv/2 (rational division) function. Using the same functor for rational division and for representing rational numbers allows for passing rational numbers between computations as well as for using format/3 for printing.
In the long term, it is likely that rational numbers will become
atomic as well as a subtype of number. User code that
creates or inspects the
rdiv(M,N) terms will not be
portable to future versions. Rationals are created using one of the
functions mentioned above and inspected using rational/3.
double. On most of today's platforms these are 64-bit IEEE floating point numbers.
Arithmetic functions that require integer arguments accept, in addition to integers, rational numbers with (canonical) denominator `1'. If the required argument is a float the argument is converted to float. Note that conversion of integers to floating point numbers may raise an overflow exception. In all other cases, arguments are converted to the same type using the order below.
integer -> rational number -> floating point number
The use of rational numbers with unbounded integers allows for exact integer or fixed point arithmetic under addition, subtraction, multiplication and division. To exploit rational arithmetic rdiv/2 should be used instead of `/' and floating point numbers must be converted to rational using rational/1. Omitting the rational/1 on floats will convert a rational operand to float and continue the arithmetic using floating point numbers. Here are some examples.
|A is 2 rdiv 6||A = 1 rdiv 3|
|A is 4 rdiv 3 + 1||A = 7 rdiv 3|
|A is 4 rdiv 3 + 1.5||A = 2.83333|
|A is 4 rdiv 3 + rational(1.5)||A = 17 rdiv 6|
Note that floats cannot represent all decimal numbers exactly. The function rational/1 creates an exact equivalent of the float, while rationalize/1 creates a rational number that is within the float rounding error from the original float. Please check the documentation of these functions for details and examples.
Rational numbers can be printed as decimal numbers with arbitrary precision using the format/3 floating point conversion:
?- A is 4 rdiv 3 + rational(1.5), format('~50f~n', [A]). 2.83333333333333333333333333333333333333333333333333 A = 17 rdiv 6
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 YAP.
is followed by a number, the parser discards the
true, both arguments are converted to float and the return value is a float. Otherwise (default), if both arguments are integers the operation returns an integer if the division is exact. If at least one of the arguments is rational and the other argument is integer, the operation returns a rational number. In all other cases the return value is a float. See also ///2 and rdiv/2.
divis floored division.
towards_zero.116Future versions might guarantee rounding towards zero.
Y =\= 0.
Q is div(X, Y), M is mod(X, Y), X =:= Y*Q+M.
"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. 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"also works of the Prolog flag double_quotes is set to
string. The recommended way to specify the character code of the letter `a' is
/dev/random.117On 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 220.127.116.11 for more information on rational number support.
?- A is rational(0.25). A is 1 rdiv 4 ?- A is rational(0.1). A = 3602879701896397 rdiv 36028797018963968
?- A is rationalize(0.25). A = 1 rdiv 4 ?- A is rationalize(0.1). A = 1 rdiv 10
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.
|Int||Int||**/2||Int or Float||Float|
|Int||Int||^/2||Int or Float||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.123This 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.