Arithmetic can be divided into some special purpose integer predicates and a series of general predicates for integer, floating point and rational arithmetic as appropriate. The general arithmetic predicates all handle expressions. An expression is either a simple number or a function. The arguments of a function are expressions. The functions are described in section 4.27.2.6.
The predicates in this section provide more logical operations between integers. They are not covered by the ISO standard, although they are‘part of the community' and found as either library or built-in in many other Prolog systems.
inf or
infinite121We prefer infinite, 
but some other Prolog systems already use inf for infinity; 
we accept both for the time being.
between/3 
is true iff Value >=Low, a feature 
that is particularly interesting for generating integers from a certain 
value.not_less_than_zero 
if called with a negative integer. E.g. succ(X, 0) fails 
silently and succ(X, -1) raises a domain error.122The 
behaviour to deal with natural numbers only was defined by Richard 
O'Keefe to support the common count-down-to-zero in a natural way. Up to 
5.1.8, succ/2 
also accepted negative integers.
divmod(Dividend, Divisor, Quotient, Remainder) :-
        Quotient  is Dividend div Divisor,
        Remainder is Dividend mod Divisor.
Note that this predicate is only available if SWI-Prolog is compiled with unbounded integer support. This is the case for all packaged versions.
%   I < 0,
%   N mod 2 =\= 0,
    nth_integer_root_and_remainder(
        N, I, Root, Remainder),
    IPos is -I,
    nth_integer_root_and_remainder(
        N, IPos, RootPos, RemainderPos),
    Root =:= -RootPos,
    Remainder =:= -RemainderPos.
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.
?- 1 is sin(pi/2).  | Fails! sin(pi/2) evaluates to the float 1.0, which does not unify with the integer 1. | 
?- 1 =:= sin(pi/2).  | 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.
true (default), division (//2) 
and integer power (^/2) 
also produce a rational number.
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, division and exponentiation (^/2). 
Support for rational numbers depends on the Prolog flag
prefer_rationals. 
If this is true (default), the number division function (//2) 
and exponentiation function (^/2) 
generate a rational number on integer and rational arguments and read/1 
and friends read [-+][0-9_ ]+/[0-9_ ]+ into a rational 
number. See also section 
2.16.1.6. Here are some examples.
| A is 2/6 | A = 1/3 | 
| A is 4/3 + 1 | A = 7/3 | 
| A is 4/3 + 1.5 | A = 2.83333 | 
| A is 4/3 + rationalize(1.5) | A = 17/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/3 + rational(1.5),
   format('~50f~n', [A]).
2.83333333333333333333333333333333333333333333333333
A = 17/6
SWI-Prolog uses rational number arithmetic if the Prolog flag
prefer_rationals 
is true and if this is defined for a function on the given 
operants. This results in perfectly precise answers. Unfortunately 
rational numbers can get really large and, if a precise answer is not 
needed, a big waste of memory and CPU time. In such cases one should use 
floating point arithmetic. The Prolog flag
max_rational_size 
provides a tripwire to detect cases where rational numbers get 
big and react on these events.
Floating point arithmetic can be forced by forcing a float into an argument at any point, i.e., the result of a function with at least one float is always float except for the float-to-integer rounding and truncating functions such as round/1, rational/1 or float_integer_part/1.
Float arithmetic is typically forced by using a floating point constant as initial value or operant. Alternatively, the float/1 function forces conversion of the argument.
The Prolog ISO standard defines that floating point arithmetic 
returns a valid floating point number or raises an exception. IEEE 
floating point arithmetic defines two modes: raising exceptions and 
propagating the special float values NaN, Inf, -Inf 
and
-0.0. SWI-Prolog implements a part of the
ECLiPSe 
proposal to support non-exception based processing of floating point 
numbers. There are four flags that define handling the four exceptional 
events in floating point arithmetic, providing the choice between
error and returning the IEEE special value. Note that these 
flags only apply for floating point arithmetic. For example 
rational division by zero always raises an exception.
| Flag | Default | Alternative | 
| float_overflow | error | infinity | 
| float_zero_div | error | infinity | 
| float_undefined | error | nan | 
| float_underflow | ignore | error | 
The Prolog flag float_rounding 
and the function
roundtoward/2 
control the rounding mode for floating point arithmetic. The default 
rounding is to_nearest and the following alternatives are 
provided: to_positive, to_negative and
to_zero.
nan. Although IEEE 754 allows NaN to carry a payload 
and have a sign, SWI-Prolog has only a single NaN values. Note that two 
NaN
terms compare equal in the standard order of terms (==/2, 
etc.), they compare non-equal for arithmetic (=:=/2, 
etc.).infinity.error.Float =:= Mantissa × Base^Exponent
NaN, Inf, 
and -Inf are not bounded numbers.
If Low and/or High are variables they will be unified with tightest values that still meet the bounds criteria. The generated bounds will be integers if Num is an integer; otherwise they will be floats (also see nexttoward/2 for generating float bounds). Some examples:
?- bounded_number(0,10,1). true. ?- bounded_number(0.0,1.0,1r2). true. ?- bounded_number(L,H,1.0). L = 0.9999999999999999, H = 1.0000000000000002. ?- bounded_number(L,H,-1). L = -2, H = 0. ?- bounded_number(0,1r2,1). false. ?- bounded_number(L,H,1.0Inf). false.
SWI-Prolog represents floats using the C double type. On 
virtually all modern hardware this implies it uses 64-bit IEEE 754 
floating point numbers. See also section 
4.27.2.4. All floating point arithmetic is performed using C. 
Different C compilers, different C math libraries and different hardware 
floating point support may yield different results for the same 
expression on different instances of SWI-Prolog.
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 4.27.2.1 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 +. 
I.e. ?- integer(+1) succeeds.true 
or 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 false 
the 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 
4.27.2.2, ///2, and rdiv/2.
The current default for the Prolog flag prefer_rationals 
is
false. Future version may switch this to true, 
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 
dividing 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.
div 
is
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.
to_nearest, to_positive, to_negative 
or
to_zero.
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.
nan and 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.
./2. Using 
SWI-Prolog v7 and later the actual functor is [|]/2. 
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
codes, chars or string.
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 
from library library(crypto) provided by the ssl 
package.
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) =:= 2 and
round(-1.5) =:= -2.rational(0.1). The function rationalize/1 
remedies this. See section 
4.27.2.2 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
X  rational(X) holds.
=:=
This function raises an evaluation_error(undefined) if Expr 
is NaN and evaluation_error(rational_overflow) if Expr 
is Inf.
?- A is rationalize(0.25). A = 1r4 ?- A is rationalize(0.1). A = 1r10
For every normal float X the relation
X  rationalize(X) 
holds.
=:=
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 atan2(0.0,0.0) 
to raise an evaluation error, whereas the C99 and POSIX standards demand 
this to evaluate to 0.0. SWI-Prolog follows C99 and POSIX.
resource error 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 
both
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 IntInt 
depends on the flag
prefer_rationals, 
producing either a rational number or a floating point number.
^
| Expr1 | Expr2 | Function | SWI | ISO | 
| Int | Int | **/2 | Int or Rational | Float | 
| Int | Float | **/2 | Float | Float | 
| Rational | Int | **/2 | Rational | - | 
| Float | Int | **/2 | Float | Float | 
| Float | Float | **/2 | Float | Float | 
| Int | Int | ^/2 | Int or Rational | Int or error | 
| Int | Float | ^/2 | Float | Float | 
| Rational | Int | ^/2 | Rational | - | 
| Float | Int | ^/2 | Float | Float | 
| Float | Float | ^/2 | Float | Float | 
Bitvector functions
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 setbit(Vector,Index) 
and clrbit(Vector,Index). The others are SWI-Prolog 
extensions that improve handling of ---unbounded--- integers as 
bit-vectors.
(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)/\1 
to 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.