--- a/Lib/_pydecimal.py Tue Nov 08 23:14:00 2016 +0200 |
+++ b/Lib/_pydecimal.py Thu Dec 01 13:45:41 2016 -0800 |
@@ -527,6 +527,26 @@ |
return +s # Convert result to normal context |
>>> setcontext(DefaultContext) |
+ >>> print(getcontext().prec) # Return a context manager for a copy of the supplied context |
+ |
+ Uses a copy of the current context if no context is specified |
+ The returned context manager creates a local decimal context |
+ in a with statement: |
+ def sin(x): |
+ with localcontext() as ctx: |
+ ctx.prec += 2 |
+ # Rest of sin calculation algorithm |
+ # uses a precision 2 greater than normal |
+ return +s # Convert result to normal precision |
+ |
+ def sin(x): |
+ with localcontext(ExtendedContext): |
+ # Rest of sin calculation algorithm |
+ # uses the Extended Context from the |
+ # General Decimal Arithmetic Specification |
+ return +s # Convert result to normal context |
+ |
+ >>> setcontext(DefaultContext) |
>>> print(getcontext().prec) |
28 |
>>> with localcontext(): |
@@ -541,6 +561,19 @@ |
9 |
>>> print(getcontext().prec) |
28 |
+ 28 |
+ >>> with localcontext(): |
+ ... ctx = getcontext() |
+ ... ctx.prec += 2 |
+ ... print(ctx.prec) |
+ ... |
+ 30 |
+ >>> with localcontext(ExtendedContext): |
+ ... print(getcontext().prec) |
+ ... |
+ 9 |
+ >>> print(getcontext().prec) |
+ 28 |
""" |
if ctx is None: ctx = getcontext() |
return _ContextManager(ctx) |
@@ -572,7 +605,7 @@ |
Decimal('314') |
>>> Decimal(Decimal(314)) # another decimal instance |
Decimal('314') |
- >>> Decimal(' 3.14 \\n') # leading and trailing whitespace okay |
+ >>> Decimal(' 3.14 \\n') # leading and trailing whitespace okay |
Decimal('3.14') |
""" |
@@ -1004,17 +1037,18 @@ |
return -2 if ans == -1 else ans |
def as_tuple(self): |
- """Represents the number as a triple tuple. |
- |
- To show the internals exactly as they are. |
+ """Represents the number as a triple tuple, to show the internals |
+ exactly as they are. |
""" |
return DecimalTuple(self._sign, tuple(map(int, self._int)), self._exp) |
def as_integer_ratio(self): |
"""Express a finite Decimal instance in the form n / d. |
- Returns a pair (n, d) of integers. When called on an infinity |
- or NaN, raises OverflowError or ValueError respectively. |
+ Return a pair (n, d) of integers, whose ratio is exactly equal to the |
+ original Decimal and with a positive denominator. The ratio is in |
+ lowest terms. Raise OverflowError on infinities and a ValueError |
+ on NaNs. |
>>> Decimal('3.14').as_integer_ratio() |
(157, 50) |
@@ -2942,7 +2976,10 @@ |
return self._int[-1+self._exp] in '02468' |
def adjusted(self): |
- """Return the adjusted exponent of self""" |
+ """Return the adjusted exponent of self. |
+ |
+ Defined as exp + digits - 1. |
+ """ |
try: |
return self._exp + len(self._int) - 1 |
# If NaN or Infinity, self._exp is string |
@@ -2950,10 +2987,10 @@ |
return 0 |
def canonical(self): |
- """Returns the same Decimal object. |
- |
- As we do not have different encodings for the same number, the |
- received object already is in its canonical form. |
+ """Return the canonical encoding of the argument. |
+ |
+ Currently, the encoding of a Decimal instance is always canonical, |
+ so this operation returns its argument unchanged. |
""" |
return self |
@@ -3094,7 +3131,7 @@ |
return Decimal(self) |
# the result is now guaranteed to be inexact (the true |
- # mathematical result is transcendental). There's no need to |
+ # mathematical is transcendental). There's no need to |
# raise Rounded and Inexact here---they'll always be raised as |
# a result of the call to _fix. |
p = context.prec |
@@ -4235,6 +4272,11 @@ |
subtraction: '-1' if the result is less than zero, '0' if the result is |
zero or negative zero, or '1' if the result is greater than zero. |
+ a or b is a NaN ==> Decimal('NaN') |
+ a < b ==> Decimal('-1') |
+ a == b ==> Decimal('0') |
+ a > b ==> Decimal('1') |
+ |
>>> ExtendedContext.compare(Decimal('2.1'), Decimal('3')) |
Decimal('-1') |
>>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1')) |
@@ -4253,6 +4295,8 @@ |
Decimal('-1') |
>>> ExtendedContext.compare(1, Decimal(2)) |
Decimal('-1') |
+ >>> ExtendedContext.compare(Decimal('2'), Decimal('NaN')) |
+ Decimal('NaN') |
""" |
a = _convert_other(a, raiseit=True) |
return a.compare(b, context=self) |
@@ -4263,41 +4307,50 @@ |
It's pretty much like compare(), but all NaNs signal, with signaling |
NaNs taking precedence over quiet NaNs. |
- >>> c = ExtendedContext |
- >>> c.compare_signal(Decimal('2.1'), Decimal('3')) |
+ >>> ExtendedContext.compare_signal(Decimal('2.1'), Decimal('3')) |
Decimal('-1') |
- >>> c.compare_signal(Decimal('2.1'), Decimal('2.1')) |
+ >>> ExtendedContext.compare_signal(Decimal('2.1'), Decimal('2.1')) |
Decimal('0') |
- >>> c.flags[InvalidOperation] = 0 |
- >>> print(c.flags[InvalidOperation]) |
+ >>> ExtendedContext.flags[InvalidOperation] = 0 |
+ >>> print(ExtendedContext.flags[InvalidOperation]) |
0 |
- >>> c.compare_signal(Decimal('NaN'), Decimal('2.1')) |
+ >>> ExtendedContext.compare_signal(Decimal('NaN'), Decimal('2.1')) |
Decimal('NaN') |
- >>> print(c.flags[InvalidOperation]) |
+ >>> print(ExtendedContext.flags[InvalidOperation]) |
1 |
- >>> c.flags[InvalidOperation] = 0 |
- >>> print(c.flags[InvalidOperation]) |
+ >>> ExtendedContext.flags[InvalidOperation] = 0 |
+ >>> print(ExtendedContext.flags[InvalidOperation]) |
0 |
- >>> c.compare_signal(Decimal('sNaN'), Decimal('2.1')) |
+ >>> ExtendedContext.compare_signal(Decimal('sNaN'), Decimal('2.1')) |
Decimal('NaN') |
- >>> print(c.flags[InvalidOperation]) |
+ >>> print(ExtendedContext.flags[InvalidOperation]) |
1 |
- >>> c.compare_signal(-1, 2) |
+ >>> ExtendedContext.compare_signal(-1, 2) |
Decimal('-1') |
- >>> c.compare_signal(Decimal(-1), 2) |
+ >>> ExtendedContext.compare_signal(Decimal(-1), 2) |
Decimal('-1') |
- >>> c.compare_signal(-1, Decimal(2)) |
+ >>> ExtendedContext.compare_signal(-1, Decimal(2)) |
Decimal('-1') |
""" |
a = _convert_other(a, raiseit=True) |
return a.compare_signal(b, context=self) |
def compare_total(self, a, b): |
- """Compares two operands using their abstract representation. |
- |
- This is not like the standard compare, which use their numerical |
- value. Note that a total ordering is defined for all possible abstract |
- representations. |
+ """Compares two operands using their abstract representation rather |
+ than their numerical value. |
+ |
+ Similar to the compare() method, but the result gives a total ordering |
+ on Decimal instances. |
+ |
+ Quiet and signaling NaNs are also included in the total ordering. |
+ The result of this function is Decimal('0') if both operands have the |
+ same representation, Decimal('-1') if the first operand is lower in |
+ the total order than the second, and Decimal('1') if the first |
+ operand is higher in the total order than the second operand. See |
+ the specification for details of the total order. |
+ |
+ This operation is unaffected by context and is quiet: no flags are |
+ changed and no rounding is performed. |
>>> ExtendedContext.compare_total(Decimal('12.73'), Decimal('127.9')) |
Decimal('-1') |
@@ -4322,9 +4375,15 @@ |
return a.compare_total(b) |
def compare_total_mag(self, a, b): |
- """Compares two operands using their abstract representation ignoring sign. |
- |
- Like compare_total, but with operand's sign ignored and assumed to be 0. |
+ """Compares two operands using their abstract representation rather |
+ than their numerical value and with their sign ignored. |
+ |
+ Like compare_total, but with operand's sign ignored and assumed to be |
+ 0. |
+ |
+ x.compare_total_mag(y) is equivalent to x.copy_abs().compare_total(y.copy_abs()) |
+ This operation is unaffected by context and is quiet: no flags are |
+ changed and no rounding is performed. |
""" |
a = _convert_other(a, raiseit=True) |
return a.compare_total_mag(b) |
@@ -4369,10 +4428,8 @@ |
return a.copy_negate() |
def copy_sign(self, a, b): |
- """Copies the second operand's sign to the first one. |
- |
- In detail, it returns a copy of the first operand with the sign |
- equal to the sign of the second operand. |
+ """Returns a copy of the first operand with the sign equal to the second |
+ operand. |
>>> ExtendedContext.copy_sign(Decimal( '1.50'), Decimal('7.33')) |
Decimal('1.50') |
@@ -4388,6 +4445,9 @@ |
Decimal('-1') |
>>> ExtendedContext.copy_sign(1, Decimal(-2)) |
Decimal('-1') |
+ |
+ This operation is unaffected by context and is quiet: no flags are |
+ changed and no rounding is performed. |
""" |
a = _convert_other(a, raiseit=True) |
return a.copy_sign(b) |
@@ -4474,7 +4534,9 @@ |
return r |
def exp(self, a): |
- """Returns e ** a. |
+ """Return the value of the (natural) exponential function e ** a. |
+ The function always uses the ROUND_HALF_EVEN mode and the result |
+ is correctly rounded. |
>>> c = ExtendedContext.copy() |
>>> c.Emin = -999 |
@@ -4500,8 +4562,8 @@ |
def fma(self, a, b, c): |
"""Returns a multiplied by b, plus c. |
- The first two operands are multiplied together, using multiply, |
- the third operand is then added to the result of that |
+ Fused multiple-add. The first two operands are multiplied together, |
+ using multiply, the third operand is then added to the result of that |
multiplication, using add, all with only one final rounding. |
>>> ExtendedContext.fma(Decimal('3'), Decimal('5'), Decimal('7')) |
@@ -4571,7 +4633,7 @@ |
return a.is_infinite() |
def is_nan(self, a): |
- """Return True if the operand is a qNaN or sNaN; |
+ """Return True if the operand is a (quiet or signaling) NaN or NaN; |
otherwise return False. |
>>> ExtendedContext.is_nan(Decimal('2.50')) |
@@ -4627,6 +4689,8 @@ |
def is_signed(self, a): |
"""Return True if the operand is negative; otherwise return False. |
+ Note that both zeros and NaNs can carry signs. |
+ |
>>> ExtendedContext.is_signed(Decimal('2.50')) |
False |
>>> ExtendedContext.is_signed(Decimal('-12')) |
@@ -4660,6 +4724,9 @@ |
def is_subnormal(self, a): |
"""Return True if the operand is subnormal; otherwise return False. |
+ A number is subnormal if it is non-zero, finite, and has an adjusted |
+ exponent less than Emin. |
+ |
>>> c = ExtendedContext.copy() |
>>> c.Emin = -999 |
>>> c.Emax = 999 |
@@ -4699,6 +4766,9 @@ |
def ln(self, a): |
"""Returns the natural (base e) logarithm of the operand. |
+ The function always uses the ROUND_HALF_EVEN mode and the result is |
+ correctly rounded. |
+ |
>>> c = ExtendedContext.copy() |
>>> c.Emin = -999 |
>>> c.Emax = 999 |
@@ -4721,6 +4791,9 @@ |
def log10(self, a): |
"""Returns the base 10 logarithm of the operand. |
+ The function always uses the ROUND_HALF_EVEN mode and the result |
+ is correctly rounded. |
+ |
>>> c = ExtendedContext.copy() |
>>> c.Emin = -999 |
>>> c.Emax = 999 |
@@ -4747,7 +4820,7 @@ |
return a.log10(context=self) |
def logb(self, a): |
- """ Returns the exponent of the magnitude of the operand's MSD. |
+ """Returns the exponent of the magnitude of the operand's MSD. |
The result is the integer which is the exponent of the magnitude |
of the most significant digit of the operand (as though the |
@@ -5314,7 +5387,8 @@ |
return a.quantize(b, context=self) |
def radix(self): |
- """Just returns 10, as this is Decimal, :) |
+ """Return Decimal(10), the radix (base) in which the Decimal class does |
+ all its arithmetic. Included for compatibility with the specification. |
>>> ExtendedContext.radix() |
Decimal('10') |