2.1 Integer-valued arithmetic operators
Stan’s arithmetic is based on standard double-precision C++ integer
and floating-point arithmetic. If the arguments to an arithmetic
operator are both integers, as in 2 + 2
, integer arithmetic is used.
If one argument is an integer and the other a floating-point value, as
in 2.0 + 2
and 2 + 2.0
, then the integer is promoted to a floating
point value and floating-point arithmetic is used.
Integer arithmetic behaves slightly differently than floating point arithmetic. The first difference is how overflow is treated. If the sum or product of two integers overflows the maximum integer representable, the result is an undesirable wraparound behavior at the bit level. If the integers were first promoted to real numbers, they would not overflow a floating-point representation. There are no extra checks in Stan to flag overflows, so it is up to the user to make sure it does not occur.
Secondly, because the set of integers is not closed under division and
there is no special infinite value for integers, integer division
implicitly rounds the result. If both arguments are positive, the
result is rounded down. For example, 1 / 2
evaluates to 0 and 5 / 3
evaluates to 1.
If one of the integer arguments to division is negative, the latest
C++ specification ( C++11), requires rounding toward zero. This would
have 1 / 2
and -1 / 2
evaluate to 0, -7 / 2
evaluate to -3, and
7 / 2
evaluate to 3. Before the C++11 specification, the behavior
was platform dependent, allowing rounding up or down. All compilers
recent enough to be able to deal with Stan’s templating should follow
the C++11 specification, but it may be worth testing if you are not
sure and plan to use integer division with negative values.
Unlike floating point division, where 1.0 / 0.0
produces the special
positive infinite value, integer division by zero, as in 1 / 0
, has
undefined behavior in the C++ standard. For example, the clang++
compiler on Mac OS X returns 3764, whereas the g++ compiler throws an
exception and aborts the program with a warning. As with overflow, it
is up to the user to make sure integer divide-by-zero does not occur.
2.1.1 Binary infix operators
Operators are described using the C++ syntax. For instance, the
binary operator of addition, written X + Y
, would have the Stan
signature int operator+(int,int)
indicating it takes two real
arguments and returns a real value. As noted previously, the value of
integer division is platform-dependent when rounding is platform
dependent before C++11; the descriptions below provide the C++11
definition.
int
operator+
(int x, int y)
The sum of the addends x and y \[ \text{operator+}(x,y) = (x + y) \]
int
operator-
(int x, int y)
The difference between the minuend x and subtrahend y \[
\text{operator-}(x,y) = (x - y) \]
int
operator*
(int x, int y)
The product of the factors x and y \[ \text{operator*}(x,y) = (x
\times y) \]
int
operator/
(int x, int y)
The integer quotient of the dividend x and divisor y \[
\text{operator/}(x,y) = \begin{cases} \lfloor x / y \rfloor & \text{if
} x / y \geq 0 \\ - \lfloor \text{floor}(-x / y) \rfloor & \text{if }
x / y < 0. \end{cases} \]
int
operator%
(int x, int y)
x modulo y, which is the positive remainder after dividing x by y. If
both x and y are non-negative, so is the result; otherwise, the sign
of the result is platform dependent. \[ \mathrm{operator\%}(x, y) \ =
\ x \ \text{mod} \ y \ = \ x - y * \lfloor x / y \rfloor \]
2.1.2 Unary prefix operators
int
operator-
(int x)
The negation of the subtrahend x [ (x) = -x
int
operator+
(int x)
This is a no-op. \[ \text{operator+}(x) = x \]