17db96d56Sopenharmony_ci# Copyright 2007 Google, Inc. All Rights Reserved.
27db96d56Sopenharmony_ci# Licensed to PSF under a Contributor Agreement.
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci"""Abstract Base Classes (ABCs) for numbers, according to PEP 3141.
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ciTODO: Fill out more detailed documentation on the operators."""
77db96d56Sopenharmony_ci
87db96d56Sopenharmony_cifrom abc import ABCMeta, abstractmethod
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ci__all__ = ["Number", "Complex", "Real", "Rational", "Integral"]
117db96d56Sopenharmony_ci
127db96d56Sopenharmony_ciclass Number(metaclass=ABCMeta):
137db96d56Sopenharmony_ci    """All numbers inherit from this class.
147db96d56Sopenharmony_ci
157db96d56Sopenharmony_ci    If you just want to check if an argument x is a number, without
167db96d56Sopenharmony_ci    caring what kind, use isinstance(x, Number).
177db96d56Sopenharmony_ci    """
187db96d56Sopenharmony_ci    __slots__ = ()
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ci    # Concrete numeric types must provide their own hash implementation
217db96d56Sopenharmony_ci    __hash__ = None
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_ci## Notes on Decimal
257db96d56Sopenharmony_ci## ----------------
267db96d56Sopenharmony_ci## Decimal has all of the methods specified by the Real abc, but it should
277db96d56Sopenharmony_ci## not be registered as a Real because decimals do not interoperate with
287db96d56Sopenharmony_ci## binary floats (i.e.  Decimal('3.14') + 2.71828 is undefined).  But,
297db96d56Sopenharmony_ci## abstract reals are expected to interoperate (i.e. R1 + R2 should be
307db96d56Sopenharmony_ci## expected to work if R1 and R2 are both Reals).
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ciclass Complex(Number):
337db96d56Sopenharmony_ci    """Complex defines the operations that work on the builtin complex type.
347db96d56Sopenharmony_ci
357db96d56Sopenharmony_ci    In short, those are: a conversion to complex, .real, .imag, +, -,
367db96d56Sopenharmony_ci    *, /, **, abs(), .conjugate, ==, and !=.
377db96d56Sopenharmony_ci
387db96d56Sopenharmony_ci    If it is given heterogeneous arguments, and doesn't have special
397db96d56Sopenharmony_ci    knowledge about them, it should fall back to the builtin complex
407db96d56Sopenharmony_ci    type as described below.
417db96d56Sopenharmony_ci    """
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_ci    __slots__ = ()
447db96d56Sopenharmony_ci
457db96d56Sopenharmony_ci    @abstractmethod
467db96d56Sopenharmony_ci    def __complex__(self):
477db96d56Sopenharmony_ci        """Return a builtin complex instance. Called for complex(self)."""
487db96d56Sopenharmony_ci
497db96d56Sopenharmony_ci    def __bool__(self):
507db96d56Sopenharmony_ci        """True if self != 0. Called for bool(self)."""
517db96d56Sopenharmony_ci        return self != 0
527db96d56Sopenharmony_ci
537db96d56Sopenharmony_ci    @property
547db96d56Sopenharmony_ci    @abstractmethod
557db96d56Sopenharmony_ci    def real(self):
567db96d56Sopenharmony_ci        """Retrieve the real component of this number.
577db96d56Sopenharmony_ci
587db96d56Sopenharmony_ci        This should subclass Real.
597db96d56Sopenharmony_ci        """
607db96d56Sopenharmony_ci        raise NotImplementedError
617db96d56Sopenharmony_ci
627db96d56Sopenharmony_ci    @property
637db96d56Sopenharmony_ci    @abstractmethod
647db96d56Sopenharmony_ci    def imag(self):
657db96d56Sopenharmony_ci        """Retrieve the imaginary component of this number.
667db96d56Sopenharmony_ci
677db96d56Sopenharmony_ci        This should subclass Real.
687db96d56Sopenharmony_ci        """
697db96d56Sopenharmony_ci        raise NotImplementedError
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ci    @abstractmethod
727db96d56Sopenharmony_ci    def __add__(self, other):
737db96d56Sopenharmony_ci        """self + other"""
747db96d56Sopenharmony_ci        raise NotImplementedError
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_ci    @abstractmethod
777db96d56Sopenharmony_ci    def __radd__(self, other):
787db96d56Sopenharmony_ci        """other + self"""
797db96d56Sopenharmony_ci        raise NotImplementedError
807db96d56Sopenharmony_ci
817db96d56Sopenharmony_ci    @abstractmethod
827db96d56Sopenharmony_ci    def __neg__(self):
837db96d56Sopenharmony_ci        """-self"""
847db96d56Sopenharmony_ci        raise NotImplementedError
857db96d56Sopenharmony_ci
867db96d56Sopenharmony_ci    @abstractmethod
877db96d56Sopenharmony_ci    def __pos__(self):
887db96d56Sopenharmony_ci        """+self"""
897db96d56Sopenharmony_ci        raise NotImplementedError
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_ci    def __sub__(self, other):
927db96d56Sopenharmony_ci        """self - other"""
937db96d56Sopenharmony_ci        return self + -other
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ci    def __rsub__(self, other):
967db96d56Sopenharmony_ci        """other - self"""
977db96d56Sopenharmony_ci        return -self + other
987db96d56Sopenharmony_ci
997db96d56Sopenharmony_ci    @abstractmethod
1007db96d56Sopenharmony_ci    def __mul__(self, other):
1017db96d56Sopenharmony_ci        """self * other"""
1027db96d56Sopenharmony_ci        raise NotImplementedError
1037db96d56Sopenharmony_ci
1047db96d56Sopenharmony_ci    @abstractmethod
1057db96d56Sopenharmony_ci    def __rmul__(self, other):
1067db96d56Sopenharmony_ci        """other * self"""
1077db96d56Sopenharmony_ci        raise NotImplementedError
1087db96d56Sopenharmony_ci
1097db96d56Sopenharmony_ci    @abstractmethod
1107db96d56Sopenharmony_ci    def __truediv__(self, other):
1117db96d56Sopenharmony_ci        """self / other: Should promote to float when necessary."""
1127db96d56Sopenharmony_ci        raise NotImplementedError
1137db96d56Sopenharmony_ci
1147db96d56Sopenharmony_ci    @abstractmethod
1157db96d56Sopenharmony_ci    def __rtruediv__(self, other):
1167db96d56Sopenharmony_ci        """other / self"""
1177db96d56Sopenharmony_ci        raise NotImplementedError
1187db96d56Sopenharmony_ci
1197db96d56Sopenharmony_ci    @abstractmethod
1207db96d56Sopenharmony_ci    def __pow__(self, exponent):
1217db96d56Sopenharmony_ci        """self**exponent; should promote to float or complex when necessary."""
1227db96d56Sopenharmony_ci        raise NotImplementedError
1237db96d56Sopenharmony_ci
1247db96d56Sopenharmony_ci    @abstractmethod
1257db96d56Sopenharmony_ci    def __rpow__(self, base):
1267db96d56Sopenharmony_ci        """base ** self"""
1277db96d56Sopenharmony_ci        raise NotImplementedError
1287db96d56Sopenharmony_ci
1297db96d56Sopenharmony_ci    @abstractmethod
1307db96d56Sopenharmony_ci    def __abs__(self):
1317db96d56Sopenharmony_ci        """Returns the Real distance from 0. Called for abs(self)."""
1327db96d56Sopenharmony_ci        raise NotImplementedError
1337db96d56Sopenharmony_ci
1347db96d56Sopenharmony_ci    @abstractmethod
1357db96d56Sopenharmony_ci    def conjugate(self):
1367db96d56Sopenharmony_ci        """(x+y*i).conjugate() returns (x-y*i)."""
1377db96d56Sopenharmony_ci        raise NotImplementedError
1387db96d56Sopenharmony_ci
1397db96d56Sopenharmony_ci    @abstractmethod
1407db96d56Sopenharmony_ci    def __eq__(self, other):
1417db96d56Sopenharmony_ci        """self == other"""
1427db96d56Sopenharmony_ci        raise NotImplementedError
1437db96d56Sopenharmony_ci
1447db96d56Sopenharmony_ciComplex.register(complex)
1457db96d56Sopenharmony_ci
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_ciclass Real(Complex):
1487db96d56Sopenharmony_ci    """To Complex, Real adds the operations that work on real numbers.
1497db96d56Sopenharmony_ci
1507db96d56Sopenharmony_ci    In short, those are: a conversion to float, trunc(), divmod,
1517db96d56Sopenharmony_ci    %, <, <=, >, and >=.
1527db96d56Sopenharmony_ci
1537db96d56Sopenharmony_ci    Real also provides defaults for the derived operations.
1547db96d56Sopenharmony_ci    """
1557db96d56Sopenharmony_ci
1567db96d56Sopenharmony_ci    __slots__ = ()
1577db96d56Sopenharmony_ci
1587db96d56Sopenharmony_ci    @abstractmethod
1597db96d56Sopenharmony_ci    def __float__(self):
1607db96d56Sopenharmony_ci        """Any Real can be converted to a native float object.
1617db96d56Sopenharmony_ci
1627db96d56Sopenharmony_ci        Called for float(self)."""
1637db96d56Sopenharmony_ci        raise NotImplementedError
1647db96d56Sopenharmony_ci
1657db96d56Sopenharmony_ci    @abstractmethod
1667db96d56Sopenharmony_ci    def __trunc__(self):
1677db96d56Sopenharmony_ci        """trunc(self): Truncates self to an Integral.
1687db96d56Sopenharmony_ci
1697db96d56Sopenharmony_ci        Returns an Integral i such that:
1707db96d56Sopenharmony_ci          * i>0 iff self>0;
1717db96d56Sopenharmony_ci          * abs(i) <= abs(self);
1727db96d56Sopenharmony_ci          * for any Integral j satisfying the first two conditions,
1737db96d56Sopenharmony_ci            abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
1747db96d56Sopenharmony_ci        i.e. "truncate towards 0".
1757db96d56Sopenharmony_ci        """
1767db96d56Sopenharmony_ci        raise NotImplementedError
1777db96d56Sopenharmony_ci
1787db96d56Sopenharmony_ci    @abstractmethod
1797db96d56Sopenharmony_ci    def __floor__(self):
1807db96d56Sopenharmony_ci        """Finds the greatest Integral <= self."""
1817db96d56Sopenharmony_ci        raise NotImplementedError
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_ci    @abstractmethod
1847db96d56Sopenharmony_ci    def __ceil__(self):
1857db96d56Sopenharmony_ci        """Finds the least Integral >= self."""
1867db96d56Sopenharmony_ci        raise NotImplementedError
1877db96d56Sopenharmony_ci
1887db96d56Sopenharmony_ci    @abstractmethod
1897db96d56Sopenharmony_ci    def __round__(self, ndigits=None):
1907db96d56Sopenharmony_ci        """Rounds self to ndigits decimal places, defaulting to 0.
1917db96d56Sopenharmony_ci
1927db96d56Sopenharmony_ci        If ndigits is omitted or None, returns an Integral, otherwise
1937db96d56Sopenharmony_ci        returns a Real. Rounds half toward even.
1947db96d56Sopenharmony_ci        """
1957db96d56Sopenharmony_ci        raise NotImplementedError
1967db96d56Sopenharmony_ci
1977db96d56Sopenharmony_ci    def __divmod__(self, other):
1987db96d56Sopenharmony_ci        """divmod(self, other): The pair (self // other, self % other).
1997db96d56Sopenharmony_ci
2007db96d56Sopenharmony_ci        Sometimes this can be computed faster than the pair of
2017db96d56Sopenharmony_ci        operations.
2027db96d56Sopenharmony_ci        """
2037db96d56Sopenharmony_ci        return (self // other, self % other)
2047db96d56Sopenharmony_ci
2057db96d56Sopenharmony_ci    def __rdivmod__(self, other):
2067db96d56Sopenharmony_ci        """divmod(other, self): The pair (self // other, self % other).
2077db96d56Sopenharmony_ci
2087db96d56Sopenharmony_ci        Sometimes this can be computed faster than the pair of
2097db96d56Sopenharmony_ci        operations.
2107db96d56Sopenharmony_ci        """
2117db96d56Sopenharmony_ci        return (other // self, other % self)
2127db96d56Sopenharmony_ci
2137db96d56Sopenharmony_ci    @abstractmethod
2147db96d56Sopenharmony_ci    def __floordiv__(self, other):
2157db96d56Sopenharmony_ci        """self // other: The floor() of self/other."""
2167db96d56Sopenharmony_ci        raise NotImplementedError
2177db96d56Sopenharmony_ci
2187db96d56Sopenharmony_ci    @abstractmethod
2197db96d56Sopenharmony_ci    def __rfloordiv__(self, other):
2207db96d56Sopenharmony_ci        """other // self: The floor() of other/self."""
2217db96d56Sopenharmony_ci        raise NotImplementedError
2227db96d56Sopenharmony_ci
2237db96d56Sopenharmony_ci    @abstractmethod
2247db96d56Sopenharmony_ci    def __mod__(self, other):
2257db96d56Sopenharmony_ci        """self % other"""
2267db96d56Sopenharmony_ci        raise NotImplementedError
2277db96d56Sopenharmony_ci
2287db96d56Sopenharmony_ci    @abstractmethod
2297db96d56Sopenharmony_ci    def __rmod__(self, other):
2307db96d56Sopenharmony_ci        """other % self"""
2317db96d56Sopenharmony_ci        raise NotImplementedError
2327db96d56Sopenharmony_ci
2337db96d56Sopenharmony_ci    @abstractmethod
2347db96d56Sopenharmony_ci    def __lt__(self, other):
2357db96d56Sopenharmony_ci        """self < other
2367db96d56Sopenharmony_ci
2377db96d56Sopenharmony_ci        < on Reals defines a total ordering, except perhaps for NaN."""
2387db96d56Sopenharmony_ci        raise NotImplementedError
2397db96d56Sopenharmony_ci
2407db96d56Sopenharmony_ci    @abstractmethod
2417db96d56Sopenharmony_ci    def __le__(self, other):
2427db96d56Sopenharmony_ci        """self <= other"""
2437db96d56Sopenharmony_ci        raise NotImplementedError
2447db96d56Sopenharmony_ci
2457db96d56Sopenharmony_ci    # Concrete implementations of Complex abstract methods.
2467db96d56Sopenharmony_ci    def __complex__(self):
2477db96d56Sopenharmony_ci        """complex(self) == complex(float(self), 0)"""
2487db96d56Sopenharmony_ci        return complex(float(self))
2497db96d56Sopenharmony_ci
2507db96d56Sopenharmony_ci    @property
2517db96d56Sopenharmony_ci    def real(self):
2527db96d56Sopenharmony_ci        """Real numbers are their real component."""
2537db96d56Sopenharmony_ci        return +self
2547db96d56Sopenharmony_ci
2557db96d56Sopenharmony_ci    @property
2567db96d56Sopenharmony_ci    def imag(self):
2577db96d56Sopenharmony_ci        """Real numbers have no imaginary component."""
2587db96d56Sopenharmony_ci        return 0
2597db96d56Sopenharmony_ci
2607db96d56Sopenharmony_ci    def conjugate(self):
2617db96d56Sopenharmony_ci        """Conjugate is a no-op for Reals."""
2627db96d56Sopenharmony_ci        return +self
2637db96d56Sopenharmony_ci
2647db96d56Sopenharmony_ciReal.register(float)
2657db96d56Sopenharmony_ci
2667db96d56Sopenharmony_ci
2677db96d56Sopenharmony_ciclass Rational(Real):
2687db96d56Sopenharmony_ci    """.numerator and .denominator should be in lowest terms."""
2697db96d56Sopenharmony_ci
2707db96d56Sopenharmony_ci    __slots__ = ()
2717db96d56Sopenharmony_ci
2727db96d56Sopenharmony_ci    @property
2737db96d56Sopenharmony_ci    @abstractmethod
2747db96d56Sopenharmony_ci    def numerator(self):
2757db96d56Sopenharmony_ci        raise NotImplementedError
2767db96d56Sopenharmony_ci
2777db96d56Sopenharmony_ci    @property
2787db96d56Sopenharmony_ci    @abstractmethod
2797db96d56Sopenharmony_ci    def denominator(self):
2807db96d56Sopenharmony_ci        raise NotImplementedError
2817db96d56Sopenharmony_ci
2827db96d56Sopenharmony_ci    # Concrete implementation of Real's conversion to float.
2837db96d56Sopenharmony_ci    def __float__(self):
2847db96d56Sopenharmony_ci        """float(self) = self.numerator / self.denominator
2857db96d56Sopenharmony_ci
2867db96d56Sopenharmony_ci        It's important that this conversion use the integer's "true"
2877db96d56Sopenharmony_ci        division rather than casting one side to float before dividing
2887db96d56Sopenharmony_ci        so that ratios of huge integers convert without overflowing.
2897db96d56Sopenharmony_ci
2907db96d56Sopenharmony_ci        """
2917db96d56Sopenharmony_ci        return int(self.numerator) / int(self.denominator)
2927db96d56Sopenharmony_ci
2937db96d56Sopenharmony_ci
2947db96d56Sopenharmony_ciclass Integral(Rational):
2957db96d56Sopenharmony_ci    """Integral adds methods that work on integral numbers.
2967db96d56Sopenharmony_ci
2977db96d56Sopenharmony_ci    In short, these are conversion to int, pow with modulus, and the
2987db96d56Sopenharmony_ci    bit-string operations.
2997db96d56Sopenharmony_ci    """
3007db96d56Sopenharmony_ci
3017db96d56Sopenharmony_ci    __slots__ = ()
3027db96d56Sopenharmony_ci
3037db96d56Sopenharmony_ci    @abstractmethod
3047db96d56Sopenharmony_ci    def __int__(self):
3057db96d56Sopenharmony_ci        """int(self)"""
3067db96d56Sopenharmony_ci        raise NotImplementedError
3077db96d56Sopenharmony_ci
3087db96d56Sopenharmony_ci    def __index__(self):
3097db96d56Sopenharmony_ci        """Called whenever an index is needed, such as in slicing"""
3107db96d56Sopenharmony_ci        return int(self)
3117db96d56Sopenharmony_ci
3127db96d56Sopenharmony_ci    @abstractmethod
3137db96d56Sopenharmony_ci    def __pow__(self, exponent, modulus=None):
3147db96d56Sopenharmony_ci        """self ** exponent % modulus, but maybe faster.
3157db96d56Sopenharmony_ci
3167db96d56Sopenharmony_ci        Accept the modulus argument if you want to support the
3177db96d56Sopenharmony_ci        3-argument version of pow(). Raise a TypeError if exponent < 0
3187db96d56Sopenharmony_ci        or any argument isn't Integral. Otherwise, just implement the
3197db96d56Sopenharmony_ci        2-argument version described in Complex.
3207db96d56Sopenharmony_ci        """
3217db96d56Sopenharmony_ci        raise NotImplementedError
3227db96d56Sopenharmony_ci
3237db96d56Sopenharmony_ci    @abstractmethod
3247db96d56Sopenharmony_ci    def __lshift__(self, other):
3257db96d56Sopenharmony_ci        """self << other"""
3267db96d56Sopenharmony_ci        raise NotImplementedError
3277db96d56Sopenharmony_ci
3287db96d56Sopenharmony_ci    @abstractmethod
3297db96d56Sopenharmony_ci    def __rlshift__(self, other):
3307db96d56Sopenharmony_ci        """other << self"""
3317db96d56Sopenharmony_ci        raise NotImplementedError
3327db96d56Sopenharmony_ci
3337db96d56Sopenharmony_ci    @abstractmethod
3347db96d56Sopenharmony_ci    def __rshift__(self, other):
3357db96d56Sopenharmony_ci        """self >> other"""
3367db96d56Sopenharmony_ci        raise NotImplementedError
3377db96d56Sopenharmony_ci
3387db96d56Sopenharmony_ci    @abstractmethod
3397db96d56Sopenharmony_ci    def __rrshift__(self, other):
3407db96d56Sopenharmony_ci        """other >> self"""
3417db96d56Sopenharmony_ci        raise NotImplementedError
3427db96d56Sopenharmony_ci
3437db96d56Sopenharmony_ci    @abstractmethod
3447db96d56Sopenharmony_ci    def __and__(self, other):
3457db96d56Sopenharmony_ci        """self & other"""
3467db96d56Sopenharmony_ci        raise NotImplementedError
3477db96d56Sopenharmony_ci
3487db96d56Sopenharmony_ci    @abstractmethod
3497db96d56Sopenharmony_ci    def __rand__(self, other):
3507db96d56Sopenharmony_ci        """other & self"""
3517db96d56Sopenharmony_ci        raise NotImplementedError
3527db96d56Sopenharmony_ci
3537db96d56Sopenharmony_ci    @abstractmethod
3547db96d56Sopenharmony_ci    def __xor__(self, other):
3557db96d56Sopenharmony_ci        """self ^ other"""
3567db96d56Sopenharmony_ci        raise NotImplementedError
3577db96d56Sopenharmony_ci
3587db96d56Sopenharmony_ci    @abstractmethod
3597db96d56Sopenharmony_ci    def __rxor__(self, other):
3607db96d56Sopenharmony_ci        """other ^ self"""
3617db96d56Sopenharmony_ci        raise NotImplementedError
3627db96d56Sopenharmony_ci
3637db96d56Sopenharmony_ci    @abstractmethod
3647db96d56Sopenharmony_ci    def __or__(self, other):
3657db96d56Sopenharmony_ci        """self | other"""
3667db96d56Sopenharmony_ci        raise NotImplementedError
3677db96d56Sopenharmony_ci
3687db96d56Sopenharmony_ci    @abstractmethod
3697db96d56Sopenharmony_ci    def __ror__(self, other):
3707db96d56Sopenharmony_ci        """other | self"""
3717db96d56Sopenharmony_ci        raise NotImplementedError
3727db96d56Sopenharmony_ci
3737db96d56Sopenharmony_ci    @abstractmethod
3747db96d56Sopenharmony_ci    def __invert__(self):
3757db96d56Sopenharmony_ci        """~self"""
3767db96d56Sopenharmony_ci        raise NotImplementedError
3777db96d56Sopenharmony_ci
3787db96d56Sopenharmony_ci    # Concrete implementations of Rational and Real abstract methods.
3797db96d56Sopenharmony_ci    def __float__(self):
3807db96d56Sopenharmony_ci        """float(self) == float(int(self))"""
3817db96d56Sopenharmony_ci        return float(int(self))
3827db96d56Sopenharmony_ci
3837db96d56Sopenharmony_ci    @property
3847db96d56Sopenharmony_ci    def numerator(self):
3857db96d56Sopenharmony_ci        """Integers are their own numerators."""
3867db96d56Sopenharmony_ci        return +self
3877db96d56Sopenharmony_ci
3887db96d56Sopenharmony_ci    @property
3897db96d56Sopenharmony_ci    def denominator(self):
3907db96d56Sopenharmony_ci        """Integers have a denominator of 1."""
3917db96d56Sopenharmony_ci        return 1
3927db96d56Sopenharmony_ci
3937db96d56Sopenharmony_ciIntegral.register(int)
394