Skip to content

Commit 76125a2

Browse files
authored
Force decimals in scientific notation for OpenQASM 2.0 (#6802)
* Force decimals in scientific notation for OpenQASM 2.0 - OpenQASM 2.0 grammar requires decimal points in scientific notation. For instance, 1e-10 is not allowed according to a strict interpretation of the grammar. - This PR forces the formatter to use a decimal when printing out scientific notation.
1 parent 02f2f84 commit 76125a2

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

cirq-core/cirq/protocols/qasm.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,23 @@ def __init__(
5555
self.qubit_id_map = {} if qubit_id_map is None else qubit_id_map
5656
self.meas_key_id_map = {} if meas_key_id_map is None else meas_key_id_map
5757

58+
def _format_number(self, value) -> str:
59+
"""OpenQASM 2.0 does not support '1e-5' and wants '1.0e-5'"""
60+
s = f'{value}'
61+
if 'e' in s and not '.' in s:
62+
return s.replace('e', '.0e')
63+
return s
64+
5865
def format_field(self, value: Any, spec: str) -> str:
5966
"""Method of string.Formatter that specifies the output of format()."""
6067
if isinstance(value, (float, int)):
6168
if isinstance(value, float):
6269
value = round(value, self.precision)
6370
if spec == 'half_turns':
64-
value = f'pi*{value}' if value != 0 else '0'
71+
value = f'pi*{self._format_number(value)}' if value != 0 else '0'
6572
spec = ''
73+
else:
74+
value = self._format_number(value)
6675
elif isinstance(value, ops.Qid):
6776
value = self.qubit_id_map[value]
6877
elif isinstance(value, str) and spec == 'meas':

cirq-core/cirq/protocols/qasm_test.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,15 @@ def test_qasm():
5252

5353
assert cirq.qasm(ExpectsArgs(), args=cirq.QasmArgs()) == 'text'
5454
assert cirq.qasm(ExpectsArgsQubits(), args=cirq.QasmArgs(), qubits=()) == 'text'
55+
56+
57+
def test_qasm_args_formatting():
58+
args = cirq.QasmArgs()
59+
assert args.format_field(0.01, '') == '0.01'
60+
assert args.format_field(0.01, 'half_turns') == 'pi*0.01'
61+
assert args.format_field(0.00001, '') == '1.0e-05'
62+
assert args.format_field(0.00001, 'half_turns') == 'pi*1.0e-05'
63+
assert args.format_field(1e-10, 'half_turns') == 'pi*1.0e-10'
64+
args = cirq.QasmArgs(precision=6)
65+
assert args.format_field(0.00001234, '') == '1.2e-05'
66+
assert args.format_field(0.00001234, 'half_turns') == 'pi*1.2e-05'

0 commit comments

Comments
 (0)