def _fix_precision(val: value.Scalar | sympy.Expr, precision) -> int | tuple[int, int]:
    """Convert floating point or complex numbers to (implicitly) fixed point
    integers. Complex numbers will return fixed-point (real, imag) tuples.

    Circuit parameters can be complex but we also need to use them as
    dictionary keys. We secretly use these fixed-precision integers.
    """
    if isinstance(val, sympy.Expr):
        raise ValueError(f'Cannot convert {val} to fixed precision in observable settings')
    if isinstance(val, (complex, numbers.Complex)):
        return int(val.real * precision), int(val.imag * precision)
    # Pretty much all numbers are instances of numbers.Complex
    return int(val * precision)  # pragma: no cover
Convert floating point or complex numbers to (implicitly) fixed point
    integers. Complex numbers will return fixed-point (real, imag) tuples.

    Circuit parameters can be complex but we also need to use them as
    dictionary keys. We secretly use these fixed-precision integers.
    
cirq-core/cirq/work/observable_settings.py