diff --git a/cirq-core/cirq/protocols/qasm.py b/cirq-core/cirq/protocols/qasm.py index 1700461f210..8fca84f0377 100644 --- a/cirq-core/cirq/protocols/qasm.py +++ b/cirq-core/cirq/protocols/qasm.py @@ -55,14 +55,23 @@ def __init__( self.qubit_id_map = {} if qubit_id_map is None else qubit_id_map self.meas_key_id_map = {} if meas_key_id_map is None else meas_key_id_map + def _format_number(self, value) -> str: + """OpenQASM 2.0 does not support '1e-5' and wants '1.0e-5'""" + s = f'{value}' + if 'e' in s and not '.' in s: + return s.replace('e', '.0e') + return s + def format_field(self, value: Any, spec: str) -> str: """Method of string.Formatter that specifies the output of format().""" if isinstance(value, (float, int)): if isinstance(value, float): value = round(value, self.precision) if spec == 'half_turns': - value = f'pi*{value}' if value != 0 else '0' + value = f'pi*{self._format_number(value)}' if value != 0 else '0' spec = '' + else: + value = self._format_number(value) elif isinstance(value, ops.Qid): value = self.qubit_id_map[value] elif isinstance(value, str) and spec == 'meas': diff --git a/cirq-core/cirq/protocols/qasm_test.py b/cirq-core/cirq/protocols/qasm_test.py index 1aa56261c03..4f993f0a5bb 100644 --- a/cirq-core/cirq/protocols/qasm_test.py +++ b/cirq-core/cirq/protocols/qasm_test.py @@ -52,3 +52,15 @@ def test_qasm(): assert cirq.qasm(ExpectsArgs(), args=cirq.QasmArgs()) == 'text' assert cirq.qasm(ExpectsArgsQubits(), args=cirq.QasmArgs(), qubits=()) == 'text' + + +def test_qasm_args_formatting(): + args = cirq.QasmArgs() + assert args.format_field(0.01, '') == '0.01' + assert args.format_field(0.01, 'half_turns') == 'pi*0.01' + assert args.format_field(0.00001, '') == '1.0e-05' + assert args.format_field(0.00001, 'half_turns') == 'pi*1.0e-05' + assert args.format_field(1e-10, 'half_turns') == 'pi*1.0e-10' + args = cirq.QasmArgs(precision=6) + assert args.format_field(0.00001234, '') == '1.2e-05' + assert args.format_field(0.00001234, 'half_turns') == 'pi*1.2e-05'