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 \]