def naive_log_ctz(x: int) ->int:
    """Count trailing zeros, in a O(log(zeros)) steps.

    Args:
        x: An int.

    Returns:
        The number of trailing zeros in x, as an int.

    This implementation is much faster than the naive linear implementation,
    as it performs a logarithmic number of steps relative to the number of
    trailing zeros in x. Unlike the linear implementation, this one avoids
    looking at the high bits of x if it can, so it only returns the number
    of zeros, not the remaining significant bits of x.

    We still say this implementation is "naive" because it does not try
    to use any specific optimization tricks besides the logarithmic algorithm.

    >>> naive_log_ctz(0)
    0
    >>> naive_log_ctz(1)
    0
    >>> naive_log_ctz(-1)
    0
    >>> naive_log_ctz(2)
    1
    >>> naive_log_ctz(-2)
    1
    >>> naive_log_ctz(40) # 0b101000 = 2**3 * 5
    3
    >>> naive_log_ctz(-40) # 0b1..1011000
    3
    >>> naive_log_ctz(37 << 100)
    100

    # Of course the behavior should match for all integers...
    >>> all(naive_ctz2(x)[0] == naive_log_ctz(x) for x in range(1024))
    True
    """
    if x == 0:
        return 0
    else:
        zmask = 1
        zscale = 1
        low_bits = x & zmask
        while low_bits == 0:
            zmask = zmask << zscale | zmask
            zscale <<= 1
            low_bits = x & zmask
        zscale >>= 1
        zmask >>= zscale
        zeros: int = 0
        while zscale > 0:
            if low_bits & zmask == 0:
                low_bits >>= zscale
                zeros += zscale
            zscale >>= 1
            zmask >>= zscale
        return zeros
