def __pow__(self,other):
     if self.interv_class == "M":
         if other%2 == 0:
             maximo = max(abs(self.inf),abs(self.sup))
             return Interv_single(0,up(lambda:maximo**other))
         else:
             return Interv_single(down(lambda:self.inf**other),up(lambda:self.sup**other))
     else:  # N, P, Z, E
         return Interv_single(down(lambda:self.inf**other),up(lambda:self.sup**other))
 def __pow__(self, other):
     if self.interv_class == "M":
         if other % 2 == 0:
             maximo = max(abs(self.inf), abs(self.sup))
             return Interv_single(0, up(lambda: maximo**other))
         else:
             return Interv_single(down(lambda: self.inf**other),
                                  up(lambda: self.sup**other))
     else:  # N, P, Z, E
         return Interv_single(down(lambda: self.inf**other),
                              up(lambda: self.sup**other))
    def __mul__(self, other):
        inf = 0
        sup = 0
        c1 = self.interv_class
        c2 = other.interv_class
        if c1 == "E" or c2 == "E":
            inf = float("nan")
            sup = float("nan")
        elif c1 == 'Z' or c2 == 'Z':
            inf = 0
            sup = 0
        elif c1 in self._P_:
            if c2 in self._P_:
                inf = down(lambda: self.inf * other.inf)
                sup = up(lambda: self.sup * other.sup)
            elif c2 == 'M':
                inf = down(lambda: self.sup * other.inf)
                sup = up(lambda: self.sup * other.sup)
            else:  #c2 in self._N_:
                inf = down(lambda: self.sup * other.inf)
                sup = up(lambda: self.inf * other.sup)
        elif c1 == 'M':
            if c2 in self._P_:
                inf = down(lambda: self.inf * other.sup)
                sup = up(lambda: self.sup * other.sup)
            elif c2 == 'M':
                inf = min(down(lambda: self.inf * other.sup),
                          down(lambda: self.sup * other.inf))
                sup = max(up(lambda: self.sup * other.sup),
                          up(lambda: self.inf * other.inf))
            else:  #c2 in N
                inf = down(lambda: self.sup * other.inf)
                sup = up(lambda: self.inf * other.inf)
        else:  #c1 in N
            if c2 in self._P_:
                inf = down(lambda: self.inf * other.sup)
                sup = up(lambda: self.sup * other.inf)
            elif c2 == 'M':
                inf = down(lambda: self.inf * other.sup)
                sup = up(lambda: self.inf * other.inf)
            else:  #c2 in N
                inf = down(lambda: self.sup * other.sup)
                sup = up(lambda: self.inf * other.inf)

        return Interv_single(inf, sup)
    def __mul__(self,other):
        inf = 0
        sup = 0
        c1 = self.interv_class
        c2 = other.interv_class
        if c1 == "E" or c2 == "E":
            inf = float("nan")
            sup = float("nan")
        elif c1 == 'Z' or c2 == 'Z':
            inf = 0
            sup = 0
        elif c1 in self._P_:
            if c2 in self._P_:
                inf = down(lambda: self.inf * other.inf)
                sup = up(lambda: self.sup * other.sup)
            elif c2 == 'M':
                inf = down(lambda: self.sup * other.inf)
                sup = up(lambda: self.sup * other.sup)
            else: #c2 in self._N_:
                inf = down(lambda: self.sup * other.inf)
                sup = up(lambda: self.inf * other.sup)
        elif c1 == 'M':
            if c2 in self._P_:
                inf = down(lambda: self.inf * other.sup)
                sup = up(lambda: self.sup * other.sup)
            elif c2 == 'M':
                inf = min(down(lambda: self.inf * other.sup), down(lambda: self.sup * other.inf))
                sup = max(up(lambda: self.sup * other.sup), up(lambda: self.inf * other.inf))
            else: #c2 in N
                inf = down(lambda: self.sup * other.inf)
                sup = up(lambda: self.inf * other.inf)
        else: #c1 in N
            if c2 in self._P_:
                inf = down(lambda: self.inf * other.sup)
                sup = up(lambda: self.sup * other.inf)
            elif c2 == 'M':
                inf = down(lambda: self.inf * other.sup)
                sup = up(lambda: self.inf * other.inf)
            else: #c2 in N
                inf = down(lambda: self.sup * other.sup)
                sup = up(lambda: self.inf * other.inf)

        return Interv_single(inf,sup)
 def __sub__(self, other):
     return Interv_single(down(lambda: self.inf - other.sup),
                          up(lambda: (self.sup - other.inf)))
 def __add__(self, other):
     return Interv_single(down(lambda: self.inf + other.inf),
                          up(lambda: (self.sup + other.sup)))
    def __div__(self, other):

        inf = 0
        sup = 0
        c1 = self.interv_class
        c2 = other.interv_class
        if c2 == "E" or c1 == "E":
            inf = float("nan")
            sup = float("nan")
        elif c2 == "Z":
            inf = float("nan")
            sup = float("nan")
        elif c1 == "Z":
            inf = 0
            sup = 0
        elif c2 == "P0":
            if c1 == "P1":
                inf = down(lambda: self.inf / other.sup)
                sup = float("+inf")
            elif c1 == "P0":
                inf = 0
                sup = float("+inf")
            elif c1 == "M":
                inf = float("-inf")
                sup = float("inf")
            elif c1 == "N0":
                inf = float("-inf")
                sup = 0
            else:  #c1 == "N1":
                inf = float("-inf")
                sup = up(lambda: self.sup / other.sup)
        elif c2 == "P1":
            if c1 == "P1":
                inf = down(lambda: self.inf / other.sup)
                sup = up(lambda: self.sup / other.inf)
            elif c1 == "P0":
                inf = 0
                sup = up(lambda: self.sup / other.inf)
            elif c1 == "M":
                inf = down(lambda: self.inf / other.inf)
                sup = up(lambda: self.sup / other.inf)
            elif c1 == "N0":
                inf = down(lambda: self.inf / other.inf)
                sup = 0
            else:  #c1 == "N1":
                inf = down(lambda: self.inf / other.inf)
                sup = up(lambda: self.sup / other.sup)
        elif c2 == "M":
            inf = float("-inf")
            sup = float("inf")
        elif c2 == "N0":
            if c1 == "P1":
                inf = float("-inf")
                sup = up(lambda: self.inf / other.inf)
            elif c1 == "P0":
                inf = float("-inf")
                sup = 0
            elif c1 == "M":
                inf = float("-inf")
                sup = float("inf")
            elif c1 == "N0":
                inf = 0
                sup = float("+inf")
            else:  #c1 == "N1":
                inf = down(lambda: self.sup / other.inf)
                sup = float("+inf")
        elif c2 == "N1":
            if c1 == "P1":
                inf = down(lambda: self.sup / other.sup)
                sup = up(lambda: self.inf / other.inf)
            elif c1 == "P0":
                inf = down(lambda: self.sup / other.sup)
                sup = 0
            elif c1 == "M":
                inf = down(lambda: self.sup / other.sup)
                sup = up(lambda: self.inf / other.sup)
            elif c1 == "N0":
                inf = 0
                sup = up(lambda: self.inf / other.sup)
            else:  #c1 == "N1":
                inf = down(lambda: self.sup / other.inf)
                sup = up(lambda: self.inf / other.sup)

        return Interv_single(inf, sup)
 def __sub__(self,other):
     return Interv_single(down(lambda: self.inf - other.sup), up(lambda: (self.sup - other.inf)))
 def __add__(self,other):
     return Interv_single(down(lambda: self.inf + other.inf), up(lambda:(self.sup + other.sup)))
    def __div__(self,other):

        inf = 0
        sup = 0
        c1 = self.interv_class
        c2 = other.interv_class
        if c2 == "E" or c1 == "E":
            inf = float("nan")
            sup = float("nan")
        elif c2 == "Z":
            inf = float("nan")
            sup = float("nan")
        elif c1 == "Z":
            inf = 0
            sup = 0
        elif c2 == "P0":
            if c1 == "P1":
                inf = down(lambda: self.inf / other.sup)
                sup = float("+inf")
            elif c1 == "P0":
                inf = 0
                sup = float("+inf")
            elif c1 == "M":
                inf = float("-inf")
                sup = float("inf")
            elif c1 == "N0":
                inf = float("-inf")
                sup = 0
            else: #c1 == "N1":
                inf = float("-inf")
                sup = up(lambda: self.sup / other.sup)
        elif c2 == "P1":
            if c1 == "P1":
                inf = down(lambda: self.inf / other.sup)
                sup = up(lambda: self.sup / other.inf)
            elif c1 == "P0":
                inf = 0
                sup = up(lambda: self.sup / other.inf)
            elif c1 == "M":
                inf = down(lambda: self.inf / other.inf)
                sup = up(lambda: self.sup / other.inf)
            elif c1 == "N0":
                inf = down(lambda: self.inf / other.inf)
                sup = 0
            else: #c1 == "N1":
                inf = down(lambda: self.inf / other.inf)
                sup = up(lambda: self.sup / other.sup)
        elif c2 == "M":
            inf = float("-inf")
            sup = float("inf")
        elif c2 == "N0":
            if c1 == "P1":
                inf = float("-inf")
                sup = up(lambda: self.inf / other.inf)
            elif c1 == "P0":
                inf = float("-inf")
                sup = 0
            elif c1 == "M":
                inf = float("-inf")
                sup = float("inf")
            elif c1 == "N0":
                inf = 0
                sup = float("+inf")
            else: #c1 == "N1":
                inf = down(lambda: self.sup / other.inf)
                sup = float("+inf")
        elif c2 == "N1":
            if c1 == "P1":
                inf = down(lambda: self.sup / other.sup)
                sup = up(lambda: self.inf / other.inf)
            elif c1 == "P0":
                inf = down(lambda: self.sup / other.sup)
                sup = 0
            elif c1 == "M":
                inf = down(lambda: self.sup / other.sup)
                sup = up(lambda: self.inf / other.sup)
            elif c1 == "N0":
                inf = 0
                sup = up(lambda: self.inf / other.sup)
            else: #c1 == "N1":
                inf = down(lambda: self.sup / other.inf)
                sup = up(lambda: self.inf / other.sup)

        return Interv_single(inf,sup)