Arithmetic operations

The basic arithmetic operations are built into the language; additional operations are provided by the required floating-point interfaces.

To test or set the implementation's behavior for overflow, underflow, rounding, and division by zero, see the required interface FloatMode. Modula-3 arithmetic was designed to support the IEEE floating-point standard, but not to require it.

To perform arithmetic operations modulo the word size, programs should use the routines in the required interface Word.

Implementations must not rearrange the computation of expressions in a way that could affect the result. For example, (x+y)+z generally cannot be computed as x+(y+z), since addition is not associative either for bounded integers or for floating-point values.

```    prefix    +  (x: Integer)    : Integer
+  (x: Float)      : Float

infix    +  (x,y: Integer)  : Integer
(x,y: Float)    : Float
(x,y: Set)      : Set
```
As a prefix operator, +x returns x. As an infix operator on numeric arguments, + denotes addition. On sets, + denotes set union. That is, e IN (x + y) if and only if (e IN x) OR (e IN y). The types of x and y must be the same, and the result is the same type as both. In unsafe modules, + is extended to ADDRESS.

```    prefix    -  (x: Integer)    : Integer
(x: Float)      : Float

infix    -  (x,y: Integer)  : Integer
(x,y: Float)    : Float
(x,y: Set)      : Set
```
As a prefix operator, -x is the negative of x. As an infix operator on numeric arguments, - denotes subtraction. On sets, - denotes set difference. That is, e IN (x - y) if and only if (e IN x) AND NOT (e IN y). The types of x and y must be the same, and the result is the same type as both. In unsafe modules, - is extended to ADDRESS.

```    infix     *  (x,y: Integer)  : Integer
(x,y: Float)    : Float
(x,y: Set)      : Set
```
On numeric arguments, * denotes multiplication. On sets, * denotes intersection. That is, e IN (x * y) if and only if (e IN x) AND (e IN y). The types of x and y must be the same, and the result is the same type as both.

```    infix     /  (x,y: Float)    : Float
(x,y: Set)      : Set
```
On reals, / denotes division. On sets, / denotes symmetric difference. That is, e IN (x / y) if and only if (e IN x) # (e IN y). The types of x and y must be the same, and the result is the same type as both.

```    infix    DIV (x,y: Integer) : Integer
infix    MOD (x,y: Integer) : Integer
MOD (x, y: Float)  : Float
```
The value x DIV y is the floor of the quotient of x and y; that is, the maximum integer not exceeding the real number z such that z * y = x. For integers x and y, the value of x MOD y is defined to be x - y * (x DIV y).

This means that for positive y, the value of x MOD y lies in the interval [0 .. y-1], regardless of the sign of x. For negative y, the value of x MOD y lies in the interval [y+1 .. 0], regardless of the sign of x.

If x and y are floats, the value of x MOD y is x - y * FLOOR(x / y). This may be computed as a Modula-3 expression, or by a method that avoids overflow if x is much greater than y. The types of x and y must be the same, and the result is the same type as both.

```             ABS (x: Integer) : Integer
(x: Float)   : Float
```
ABS(x) is the absolute value of x. The type of ABS(x) is the same as the type of x.

```           FLOAT (x: Integer; T: Type := REAL): T
(x: Float;   T: Type := REAL): T
```
FLOAT(x, T) is a floating-point value of type T that is equal to or very near x. The type T must be a floating-point type; it defaults to REAL. The exact semantics depend on the thread's current rounding mode, as defined in the required interface FloatMode.

```           FLOOR   (x: Float; T: Type := INTEGER): T

CEILING (x: Float; T: Type := INTEGER): T
```
FLOOR(x) is the greatest integer not exceeding x. CEILING(x) is the least integer not less than x. The type T must be an integer type; it defaults to INTEGER.

```           ROUND (r: Float; T: Type := INTEGER): T

TRUNC (r: Float; T: Type := INTEGER): T
```
ROUND(r) is the nearest integer to r; ties are broken according to the constant RoundDefault in the required interface FloatMode. TRUNC(r) rounds r toward zero; it equals FLOOR(r) for positive r and CEILING(r) for negative r. The type T must be an integer type; it defaults to INTEGER.

```       MAX, MIN (x,y: Ordinal) : Ordinal
(x,y: Float)   : Float
```
MAX returns the greater of the two values x and y; MIN returns the lesser. If x and y are ordinals, they must have the same base type, which is the type of the result. If x and y are floats, they must have the same type, and the result is the same type as both.