'Return the number of roots of ``f`` in ``[inf, sup]`` interval.
Examples
>>> from sympy import Poly, I
>>> from sympy.abc import x
>>> Poly(x**4 - 4, x).count_roots(-3, 3)
2
>>> Poly(x**4 - 4, x).count_roots(0, 1 + 3*I)
1'

def count_roots(f, inf=None, sup=None):

    (inf_real, sup_real) = (True, True)
    if (inf is not None):
        inf = sympify(inf)
        if (inf is S.NegativeInfinity):
            inf = None
        else:
            (re, im) = inf.as_real_imag()
            if (not im):
                inf = QQ.convert(inf)
            else:
                (inf, inf_real) = (list(map(QQ.convert, (re, im))), False)
    if (sup is not None):
        sup = sympify(sup)
        if (sup is S.Infinity):
            sup = None
        else:
            (re, im) = sup.as_real_imag()
            if (not im):
                sup = QQ.convert(sup)
            else:
                (sup, sup_real) = (list(map(QQ.convert, (re, im))), False)
    if (inf_real and sup_real):
        if hasattr(f.rep, 'count_real_roots'):
            count = f.rep.count_real_roots(inf=inf, sup=sup)
        else:
            raise OperationNotSupported(f, 'count_real_roots')
    else:
        if (inf_real and (inf is not None)):
            inf = (inf, QQ.zero)
        if (sup_real and (sup is not None)):
            sup = (sup, QQ.zero)
        if hasattr(f.rep, 'count_complex_roots'):
            count = f.rep.count_complex_roots(inf=inf, sup=sup)
        else:
            raise OperationNotSupported(f, 'count_complex_roots')
    return Integer(count)
