Logical shift right with a concrete shift amount

        :param int shift_amount: Number of bits to shift right.
        :return: The new StridedInterval after right shifting
        :rtype: StridedInterval

def _rshift_logical(self, shift_amount):
        """
        Logical shift right with a concrete shift amount

        :param int shift_amount: Number of bits to shift right.
        :return: The new StridedInterval after right shifting
        :rtype: StridedInterval
        """

        if self.is_empty:
            return self

        # If straddling the south pole, we'll have to split it into two, perform logical right shift on them
        # individually, then union the result back together for better precision. Note that it's an improvement from
        # the original WrappedIntervals paper.

        ssplit = self._ssplit()
        if len(ssplit) == 1:
            l = self.lower_bound >> shift_amount
            u = self.upper_bound >> shift_amount
            stride = max(self.stride >> shift_amount, 1)

            return StridedInterval(bits=self.bits,
                                   lower_bound=l,
                                   upper_bound=u,
                                   stride=stride,
                                   uninitialized=self.uninitialized
                                   )
        else:
            a = ssplit[0]._rshift_logical(shift_amount)
            b = ssplit[1]._rshift_logical(shift_amount)

            return a.union(b)