From e3905af305c04b48bdc950b490e802919cec8722 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Sat, 15 Mar 2025 14:42:30 +0700 Subject: [PATCH 1/3] Allow negative shift for flint rational polynomial --- .../polynomial/polynomial_rational_flint.pyx | 29 ++++++++++++++----- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/sage/rings/polynomial/polynomial_rational_flint.pyx b/src/sage/rings/polynomial/polynomial_rational_flint.pyx index 4a8d72fd590..d14eabed6ea 100644 --- a/src/sage/rings/polynomial/polynomial_rational_flint.pyx +++ b/src/sage/rings/polynomial/polynomial_rational_flint.pyx @@ -24,6 +24,7 @@ AUTHOR: from cysignals.signals cimport sig_on, sig_str, sig_off +from libc.limits cimport LONG_MIN from cpython.long cimport PyLong_AsLong from sage.arith.long cimport pyobject_to_long @@ -779,7 +780,7 @@ cdef class Polynomial_rational_flint(Polynomial): # Shifting # ########################################################################### - def __lshift__(self, n): + def __lshift__(self, long n): """ Notationally multiply ``self`` by `t^n`. @@ -792,27 +793,34 @@ cdef class Polynomial_rational_flint(Polynomial): TESTS:: sage: R. = QQ[] + sage: t << (-1) + 1 + sage: t << (-10) + 0 sage: f = R.random_element(1000) sage: (f << 23) >> 23 == f # indirect doctest True """ - cdef unsigned long k = n + if n < 0: + assert n != LONG_MIN + return self >> (-n) + cdef Polynomial_rational_flint f = self cdef Polynomial_rational_flint res cdef bint do_sig - if k == 0 or fmpq_poly_is_zero(f._poly): + if n == 0 or fmpq_poly_is_zero(f._poly): return self else: res = f._new() do_sig = fmpq_poly_length(f._poly) > 5000 or n > 5000 if do_sig: sig_str("FLINT exception") - fmpq_poly_shift_left(res._poly, f._poly, k) + fmpq_poly_shift_left(res._poly, f._poly, n) if do_sig: sig_off() return res - def __rshift__(self, n): + def __rshift__(self, long n): """ Notationally return the quotient of Euclidean division of ``self`` by `t^n`. @@ -823,20 +831,25 @@ cdef class Polynomial_rational_flint(Polynomial): sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4 sage: f >> 2 1/4*t^2 + 1/3*t + 1/2 + sage: f >> (-2) + 1/4*t^6 + 1/3*t^5 + 1/2*t^4 + t^3 + t^2 """ - cdef unsigned long k = n + if n < 0: + assert n != LONG_MIN + return self << (-n) + cdef Polynomial_rational_flint f = self cdef Polynomial_rational_flint res cdef bint do_sig - if k == 0 or fmpq_poly_is_zero(f._poly): + if n == 0 or fmpq_poly_is_zero(f._poly): return self else: res = f._new() do_sig = _do_sig(f._poly) if do_sig: sig_str("FLINT exception") - fmpq_poly_shift_right(res._poly, f._poly, k) + fmpq_poly_shift_right(res._poly, f._poly, n) if do_sig: sig_off() return res From ba924abe70a44a23e7e0198d9d3605cfe2fb5af9 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 17 Mar 2025 08:51:54 +0700 Subject: [PATCH 2/3] Add test for issue 39710 --- src/sage/rings/laurent_series_ring_element.pyx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/sage/rings/laurent_series_ring_element.pyx b/src/sage/rings/laurent_series_ring_element.pyx index bdc2cdea53e..5133cdc0236 100644 --- a/src/sage/rings/laurent_series_ring_element.pyx +++ b/src/sage/rings/laurent_series_ring_element.pyx @@ -1081,6 +1081,14 @@ cdef class LaurentSeries(AlgebraElement): sage: f = 1/(1-t) sage: f.truncate_neg(15) t^15 + t^16 + t^17 + t^18 + t^19 + O(t^20) + + TESTS: + + Check that :issue:`39710` is fixed:: + + sage: S. = LaurentSeriesRing(QQ) + sage: (t+t^2).truncate_neg(-1) + t + t^2 """ return type(self)(self._parent, self.__u >> (n - self.__n), n) From 8ce71e4d64b4c82272eccb8c0cedd441fd7f430e Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Mon, 17 Mar 2025 09:12:19 +0700 Subject: [PATCH 3/3] Add more test --- src/sage/rings/laurent_series_ring_element.pyx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sage/rings/laurent_series_ring_element.pyx b/src/sage/rings/laurent_series_ring_element.pyx index 5133cdc0236..058af021d7e 100644 --- a/src/sage/rings/laurent_series_ring_element.pyx +++ b/src/sage/rings/laurent_series_ring_element.pyx @@ -1089,6 +1089,8 @@ cdef class LaurentSeries(AlgebraElement): sage: S. = LaurentSeriesRing(QQ) sage: (t+t^2).truncate_neg(-1) t + t^2 + sage: (t+t^2).truncate_neg(-2) + t + t^2 """ return type(self)(self._parent, self.__u >> (n - self.__n), n)