def get_symmetric_quantization_range_and_scale(activation_is_signed: bool,
                                               activation_n_bits: int,
                                               activation_threshold: float):
    """
    Calculates lower and upper bounds on the quantization range, along with quantization scale,
    for symmetric quantization (used for the symmetric and power-of-two quantizers),
    according to whether the quantization is signed or unsigned.

    Args:
        activation_is_signed: Whether the quantization is signed or not.
        activation_n_bits: Number of bits to use for quantization.
        activation_threshold: The quantization threshold.

    Returns: range lower bound, range upper bound and quantization scale.

    """
    if activation_is_signed:
        min_value = -2 ** (activation_n_bits - 1)
        max_value = 2 ** (activation_n_bits - 1) - 1
        scale = activation_threshold / 2 ** (activation_n_bits - 1)
    else:
        min_value = 0
        max_value = (2 ** activation_n_bits) - 1
        scale = activation_threshold / 2 ** activation_n_bits

    return min_value, max_value, scale