Skip to content

Overview of Arithmetic Operators

Quxlang uses +, -, *, /, and % for arithmetic. Concrete integer types and BYTE support all five; floating-point types do not provide %.

VAR left I32 := 17;
VAR right I32 := 5;

ASSERT(left + right == 22);
ASSERT(left - right == 12);
ASSERT(left * right == 85);
ASSERT(left / right == 3);
ASSERT(left % right == 2);

Explicit numeric types

Built-in runtime arithmetic expects compatible concrete operand types. Convert different widths or signedness explicitly:

VAR narrow I16 := 10;
VAR wide I32 := 20;
VAR total I32 := (narrow AS I32) + wide;

Untyped literals remain compile-time literals until a target type is selected:

VAR large U128 := (100000000000000000000 + 7) AS U128;

Pointer arithmetic

Array pointers advance in elements and can be subtracted to obtain a distance:

VAR values [4]I32 :[10, 20, 30, 40];
VAR begin MUT=>>I32 := values[& 0];
VAR third MUT=>>I32 := begin + (2 AS SZ);
ASSERT(third-> == 30);

Instance pointers do not support element arithmetic. ADDRESS arithmetic is byte-oriented.

Types can define their own arithmetic with .OPERATOR+, .OPERATOR-, and the other operator members.

Checked arithmetic

A ? suffix throws ARITHMETIC_OVERFLOW if an integer result is out of range. The assignment spelling puts = before ?:

VAR count U8 := 254;
count +=? 1;
TEST_ASSERT(count == 255);

+?, -?, *?, and /? check their results. Their ! counterparts promise that the result is in range; CHECK_OVERFLOW can check that promise and panic on a violation. Ordinary integer addition, subtraction, and multiplication wrap to the declared width. See the range contracts.

Reference

See the Arithmetic Operators Reference for primitive signatures, literal behavior, pointer and address arithmetic, reflected operators, and Quxlang's non-C precedence rules.