diff --git a/qualtran/_infra/data_types.py b/qualtran/_infra/data_types.py index ee918d506..82c7bcdde 100644 --- a/qualtran/_infra/data_types.py +++ b/qualtran/_infra/data_types.py @@ -16,7 +16,7 @@ We often wish to write algorithms which operate on quantum data. One can think of quantum data types, similar to classical data types, where a collection of qubits can be used to represent a specific quantum data type (eg: a quantum -integer of width 32 would comprise of 32 qubits, similar to a classical uint32 +integer of width 32 would comprise 32 qubits, similar to a classical uint32 type). More generally, many current primitives and algorithms in qualtran implicitly expect registers which represent signed or unsigned integers, fixed-point (fp) numbers , or “classical registers” which store some classical @@ -40,7 +40,7 @@ type assuming the bitsizes match. QInt(32) == QAny(32), QInt(32) != QFxp(32, 16). QInt(32) != QUInt(32). 5. We assume a big endian convention for addressing QBits in registers -throughout qualtran. Recall that in a big endian convention the most signficant +throughout qualtran. Recall that in a big endian convention the most significant bit is at index 0. If you iterate through the bits in a register they will be yielded from most significant to least significant. 6. Ones' complement integers are used extensively in quantum algorithms. We have @@ -181,7 +181,7 @@ def __str__(self): @attrs.frozen class QAny(QDType): - """Opaque bag-of-qbits type.""" + """Opaque bag-of-qubits type.""" bitsize: SymbolicInt @@ -214,7 +214,10 @@ def assert_valid_classical_val_array(self, val_array, debug_str: str = 'val'): class QInt(QDType): """Signed Integer of a given width bitsize. - A two's complement representation is assumed for negative integers. + A two's complement representation is used for negative integers. + + Here (and throughout Qualtran), we use a big-endian bit convention. The most significant + bit is at index 0. Attributes: bitsize: The number of qubits used to represent the integer. @@ -275,7 +278,11 @@ def __str__(self): class QIntOnesComp(QDType): """Signed Integer of a given width bitsize. - A ones' complement representation is assumed for negative integers. + In contrast to `QInt`, this data type uses the ones' complement representation for negative + integers. + + Here (and throughout Qualtran), we use a big-endian bit convention. The most significant + bit is at index 0. Attributes: bitsize: The number of qubits used to represent the integer. @@ -323,8 +330,11 @@ def assert_valid_classical_val(self, val, debug_str: str = 'val'): class QUInt(QDType): """Unsigned integer of a given width bitsize which wraps around upon overflow. - Similar to unsigned integer types in C. Any intended wrap around effect is - expected to be handled by the developer. + Any intended wrap around effect is expected to be handled by the developer, similar + to an unsigned integer type in C. + + Here (and throughout Qualtran), we use a big-endian bit convention. The most significant + bit is at index 0. Attributes: bitsize: The number of qubits used to represent the integer. diff --git a/qualtran/_infra/data_types_test.py b/qualtran/_infra/data_types_test.py index 65252c5cb..ff08b7df6 100644 --- a/qualtran/_infra/data_types_test.py +++ b/qualtran/_infra/data_types_test.py @@ -295,6 +295,9 @@ def test_qint_to_and_from_bits(): assert qint4.from_bits(qint4.to_bits(x)) == x assert list(qint4.to_bits(-2)) == [1, 1, 1, 0] assert list(QInt(4).to_bits(2)) == [0, 0, 1, 0] + # MSB at lowest index -- big-endian + assert qint4.from_bits([0, 0, 0, 1]) == 1 + assert qint4.from_bits([0, 0, 0, 1]) < qint4.from_bits([0, 1, 0, 0]) assert qint4.from_bits(qint4.to_bits(-2)) == -2 assert qint4.from_bits(qint4.to_bits(2)) == 2 with pytest.raises(ValueError): @@ -325,6 +328,10 @@ def test_quint_to_and_from_bits(): assert [*quint4.get_classical_domain()] == [*range(0, 16)] assert list(quint4.to_bits(10)) == [1, 0, 1, 0] assert quint4.from_bits(quint4.to_bits(10)) == 10 + # MSB at lowest index -- big-endian + assert quint4.from_bits([0, 0, 0, 1]) == 1 + assert quint4.from_bits([0, 0, 0, 1]) < quint4.from_bits([1, 0, 0, 0]) + for x in range(16): assert quint4.from_bits(quint4.to_bits(x)) == x with pytest.raises(ValueError):