Operators in Mojo
Explore arithmetic, comparison, logical, and bitwise operators in Mojo with practical Docker-ready examples
Operators are the building blocks of every expression you write. In Mojo, operators look and behave almost exactly like their Python counterparts—+, -, *, /, //, %, **, ==, and, or, and not all work as you would expect. The difference is what happens under the hood: when your variables have concrete types, Mojo’s MLIR-based compiler lowers these operators to native machine instructions, with no interpreter overhead.
Because Mojo is a Python superset with optional static typing, you can use operators in a relaxed Python style inside def functions, or in a strict, type-checked style inside fn functions. The compiler picks the right instructions based on the operand types: integer addition becomes a hardware add, floating-point division becomes an FPU instruction, and so on.
This tutorial walks through the operator categories you’ll use most: arithmetic, comparison, logical, bitwise, and compound assignment. Each example is a small, runnable Mojo program you can build and execute through the Docker image.
Arithmetic Operators
Mojo supports the same set of arithmetic operators as Python, including floor division (//), modulo (%), and exponentiation (**).
Create a file named arithmetic.mojo:
| |
True division (/) produces a floating-point result, so the integer operands are converted explicitly to Float64. Floor division (//) keeps the result as an integer, and ** raises the left operand to the power of the right.
Comparison and Logical Operators
Comparison operators (==, !=, <, <=, >, >=) return Bool values. Mojo’s logical operators—and, or, not—short-circuit just like in Python.
Create a file named comparison.mojo:
| |
Mojo also supports Python-style chained comparisons. 0 < x < 100 is equivalent to 0 < x and x < 100 and evaluates x exactly once.
Bitwise Operators
Bitwise operators work on the binary representation of integers. They are useful for flag manipulation, low-level encoding, and—because Mojo compiles to native code—for squeezing maximum performance out of integer-heavy loops.
Create a file named bitwise.mojo:
| |
~a produces -(a + 1) in two’s complement, which is why ~12 is -13. Shifts by n positions are equivalent to multiplying or dividing by 2**n, but they map to single hardware instructions.
Compound Assignment and Precedence
Compound assignment operators (+=, -=, *=, /=, //=, %=, **=, plus the bitwise variants) update a variable in place. They require the variable to be declared with var so that it is mutable.
Create a file named assignment.mojo:
| |
Mojo’s precedence rules follow Python’s: exponentiation binds tightest, followed by unary -, then *//////%, then +/-, then comparison, then not, and, or. When in doubt, parentheses make intent explicit and cost nothing at runtime.
Running with Docker
| |
Expected Output
Running arithmetic.mojo:
a + b = 22
a - b = 12
a * b = 85
a / b = 3.4
a // b = 3
a % b = 2
a ** b = 1419857
-a = -17
Running comparison.mojo:
x == y: False
x != y: True
x < y: True
x <= 10: True
x > y: False
x >= 10: True
0 < x < 100: True
x == 0 or y == 20: True
not in_range: False
Running bitwise.mojo:
a & b = 8
a | b = 14
a ^ b = 6
~a = -13
a << 2 = 48
a >> 1 = 6
Running assignment.mojo:
total = 24
2 + 3 * 4 ** 2 = 50
(2 + 3) * 4 ** 2 = 80
safe check: True
Key Concepts
- Python-familiar syntax —
+,-,*,/,//,%,**and the comparison/logical operators behave the same as in Python. - True vs floor division —
/always yields a floating-point result;//performs floor division and preserves integer types. - Compile-time lowering — When operand types are known, Mojo’s compiler emits direct machine instructions, so operators carry no interpreter overhead.
- Chained comparisons — Expressions like
0 < x < 100work natively and evaluate the middle term only once. - Short-circuit logic —
andandorstop evaluating as soon as the result is determined, which is useful for guarding against division by zero or null-like values. - Bitwise operators on
Int—&,|,^,~,<<, and>>map to hardware instructions, making them ideal for flags, masks, and low-level encoding. - Mutability is explicit — Compound assignment requires
vardeclarations; function arguments are immutable by default unless declaredinout. - Standard precedence — Mojo follows Python’s precedence rules. When mixing arithmetic, comparison, and logical operators, parentheses make intent obvious at no runtime cost.
Running Today
All examples can be run using Docker:
docker pull codearchaeology/mojo:latest
Comments
Loading comments...
Leave a Comment