[Python] Why does sympy.LT(A) / sympy.LT(B) and sympy.LC(A) / sympy.LC(B) produce different...

Discussão em 'Python' iniciado por Stack, Abril 19, 2025.

  1. Stack

    Stack Membro Participativo

    I've just find out a strange behaviour (for me) of sympy.LT and sympy.LC functions. I thought they could be seen as if related each others, but it seems not precesily...

    As an example, imagine we would like to compute ourselves the Euclidean division as proposed in Knuth of the two following polynomials A = X / 7 and B = X / 9, defined over the domain RR.

    So, we would compute tmp = sympy.LT(A) / sympy.LT(B), or the same quotient with sympy.LC, since the degree of the polynomials are the same here. But, the results are different floating point numbers:

    >>> import sympy
    >>> import fractions
    >>> x = sympy.var('X')
    >>> A = sympy.Poly(1 / 9 * x, x, domain='RR')
    >>> B = sympy.Poly(1 / 7 * x, x, domain='RR')
    >>> sympy.LT(A) / sympy.LT(B) == sympy.LC(A) / sympy.LC(B)
    False
    >>> print((sympy.LT(A) / sympy.LT(B)).evalf(60))
    0.777777777777777679091286699986085295677185058593750000000000
    >>> print((sympy.LC(A) / sympy.LC(B)).evalf(60))
    0.777777777777777790113589162501739338040351867675781250000000


    Actually, it is not difficult to understand which number are computed in each case. Let us denotes alpha = 1 - 1 / 2 ** 54. Then, the first one is 7 * alpha / 9, which is the rounding down of the floating point 7 / 9 while the second is 7 * alpha / 9 + 1 / 2 ** 54, which is the rounding to the nearest of 7 / 9:

    >>> alpha = 1 - fractions.Fraction(1, 2 ** 54)
    >>> print(str((sympy.LT(A) / sympy.LT(B)).evalf(60)) + "\n" + str((sympy.LC(A) / sympy.LC(B)).evalf(60)))
    0.777777777777777679091286699986085295677185058593750000000000
    0.777777777777777790113589162501739338040351867675781250000000

    >>> down_rounding = 7 * alpha / 9
    >>> sympy.LT(A) / sympy.LT(B) == down_rounding.numerator / down_rounding.denominator
    True

    >>> to_nearest_rounding = 7 * alpha / 9 + fractions.Fraction(1, 2 ** 54)
    >>> sympy.LC(A) / sympy.LC(B) == to_nearest_rounding.numerator / to_nearest_rounding.denominator
    True


    First, is this phenomena reprodicible? Then, if yes, is someone able to explain if this is a bug or a feature, and why?

    Continue reading...

Compartilhe esta Página