Binary operation: sub

        :param b: The other operand
        :return: self - b

def sub(self, b):
        """
        Binary operation: sub

        :param b: The other operand
        :return: self - b
        """
        new_bits = max(self.bits, b.bits)

        overflow = self._wrapped_overflow_sub(self, b)
        if overflow:
            return StridedInterval.top(self.bits)

        lb = self._modular_sub(self.lower_bound, b.upper_bound, new_bits)
        ub = self._modular_sub(self.upper_bound, b.lower_bound, new_bits)

        # Is it initialized?
        uninitialized = self.uninitialized or b.uninitialized

        # Take the GCD of two operands' strides
        stride = fractions.gcd(self.stride, b.stride)

        return StridedInterval(bits=new_bits, stride=stride, lower_bound=lb, upper_bound=ub,
                               uninitialized=uninitialized).normalize()