Perform wrapped unsigned multiplication on two StridedIntervals.

        :param a: The first operand (StridedInterval)
        :param b: The second operand (StridedInterval)
        :return: The multiplication result

def _wrapped_unsigned_mul(a, b):
        """
        Perform wrapped unsigned multiplication on two StridedIntervals.

        :param a: The first operand (StridedInterval)
        :param b: The second operand (StridedInterval)
        :return: The multiplication result
        """
        if a.bits != b.bits:
            logger.warning("Signed mul: two parameters have different bit length")

        bits = max(a.bits, b.bits)
        lb = a.lower_bound * b.lower_bound
        ub = a.upper_bound * b.upper_bound
        uninit_flag = a.uninitialized | b.uninitialized

        if (ub - lb) < (2 ** bits):
            if b.is_integer:
                # Multiplication with an integer, and it does not overflow!
                stride = abs(a.stride * b.lower_bound)
            elif a.is_integer:
                stride = abs(a.lower_bound * b.stride)
            else:
                stride = fractions.gcd(a.stride, b.stride)
            return StridedInterval(bits=bits, stride=stride, lower_bound=lb, upper_bound=ub, uninitialized=uninit_flag)
        else:
            # Overflow occurred
            return StridedInterval.top(bits, uninitialized=False)