Source code for qiskit_qm_provider.fixed_point

# Copyright 2026 Arthur Strauss
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Fixed-point arithmetic for QUA-compatible numeric representation.

Author: Arthur Strauss
Date: 2026-02-08
"""


[docs] class FixedPoint: """Fixed-point numeric type for QUA-compatible saturated arithmetic. Values are stored as signed integers scaled by ``2**fractional_bits`` within a configurable bit width. """ def __init__(self, value, fractional_bits=28, bit_width=32): """Create a fixed-point value from a float or integer scale. Args: value: Initial value (float interpreted in fixed-point units). fractional_bits: Number of fractional bits in the representation. bit_width: Total signed bit width including the sign bit. """ self.fractional_bits = fractional_bits self.scale = 1 << fractional_bits self.bit_width = bit_width self.max_value = (1 << (bit_width - 1)) - 1 self.min_value = -(1 << (bit_width - 1)) self.value = self._saturate(int(value * self.scale)) def _saturate(self, value): if value > self.max_value: return self.max_value elif value < self.min_value: return self.min_value else: return value def __add__(self, other): if isinstance(other, FixedPoint): result = self.value + other.value elif isinstance(other, int): result = self.value + (other << self.fractional_bits) else: raise TypeError("Unsupported operand type(s) for +: 'FixedPoint' and '{}'".format(type(other).__name__)) return FixedPoint(self._saturate(result) / self.scale, self.fractional_bits, self.bit_width) def __sub__(self, other): if isinstance(other, FixedPoint): result = self.value - other.value elif isinstance(other, int): result = self.value - (other << self.fractional_bits) else: raise TypeError("Unsupported operand type(s) for -: 'FixedPoint' and '{}'".format(type(other).__name__)) return FixedPoint(self._saturate(result) / self.scale, self.fractional_bits, self.bit_width) def __mul__(self, other): if isinstance(other, FixedPoint): result = (self.value * other.value) >> self.fractional_bits elif isinstance(other, int): result = self.value * other else: raise TypeError("Unsupported operand type(s) for *: 'FixedPoint' and '{}'".format(type(other).__name__)) return FixedPoint(self._saturate(result) / self.scale, self.fractional_bits, self.bit_width) def __truediv__(self, other): if isinstance(other, FixedPoint): result = (self.value << self.fractional_bits) // other.value elif isinstance(other, int): result = self.value // other else: raise TypeError("Unsupported operand type(s) for /: 'FixedPoint' and '{}'".format(type(other).__name__)) return FixedPoint(self._saturate(result) / self.scale, self.fractional_bits, self.bit_width) def __lshift__(self, other): result = self.value << other return FixedPoint(self._saturate(result) / self.scale, self.fractional_bits, self.bit_width) def __rshift__(self, other): result = self.value >> other return FixedPoint(self._saturate(result) / self.scale, self.fractional_bits, self.bit_width) def __and__(self, other): if isinstance(other, FixedPoint): result = self.value & other.value elif isinstance(other, int): result = self.value & other else: raise TypeError("Unsupported operand type(s) for &: 'FixedPoint' and '{}'".format(type(other).__name__)) return FixedPoint(result / self.scale, self.fractional_bits, self.bit_width) def __or__(self, other): if isinstance(other, FixedPoint): result = self.value | other.value elif isinstance(other, int): result = self.value | other else: raise TypeError("Unsupported operand type(s) for |: 'FixedPoint' and '{}'".format(type(other).__name__)) return FixedPoint(result / self.scale, self.fractional_bits, self.bit_width) def __repr__(self): return f"{self.value / self.scale:.10f}"
[docs] def to_int(self) -> int: """Return the value rounded toward zero as a Python integer.""" return self.value >> self.fractional_bits
[docs] def to_unsafe_int(self) -> int: """Return the raw scaled integer without fractional-bit shifting.""" return self.value
[docs] def to_float(self) -> float: """Return the value as a Python float.""" return self.value / self.scale
[docs] @classmethod def from_int(cls, int_value, fractional_bits=28, bit_width=32): """Construct a :class:`FixedPoint` from an integer fixed-point representation. Args: int_value: Scaled integer value (already in fixed-point units). fractional_bits: Number of fractional bits. bit_width: Total signed bit width. Returns: New :class:`FixedPoint` instance. """ return cls(int_value / (1 << fractional_bits), fractional_bits, bit_width)