Mojo Operators
Operators are symbols that perform computations or comparisons on values. Mojo supports arithmetic, comparison, logical, bitwise, and assignment operators. Knowing how they work and how they interact lets you write expressions that produce exactly the result you need.
Arithmetic Operators
Arithmetic operators perform basic math on numeric values.
Operator | Operation | Example | Result ---------|-------------------|----------|------- + | Addition | 8 + 3 | 11 - | Subtraction | 8 - 3 | 5 * | Multiplication | 8 * 3 | 24 / | Division | 8 / 3 | 2.666... // | Floor division | 8 // 3 | 2 % | Remainder (mod) | 8 % 3 | 2 ** | Exponentiation | 2 ** 10 | 1024
fn main():
var a = 15
var b = 4
print(a + b) # 19
print(a - b) # 11
print(a * b) # 60
print(a / b) # 3.75
print(a // b) # 3 (drops the decimal)
print(a % b) # 3 (15 = 4×3 + 3)
print(2 ** 8) # 256
Floor Division vs Regular Division
Regular: 15 / 4 → 3.75 Floor: 15 // 4 → 3 (like measuring 15 apples into bags of 4 — you fill 3 bags completely) Remainder: 15 % 4 → 3 (3 apples left over after filling 3 bags)
Comparison Operators
Comparison operators evaluate two values and return a Bool: either True or False.
Operator | Meaning | Example | Result ---------|-----------------------|-----------|------- == | Equal to | 5 == 5 | True != | Not equal to | 5 != 3 | True > | Greater than | 7 > 4 | True < | Less than | 2 < 9 | True >= | Greater or equal | 5 >= 5 | True <= | Less or equal | 3 <= 7 | True
fn main():
var x = 10
var y = 20
print(x == y) # False
print(x != y) # True
print(x < y) # True
print(x >= 10) # True
Logical Operators
Logical operators combine boolean values into a single boolean result.
Operator | Meaning | Example ---------|--------------------------------|------------------- and | Both sides must be True | True and False → False or | At least one side must be True | True or False → True not | Reverses the boolean value | not True → False
Truth Table for and / or
A | B | A and B | A or B --------|-------|---------|-------- True | True | True | True True | False | False | True False | True | False | True False | False | False | False
fn main():
var has_ticket = True
var is_adult = False
print(has_ticket and is_adult) # False
print(has_ticket or is_adult) # True
print(not has_ticket) # False
Assignment Operators
The simple assignment operator = places a value into a variable. Compound assignment operators combine an arithmetic operation with assignment to shorten repetitive code.
Operator | Equivalent to | Example | After ---------|----------------|---------------|------- = | — | x = 5 | x = 5 += | x = x + n | x += 3 | x = 8 -= | x = x - n | x -= 2 | x = 6 *= | x = x * n | x *= 4 | x = 24 /= | x = x / n | x /= 2 | x = 12.0 //= | x = x // n | x //= 5 | x = 2 %= | x = x % n | x %= 3 | x = 2 **= | x = x ** n | x **= 3 | x = 8
fn main():
var score = 100
score += 50 # score is now 150
score -= 20 # score is now 130
score *= 2 # score is now 260
print(score) # 260
Bitwise Operators
Bitwise operators work directly on the binary representation of integers. They are essential for low-level hardware programming, flags, and high-performance numerical code.
Operator | Meaning | Example (4-bit) ---------|-----------------|---------------------------------- & | AND | 1010 & 1100 = 1000 | | OR | 1010 | 1100 = 1110 ^ | XOR | 1010 ^ 1100 = 0110 ~ | NOT (flip bits) | ~1010 = 0101 << | Left shift | 0001 << 2 = 0100 (multiply by 4) >> | Right shift | 1000 >> 2 = 0010 (divide by 4)
fn main():
var flags: UInt8 = 0b00001010 # bits 1 and 3 are set
var mask: UInt8 = 0b00001100 # mask for bits 2 and 3
print(flags & mask) # 0b00001000 = 8 (only bit 3 is in both)
print(flags | mask) # 0b00001110 = 14 (any bit set in either)
print(flags ^ mask) # 0b00000110 = 6 (bits set in one but not both)
print(1 << 4) # 16 (shift 1 left by 4 positions)
Shift as Fast Multiply/Divide
x << 1 = x × 2 (shift left by 1 bit) x << 3 = x × 8 (shift left by 3 bits) x >> 1 = x ÷ 2 (shift right by 1 bit) x >> 3 = x ÷ 8 (shift right by 3 bits) Example: 5 << 2 = 20 because 5 × 4 = 20 16 >> 2 = 4 because 16 ÷ 4 = 4
Operator Precedence
When an expression contains multiple operators, Mojo evaluates them in a fixed order called precedence. Higher precedence operators evaluate first, just like the order of operations in mathematics.
Precedence (high to low): 1. ** (exponentiation) 2. ~, + (unary), - (unary) 3. *, /, //, % 4. +, - (binary) 5. <<, >> 6. & 7. ^ 8. | 9. ==, !=, >, <, >=, <= 10. not 11. and 12. or
fn main():
print(2 + 3 * 4) # 14, not 20 — * runs before +
print((2 + 3) * 4) # 20 — parentheses override precedence
print(2 ** 3 ** 2) # 512 — ** is right-associative: 2^(3^2) = 2^9
Use parentheses whenever you are unsure about precedence. They make intent clear and prevent bugs.
Key Takeaways
Mojo arithmetic operators mirror standard math. Comparison operators return Bool values. Logical operators combine booleans. Compound assignment operators like += shorten common patterns. Bitwise operators manipulate individual bits and enable powerful low-level optimizations. Parentheses override operator precedence and make complex expressions easier to understand.
