Arithmetic Operators

Binary Arithmetic Operators

Binary arithmetic operators take two operands of the same integer type and produce a result of that type.

OperatorNameDescription
+AdditionSum of operands
-SubtractionDifference of operands
*MultiplicationProduct of operands
/DivisionQuotient (integer division)
%RemainderRemainder after division

Operator Precedence

Multiplicative operators (*, /, %) have higher precedence than additive operators (+, -).

Parentheses can be used to override the default precedence of operators. A parenthesized expression evaluates to the value of its inner expression.

fn main() -> i32 {
    1 + 2 * 3    // = 7 (not 9)
    (1 + 2) * 3  // = 9 (parentheses override)
}

Associativity

All binary arithmetic operators are left-associative.

fn main() -> i32 {
    10 - 3 - 2   // = 5, parsed as (10 - 3) - 2
    24 / 4 / 2   // = 3, parsed as (24 / 4) / 2
}

Unary Negation

The unary negation operator - takes a single signed integer operand and produces its arithmetic negation.

A compiler MUST reject unary negation applied to unsigned integer types.

Unary negation binds tighter than all binary operators.

fn main() -> i32 {
    -42      // negation
    --5      // double negation = 5
    -2 * 3   // = -6, parsed as (-2) * 3
}

When a negated integer literal represents the minimum value of a signed integer type, the compiler evaluates the negation at compile time and produces the minimum value directly. This special case allows expressions like -128: i8 without runtime overflow.

When negation is applied to a non-literal expression holding the minimum value of a signed integer type, the operation overflows and MUST cause a runtime panic.

fn main() -> i32 {
    let x: i8 = -128;    // valid: compile-time constant
    let y: i8 = -x;      // runtime panic: negating -128 overflows
    0
}

Overflow

Arithmetic operations that overflow the range of their type MUST cause a runtime panic.

fn main() -> i32 {
    2147483647 + 1  // Runtime error: integer overflow
}

Division by Zero

Division or remainder by zero MUST cause a runtime panic.

fn main() -> i32 {
    10 / 0  // Runtime error: division by zero
    10 % 0  // Runtime error: division by zero
}