This action will force synchronization from OpenHarmony-SIG/python, which will overwrite any changes that you have made since you forked the repository, and can not be recovered!!!
Synchronous operation will process in the background and will refresh the page when finishing processing. Please be patient.
# Originally contributed by Sjoerd Mullender.# Significantly modified by Jeffrey Yasskin <jyasskin at gmail.com>."""Fraction, infinite-precision, real numbers."""from decimal import Decimalimport mathimport numbersimport operatorimport reimport sys__all__ = ['Fraction', 'gcd']def gcd(a, b):"""Calculate the Greatest Common Divisor of a and b.Unless b==0, the result will have the same sign as b (so that whenb is divided by it, the result comes out positive)."""import warningswarnings.warn('fractions.gcd() is deprecated. Use math.gcd() instead.',DeprecationWarning, 2)if type(a) is int is type(b):if (b or a) < 0:return -math.gcd(a, b)return math.gcd(a, b)return _gcd(a, b)def _gcd(a, b):# Supports non-integers for backward compatibility.while b:a, b = b, a%breturn a# Constants related to the hash implementation; hash(x) is based# on the reduction of x modulo the prime _PyHASH_MODULUS._PyHASH_MODULUS = sys.hash_info.modulus# Value to be used for rationals that reduce to infinity modulo# _PyHASH_MODULUS._PyHASH_INF = sys.hash_info.inf_RATIONAL_FORMAT = re.compile(r"""\A\s* # optional whitespace at the start, then(?P<sign>[-+]?) # an optional sign, then(?=\d|\.\d) # lookahead for digit or .digit(?P<num>\d*) # numerator (possibly empty)(?: # followed by(?:/(?P<denom>\d+))? # an optional denominator| # or(?:\.(?P<decimal>\d*))? # an optional fractional part(?:E(?P<exp>[-+]?\d+))? # and optional exponent)\s*\Z # and optional whitespace to finish""", re.VERBOSE | re.IGNORECASE)class Fraction(numbers.Rational):"""This class implements rational numbers.In the two-argument form of the constructor, Fraction(8, 6) willproduce a rational number equivalent to 4/3. Both arguments mustbe Rational. The numerator defaults to 0 and the denominatordefaults to 1 so that Fraction(3) == 3 and Fraction() == 0.Fractions can also be constructed from:- numeric strings similar to those accepted by thefloat constructor (for example, '-2.3' or '1e10')- strings of the form '123/456'- float and Decimal instances- other Rational instances (including integers)"""__slots__ = ('_numerator', '_denominator')# We're immutable, so use __new__ not __init__def __new__(cls, numerator=0, denominator=None, *, _normalize=True):"""Constructs a Rational.Takes a string like '3/2' or '1.5', another Rational instance, anumerator/denominator pair, or a float.Examples-------->>> Fraction(10, -8)Fraction(-5, 4)>>> Fraction(Fraction(1, 7), 5)Fraction(1, 35)>>> Fraction(Fraction(1, 7), Fraction(2, 3))Fraction(3, 14)>>> Fraction('314')Fraction(314, 1)>>> Fraction('-35/4')Fraction(-35, 4)>>> Fraction('3.1415') # conversion from numeric stringFraction(6283, 2000)>>> Fraction('-47e-2') # string may include a decimal exponentFraction(-47, 100)>>> Fraction(1.47) # direct construction from float (exact conversion)Fraction(6620291452234629, 4503599627370496)>>> Fraction(2.25)Fraction(9, 4)>>> Fraction(Decimal('1.47'))Fraction(147, 100)"""self = super(Fraction, cls).__new__(cls)if denominator is None:if type(numerator) is int:self._numerator = numeratorself._denominator = 1return selfelif isinstance(numerator, numbers.Rational):self._numerator = numerator.numeratorself._denominator = numerator.denominatorreturn selfelif isinstance(numerator, (float, Decimal)):# Exact conversionself._numerator, self._denominator = numerator.as_integer_ratio()return selfelif isinstance(numerator, str):# Handle construction from strings.m = _RATIONAL_FORMAT.match(numerator)if m is None:raise ValueError('Invalid literal for Fraction: %r' %numerator)numerator = int(m.group('num') or '0')denom = m.group('denom')if denom:denominator = int(denom)else:denominator = 1decimal = m.group('decimal')if decimal:scale = 10**len(decimal)numerator = numerator * scale + int(decimal)denominator *= scaleexp = m.group('exp')if exp:exp = int(exp)if exp >= 0:numerator *= 10**expelse:denominator *= 10**-expif m.group('sign') == '-':numerator = -numeratorelse:raise TypeError("argument should be a string ""or a Rational instance")elif type(numerator) is int is type(denominator):pass # *very* normal caseelif (isinstance(numerator, numbers.Rational) andisinstance(denominator, numbers.Rational)):numerator, denominator = (numerator.numerator * denominator.denominator,denominator.numerator * numerator.denominator)else:raise TypeError("both arguments should be ""Rational instances")if denominator == 0:raise ZeroDivisionError('Fraction(%s, 0)' % numerator)if _normalize:if type(numerator) is int is type(denominator):# *very* normal caseg = math.gcd(numerator, denominator)if denominator < 0:g = -gelse:g = _gcd(numerator, denominator)numerator //= gdenominator //= gself._numerator = numeratorself._denominator = denominatorreturn self@classmethoddef from_float(cls, f):"""Converts a finite float to a rational number, exactly.Beware that Fraction.from_float(0.3) != Fraction(3, 10)."""if isinstance(f, numbers.Integral):return cls(f)elif not isinstance(f, float):raise TypeError("%s.from_float() only takes floats, not %r (%s)" %(cls.__name__, f, type(f).__name__))return cls(*f.as_integer_ratio())@classmethoddef from_decimal(cls, dec):"""Converts a finite Decimal instance to a rational number, exactly."""from decimal import Decimalif isinstance(dec, numbers.Integral):dec = Decimal(int(dec))elif not isinstance(dec, Decimal):raise TypeError("%s.from_decimal() only takes Decimals, not %r (%s)" %(cls.__name__, dec, type(dec).__name__))return cls(*dec.as_integer_ratio())def as_integer_ratio(self):"""Return the integer ratio as a tuple.Return a tuple of two integers, whose ratio is equal to theFraction and with a positive denominator."""return (self._numerator, self._denominator)def limit_denominator(self, max_denominator=1000000):"""Closest Fraction to self with denominator at most max_denominator.>>> Fraction('3.141592653589793').limit_denominator(10)Fraction(22, 7)>>> Fraction('3.141592653589793').limit_denominator(100)Fraction(311, 99)>>> Fraction(4321, 8765).limit_denominator(10000)Fraction(4321, 8765)"""# Algorithm notes: For any real number x, define a *best upper# approximation* to x to be a rational number p/q such that:## (1) p/q >= x, and# (2) if p/q > r/s >= x then s > q, for any rational r/s.## Define *best lower approximation* similarly. Then it can be# proved that a rational number is a best upper or lower# approximation to x if, and only if, it is a convergent or# semiconvergent of the (unique shortest) continued fraction# associated to x.## To find a best rational approximation with denominator <= M,# we find the best upper and lower approximations with# denominator <= M and take whichever of these is closer to x.# In the event of a tie, the bound with smaller denominator is# chosen. If both denominators are equal (which can happen# only when max_denominator == 1 and self is midway between# two integers) the lower bound---i.e., the floor of self, is# taken.if max_denominator < 1:raise ValueError("max_denominator should be at least 1")if self._denominator <= max_denominator:return Fraction(self)p0, q0, p1, q1 = 0, 1, 1, 0n, d = self._numerator, self._denominatorwhile True:a = n//dq2 = q0+a*q1if q2 > max_denominator:breakp0, q0, p1, q1 = p1, q1, p0+a*p1, q2n, d = d, n-a*dk = (max_denominator-q0)//q1bound1 = Fraction(p0+k*p1, q0+k*q1)bound2 = Fraction(p1, q1)if abs(bound2 - self) <= abs(bound1-self):return bound2else:return bound1@propertydef numerator(a):return a._numerator@propertydef denominator(a):return a._denominatordef __repr__(self):"""repr(self)"""return '%s(%s, %s)' % (self.__class__.__name__,self._numerator, self._denominator)def __str__(self):"""str(self)"""if self._denominator == 1:return str(self._numerator)else:return '%s/%s' % (self._numerator, self._denominator)def _operator_fallbacks(monomorphic_operator, fallback_operator):"""Generates forward and reverse operators given a purely-rationaloperator and a function from the operator module.Use this like:__op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op)In general, we want to implement the arithmetic operations sothat mixed-mode operations either call an implementation whoseauthor knew about the types of both arguments, or convert bothto the nearest built in type and do the operation there. InFraction, that means that we define __add__ and __radd__ as:def __add__(self, other):# Both types have numerators/denominator attributes,# so do the operation directlyif isinstance(other, (int, Fraction)):return Fraction(self.numerator * other.denominator +other.numerator * self.denominator,self.denominator * other.denominator)# float and complex don't have those operations, but we# know about those types, so special case them.elif isinstance(other, float):return float(self) + otherelif isinstance(other, complex):return complex(self) + other# Let the other type take over.return NotImplementeddef __radd__(self, other):# radd handles more types than add because there's# nothing left to fall back to.if isinstance(other, numbers.Rational):return Fraction(self.numerator * other.denominator +other.numerator * self.denominator,self.denominator * other.denominator)elif isinstance(other, Real):return float(other) + float(self)elif isinstance(other, Complex):return complex(other) + complex(self)return NotImplementedThere are 5 different cases for a mixed-type addition onFraction. I'll refer to all of the above code that doesn'trefer to Fraction, float, or complex as "boilerplate". 'r'will be an instance of Fraction, which is a subtype ofRational (r : Fraction <: Rational), and b : B <:Complex. The first three involve 'r + b':1. If B <: Fraction, int, float, or complex, we handlethat specially, and all is well.2. If Fraction falls back to the boilerplate code, and itwere to return a value from __add__, we'd miss thepossibility that B defines a more intelligent __radd__,so the boilerplate should return NotImplemented from__add__. In particular, we don't handle Rationalhere, even though we could get an exact answer, in casethe other type wants to do something special.3. If B <: Fraction, Python tries B.__radd__ beforeFraction.__add__. This is ok, because it wasimplemented with knowledge of Fraction, so it canhandle those instances before delegating to Real orComplex.The next two situations describe 'b + r'. We assume that bdidn't know about Fraction in its implementation, and that ituses similar boilerplate code:4. If B <: Rational, then __radd_ converts both to thebuiltin rational type (hey look, that's us) andproceeds.5. Otherwise, __radd__ tries to find the nearest commonbase ABC, and fall back to its builtin type. Since thisclass doesn't subclass a concrete type, there's noimplementation to fall back to, so we need to try ashard as possible to return an actual value, or the userwill get a TypeError."""def forward(a, b):if isinstance(b, (int, Fraction)):return monomorphic_operator(a, b)elif isinstance(b, float):return fallback_operator(float(a), b)elif isinstance(b, complex):return fallback_operator(complex(a), b)else:return NotImplementedforward.__name__ = '__' + fallback_operator.__name__ + '__'forward.__doc__ = monomorphic_operator.__doc__def reverse(b, a):if isinstance(a, numbers.Rational):# Includes ints.return monomorphic_operator(a, b)elif isinstance(a, numbers.Real):return fallback_operator(float(a), float(b))elif isinstance(a, numbers.Complex):return fallback_operator(complex(a), complex(b))else:return NotImplementedreverse.__name__ = '__r' + fallback_operator.__name__ + '__'reverse.__doc__ = monomorphic_operator.__doc__return forward, reversedef _add(a, b):"""a + b"""da, db = a.denominator, b.denominatorreturn Fraction(a.numerator * db + b.numerator * da,da * db)__add__, __radd__ = _operator_fallbacks(_add, operator.add)def _sub(a, b):"""a - b"""da, db = a.denominator, b.denominatorreturn Fraction(a.numerator * db - b.numerator * da,da * db)__sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)def _mul(a, b):"""a * b"""return Fraction(a.numerator * b.numerator, a.denominator * b.denominator)__mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul)def _div(a, b):"""a / b"""return Fraction(a.numerator * b.denominator,a.denominator * b.numerator)__truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)def _floordiv(a, b):"""a // b"""return (a.numerator * b.denominator) // (a.denominator * b.numerator)__floordiv__, __rfloordiv__ = _operator_fallbacks(_floordiv, operator.floordiv)def _divmod(a, b):"""(a // b, a % b)"""da, db = a.denominator, b.denominatordiv, n_mod = divmod(a.numerator * db, da * b.numerator)return div, Fraction(n_mod, da * db)__divmod__, __rdivmod__ = _operator_fallbacks(_divmod, divmod)def _mod(a, b):"""a % b"""da, db = a.denominator, b.denominatorreturn Fraction((a.numerator * db) % (b.numerator * da), da * db)__mod__, __rmod__ = _operator_fallbacks(_mod, operator.mod)def __pow__(a, b):"""a ** bIf b is not an integer, the result will be a float or complexsince roots are generally irrational. If b is an integer, theresult will be rational."""if isinstance(b, numbers.Rational):if b.denominator == 1:power = b.numeratorif power >= 0:return Fraction(a._numerator ** power,a._denominator ** power,_normalize=False)elif a._numerator >= 0:return Fraction(a._denominator ** -power,a._numerator ** -power,_normalize=False)else:return Fraction((-a._denominator) ** -power,(-a._numerator) ** -power,_normalize=False)else:# A fractional power will generally produce an# irrational number.return float(a) ** float(b)else:return float(a) ** bdef __rpow__(b, a):"""a ** b"""if b._denominator == 1 and b._numerator >= 0:# If a is an int, keep it that way if possible.return a ** b._numeratorif isinstance(a, numbers.Rational):return Fraction(a.numerator, a.denominator) ** bif b._denominator == 1:return a ** b._numeratorreturn a ** float(b)def __pos__(a):"""+a: Coerces a subclass instance to Fraction"""return Fraction(a._numerator, a._denominator, _normalize=False)def __neg__(a):"""-a"""return Fraction(-a._numerator, a._denominator, _normalize=False)def __abs__(a):"""abs(a)"""return Fraction(abs(a._numerator), a._denominator, _normalize=False)def __trunc__(a):"""trunc(a)"""if a._numerator < 0:return -(-a._numerator // a._denominator)else:return a._numerator // a._denominatordef __floor__(a):"""math.floor(a)"""return a.numerator // a.denominatordef __ceil__(a):"""math.ceil(a)"""# The negations cleverly convince floordiv to return the ceiling.return -(-a.numerator // a.denominator)def __round__(self, ndigits=None):"""round(self, ndigits)Rounds half toward even."""if ndigits is None:floor, remainder = divmod(self.numerator, self.denominator)if remainder * 2 < self.denominator:return floorelif remainder * 2 > self.denominator:return floor + 1# Deal with the half case:elif floor % 2 == 0:return floorelse:return floor + 1shift = 10**abs(ndigits)# See _operator_fallbacks.forward to check that the results of# these operations will always be Fraction and therefore have# round().if ndigits > 0:return Fraction(round(self * shift), shift)else:return Fraction(round(self / shift) * shift)def __hash__(self):"""hash(self)"""# XXX since this method is expensive, consider caching the result# In order to make sure that the hash of a Fraction agrees# with the hash of a numerically equal integer, float or# Decimal instance, we follow the rules for numeric hashes# outlined in the documentation. (See library docs, 'Built-in# Types').# dinv is the inverse of self._denominator modulo the prime# _PyHASH_MODULUS, or 0 if self._denominator is divisible by# _PyHASH_MODULUS.dinv = pow(self._denominator, _PyHASH_MODULUS - 2, _PyHASH_MODULUS)if not dinv:hash_ = _PyHASH_INFelse:hash_ = abs(self._numerator) * dinv % _PyHASH_MODULUSresult = hash_ if self >= 0 else -hash_return -2 if result == -1 else resultdef __eq__(a, b):"""a == b"""if type(b) is int:return a._numerator == b and a._denominator == 1if isinstance(b, numbers.Rational):return (a._numerator == b.numerator anda._denominator == b.denominator)if isinstance(b, numbers.Complex) and b.imag == 0:b = b.realif isinstance(b, float):if math.isnan(b) or math.isinf(b):# comparisons with an infinity or nan should behave in# the same way for any finite a, so treat a as zero.return 0.0 == belse:return a == a.from_float(b)else:# Since a doesn't know how to compare with b, let's give b# a chance to compare itself with a.return NotImplementeddef _richcmp(self, other, op):"""Helper for comparison operators, for internal use only.Implement comparison between a Rational instance `self`, andeither another Rational instance or a float `other`. If`other` is not a Rational instance or a float, returnNotImplemented. `op` should be one of the six standardcomparison operators."""# convert other to a Rational instance where reasonable.if isinstance(other, numbers.Rational):return op(self._numerator * other.denominator,self._denominator * other.numerator)if isinstance(other, float):if math.isnan(other) or math.isinf(other):return op(0.0, other)else:return op(self, self.from_float(other))else:return NotImplementeddef __lt__(a, b):"""a < b"""return a._richcmp(b, operator.lt)def __gt__(a, b):"""a > b"""return a._richcmp(b, operator.gt)def __le__(a, b):"""a <= b"""return a._richcmp(b, operator.le)def __ge__(a, b):"""a >= b"""return a._richcmp(b, operator.ge)def __bool__(a):"""a != 0"""# bpo-39274: Use bool() because (a._numerator != 0) can return an# object which is not a bool.return bool(a._numerator)# support for pickling, copy, and deepcopydef __reduce__(self):return (self.__class__, (str(self),))def __copy__(self):if type(self) == Fraction:return self # I'm immutable; therefore I am my own clonereturn self.__class__(self._numerator, self._denominator)def __deepcopy__(self, memo):if type(self) == Fraction:return self # My components are also immutablereturn self.__class__(self._numerator, self._denominator)
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。