Quantum Integers β
QInt is a higher-level quantum type that represents an integer encoded across multiple qubits. Instead of managing individual qubits, you work with arithmetic operations directly.
Creating QInt Values β
The simplest way to create a quantum integer is with a type annotation:
x: QInt = 42 -- minimum bits needed (6 qubits)
y: QInt[8] = 13 -- fixed 8-qubit width
z: QInt = some_int_var -- dynamic (width determined at runtime)QInt = 42 allocates just enough qubits to represent 42 (6 qubits). QInt[8] fixes the register width to 8 qubits, which is useful when you need a specific bit width for arithmetic or interoperation with other registers.
Compound Assignment β
Compound assignment operators modify the target register in-place while preserving the operand. This is the accumulator style:
| Operator | Meaning |
|---|---|
x += y | Quantum addition (y preserved) |
x += 5 | Add classical constant |
x -= 3 | Subtract classical constant |
x *= 7 | Multiply by classical constant |
x ^= y | Quantum XOR (y preserved) |
The key property: the right-hand operand is not consumed. After x += y, the variable y is still live and must eventually be measured or discarded.
Binary Operations β
Binary operators create a new register and consume both operands:
Supported binary operators: +, - (with QInt or Int operands).
Linearity β
QInt is a linear type, following the same rules as Qubitβeach value must be used exactly once. The two arithmetic styles have different linearity behavior:
- Compound assignment (
x += y) β modifiesxin-place, preservesy - Binary operation (
z = x + y) β creates newz, consumes bothxandy
Use compound assignment when you need to keep operands alive. Use binary operations when you're done with both inputs.
-- Compound: y survives
x += y
-- ... can still use y ...
discard(y)
-- Binary: both consumed
z = x + y
-- x and y are gone; only z remainsMeasuring and Discarding β
Like qubits, quantum integers must be consumed. Use measure to collapse to a classical Int, or discard to throw away the value:
result: Int = measure(x) -- collapses to classical integer
discard(x) -- discards without measuringConversion Functions β
Convert between QInt and raw qubit lists when you need low-level access:
| Function | Signature | Description |
|---|---|---|
qint_from_qubits | List[Qubit] -> QInt | Wrap a qubit list as a QInt |
qubits_from_qint | QInt -> List[Qubit] | Unwrap a QInt to a qubit list |
-- Drop down to individual qubits
qubits: List[Qubit] = qubits_from_qint(x)
-- Wrap qubits back into a QInt
x: QInt = qint_from_qubits(qubits)These are useful when you need to apply individual gates to specific qubits within an integer register.
Pattern: Reading N qubits as an Int β
A common end-of-circuit pattern is measuring several qubits and reconstructing an integer. Don't write this:
-- Manual bit-to-int β also doesn't compile: measure(Qubit) returns
-- Measurement, not Int. You'd need read_measurement on each, plus
-- you've hardcoded the endianness.
measure(q0) + measure(q1) * 2 + measure(q2) * 4Promote to a QInt register and measure it directly:
-- Wraps the qubits as a register; consumes them
k: QInt = qint_from_qubits([q0, q1, q2])
result: Int = measure(k) -- bit-to-int reconstruction is built inThis works even when the qubits started life as individual Qubit values β qint_from_qubits is the bridge from bit-level work back into register-level measurement.
For bit-level register access (not just arithmetic), see QubitArray[N].
Next Steps β
- Gates β Quantum gate operations on qubits
- Linear Types β How linearity works in Kettle
- Measurement β Extracting classical results from quantum states