- 
                Notifications
    You must be signed in to change notification settings 
- Fork 2.7k
Open
Description
Environment
- Qiskit version: 2.2
- Python version: 3.13
- Operating system: Linux
What is happening?
when expr.Value is of type Uint it is expected to have unbounded precision. When it was implemented in Python, this was the case automatically; in Rust the value is converted to f64 when it is too big, causing precision loss.
How can we reproduce the issue?
from qiskit.circuit.classical import expr, types
n = 10
val = expr.Value(n, types.Uint(1)),
print(val[0].value == n) # returns True
n = 100000000000000000000000000000000000
val = expr.Value(n, types.Uint(1)),
print(val[0].value == n) # returns False
What should happen?
The code above should return True in both cases; the integer value should be stored as an unbounded sequence of bytes.
Any suggestions?
The QPY component already had this problem and solved it:
        elif isinstance(node.value, int):
            self.file_obj.write(type_keys.ExprValue.INT)
            if node.value == 0:
                num_bytes = 0
                buffer = b""
            else:
                # This wastes a byte for `-(2 ** (8*n - 1))` for natural `n`, but they'll still
                # decode fine so it's not worth another special case.  They'll encode to
                # b"\xff\x80\x00\x00...", but we could encode them to b"\x80\x00\x00...".
                num_bytes = (node.value.bit_length() // 8) + 1
                buffer = node.value.to_bytes(num_bytes, "big", signed=True)
            self.file_obj.write(
                struct.pack(formats.EXPR_VALUE_INT_PACK, *formats.EXPR_VALUE_INT(num_bytes))
            )
            self.file_obj.write(buffer)
This can be done easily in Value.
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working
Type
Projects
Status
Ready