PageRenderTime 1001ms CodeModel.GetById 242ms app.highlight 437ms RepoModel.GetById 227ms app.codeStats 2ms

/Lib/decimal.py

http://unladen-swallow.googlecode.com/
Python | 5521 lines | 5489 code | 4 blank | 28 comment | 14 complexity | a2fb9fedfd7e1dd04d8d7dd11cdfca13 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1# Copyright (c) 2004 Python Software Foundation.
   2# All rights reserved.
   3
   4# Written by Eric Price <eprice at tjhsst.edu>
   5#    and Facundo Batista <facundo at taniquetil.com.ar>
   6#    and Raymond Hettinger <python at rcn.com>
   7#    and Aahz <aahz at pobox.com>
   8#    and Tim Peters
   9
  10# This module is currently Py2.3 compatible and should be kept that way
  11# unless a major compelling advantage arises.  IOW, 2.3 compatibility is
  12# strongly preferred, but not guaranteed.
  13
  14# Also, this module should be kept in sync with the latest updates of
  15# the IBM specification as it evolves.  Those updates will be treated
  16# as bug fixes (deviation from the spec is a compatibility, usability
  17# bug) and will be backported.  At this point the spec is stabilizing
  18# and the updates are becoming fewer, smaller, and less significant.
  19
  20"""
  21This is a Py2.3 implementation of decimal floating point arithmetic based on
  22the General Decimal Arithmetic Specification:
  23
  24    www2.hursley.ibm.com/decimal/decarith.html
  25
  26and IEEE standard 854-1987:
  27
  28    www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html
  29
  30Decimal floating point has finite precision with arbitrarily large bounds.
  31
  32The purpose of this module is to support arithmetic using familiar
  33"schoolhouse" rules and to avoid some of the tricky representation
  34issues associated with binary floating point.  The package is especially
  35useful for financial applications or for contexts where users have
  36expectations that are at odds with binary floating point (for instance,
  37in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead
  38of the expected Decimal('0.00') returned by decimal floating point).
  39
  40Here are some examples of using the decimal module:
  41
  42>>> from decimal import *
  43>>> setcontext(ExtendedContext)
  44>>> Decimal(0)
  45Decimal('0')
  46>>> Decimal('1')
  47Decimal('1')
  48>>> Decimal('-.0123')
  49Decimal('-0.0123')
  50>>> Decimal(123456)
  51Decimal('123456')
  52>>> Decimal('123.45e12345678901234567890')
  53Decimal('1.2345E+12345678901234567892')
  54>>> Decimal('1.33') + Decimal('1.27')
  55Decimal('2.60')
  56>>> Decimal('12.34') + Decimal('3.87') - Decimal('18.41')
  57Decimal('-2.20')
  58>>> dig = Decimal(1)
  59>>> print dig / Decimal(3)
  600.333333333
  61>>> getcontext().prec = 18
  62>>> print dig / Decimal(3)
  630.333333333333333333
  64>>> print dig.sqrt()
  651
  66>>> print Decimal(3).sqrt()
  671.73205080756887729
  68>>> print Decimal(3) ** 123
  694.85192780976896427E+58
  70>>> inf = Decimal(1) / Decimal(0)
  71>>> print inf
  72Infinity
  73>>> neginf = Decimal(-1) / Decimal(0)
  74>>> print neginf
  75-Infinity
  76>>> print neginf + inf
  77NaN
  78>>> print neginf * inf
  79-Infinity
  80>>> print dig / 0
  81Infinity
  82>>> getcontext().traps[DivisionByZero] = 1
  83>>> print dig / 0
  84Traceback (most recent call last):
  85  ...
  86  ...
  87  ...
  88DivisionByZero: x / 0
  89>>> c = Context()
  90>>> c.traps[InvalidOperation] = 0
  91>>> print c.flags[InvalidOperation]
  920
  93>>> c.divide(Decimal(0), Decimal(0))
  94Decimal('NaN')
  95>>> c.traps[InvalidOperation] = 1
  96>>> print c.flags[InvalidOperation]
  971
  98>>> c.flags[InvalidOperation] = 0
  99>>> print c.flags[InvalidOperation]
 1000
 101>>> print c.divide(Decimal(0), Decimal(0))
 102Traceback (most recent call last):
 103  ...
 104  ...
 105  ...
 106InvalidOperation: 0 / 0
 107>>> print c.flags[InvalidOperation]
 1081
 109>>> c.flags[InvalidOperation] = 0
 110>>> c.traps[InvalidOperation] = 0
 111>>> print c.divide(Decimal(0), Decimal(0))
 112NaN
 113>>> print c.flags[InvalidOperation]
 1141
 115>>>
 116"""
 117
 118__all__ = [
 119    # Two major classes
 120    'Decimal', 'Context',
 121
 122    # Contexts
 123    'DefaultContext', 'BasicContext', 'ExtendedContext',
 124
 125    # Exceptions
 126    'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero',
 127    'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow',
 128
 129    # Constants for use in setting up contexts
 130    'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING',
 131    'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', 'ROUND_05UP',
 132
 133    # Functions for manipulating contexts
 134    'setcontext', 'getcontext', 'localcontext'
 135]
 136
 137import copy as _copy
 138import numbers as _numbers
 139
 140try:
 141    from collections import namedtuple as _namedtuple
 142    DecimalTuple = _namedtuple('DecimalTuple', 'sign digits exponent')
 143except ImportError:
 144    DecimalTuple = lambda *args: args
 145
 146# Rounding
 147ROUND_DOWN = 'ROUND_DOWN'
 148ROUND_HALF_UP = 'ROUND_HALF_UP'
 149ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
 150ROUND_CEILING = 'ROUND_CEILING'
 151ROUND_FLOOR = 'ROUND_FLOOR'
 152ROUND_UP = 'ROUND_UP'
 153ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
 154ROUND_05UP = 'ROUND_05UP'
 155
 156# Errors
 157
 158class DecimalException(ArithmeticError):
 159    """Base exception class.
 160
 161    Used exceptions derive from this.
 162    If an exception derives from another exception besides this (such as
 163    Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
 164    called if the others are present.  This isn't actually used for
 165    anything, though.
 166
 167    handle  -- Called when context._raise_error is called and the
 168               trap_enabler is set.  First argument is self, second is the
 169               context.  More arguments can be given, those being after
 170               the explanation in _raise_error (For example,
 171               context._raise_error(NewError, '(-x)!', self._sign) would
 172               call NewError().handle(context, self._sign).)
 173
 174    To define a new exception, it should be sufficient to have it derive
 175    from DecimalException.
 176    """
 177    def handle(self, context, *args):
 178        pass
 179
 180
 181class Clamped(DecimalException):
 182    """Exponent of a 0 changed to fit bounds.
 183
 184    This occurs and signals clamped if the exponent of a result has been
 185    altered in order to fit the constraints of a specific concrete
 186    representation.  This may occur when the exponent of a zero result would
 187    be outside the bounds of a representation, or when a large normal
 188    number would have an encoded exponent that cannot be represented.  In
 189    this latter case, the exponent is reduced to fit and the corresponding
 190    number of zero digits are appended to the coefficient ("fold-down").
 191    """
 192
 193class InvalidOperation(DecimalException):
 194    """An invalid operation was performed.
 195
 196    Various bad things cause this:
 197
 198    Something creates a signaling NaN
 199    -INF + INF
 200    0 * (+-)INF
 201    (+-)INF / (+-)INF
 202    x % 0
 203    (+-)INF % x
 204    x._rescale( non-integer )
 205    sqrt(-x) , x > 0
 206    0 ** 0
 207    x ** (non-integer)
 208    x ** (+-)INF
 209    An operand is invalid
 210
 211    The result of the operation after these is a quiet positive NaN,
 212    except when the cause is a signaling NaN, in which case the result is
 213    also a quiet NaN, but with the original sign, and an optional
 214    diagnostic information.
 215    """
 216    def handle(self, context, *args):
 217        if args:
 218            ans = _dec_from_triple(args[0]._sign, args[0]._int, 'n', True)
 219            return ans._fix_nan(context)
 220        return _NaN
 221
 222class ConversionSyntax(InvalidOperation):
 223    """Trying to convert badly formed string.
 224
 225    This occurs and signals invalid-operation if an string is being
 226    converted to a number and it does not conform to the numeric string
 227    syntax.  The result is [0,qNaN].
 228    """
 229    def handle(self, context, *args):
 230        return _NaN
 231
 232class DivisionByZero(DecimalException, ZeroDivisionError):
 233    """Division by 0.
 234
 235    This occurs and signals division-by-zero if division of a finite number
 236    by zero was attempted (during a divide-integer or divide operation, or a
 237    power operation with negative right-hand operand), and the dividend was
 238    not zero.
 239
 240    The result of the operation is [sign,inf], where sign is the exclusive
 241    or of the signs of the operands for divide, or is 1 for an odd power of
 242    -0, for power.
 243    """
 244
 245    def handle(self, context, sign, *args):
 246        return _SignedInfinity[sign]
 247
 248class DivisionImpossible(InvalidOperation):
 249    """Cannot perform the division adequately.
 250
 251    This occurs and signals invalid-operation if the integer result of a
 252    divide-integer or remainder operation had too many digits (would be
 253    longer than precision).  The result is [0,qNaN].
 254    """
 255
 256    def handle(self, context, *args):
 257        return _NaN
 258
 259class DivisionUndefined(InvalidOperation, ZeroDivisionError):
 260    """Undefined result of division.
 261
 262    This occurs and signals invalid-operation if division by zero was
 263    attempted (during a divide-integer, divide, or remainder operation), and
 264    the dividend is also zero.  The result is [0,qNaN].
 265    """
 266
 267    def handle(self, context, *args):
 268        return _NaN
 269
 270class Inexact(DecimalException):
 271    """Had to round, losing information.
 272
 273    This occurs and signals inexact whenever the result of an operation is
 274    not exact (that is, it needed to be rounded and any discarded digits
 275    were non-zero), or if an overflow or underflow condition occurs.  The
 276    result in all cases is unchanged.
 277
 278    The inexact signal may be tested (or trapped) to determine if a given
 279    operation (or sequence of operations) was inexact.
 280    """
 281
 282class InvalidContext(InvalidOperation):
 283    """Invalid context.  Unknown rounding, for example.
 284
 285    This occurs and signals invalid-operation if an invalid context was
 286    detected during an operation.  This can occur if contexts are not checked
 287    on creation and either the precision exceeds the capability of the
 288    underlying concrete representation or an unknown or unsupported rounding
 289    was specified.  These aspects of the context need only be checked when
 290    the values are required to be used.  The result is [0,qNaN].
 291    """
 292
 293    def handle(self, context, *args):
 294        return _NaN
 295
 296class Rounded(DecimalException):
 297    """Number got rounded (not  necessarily changed during rounding).
 298
 299    This occurs and signals rounded whenever the result of an operation is
 300    rounded (that is, some zero or non-zero digits were discarded from the
 301    coefficient), or if an overflow or underflow condition occurs.  The
 302    result in all cases is unchanged.
 303
 304    The rounded signal may be tested (or trapped) to determine if a given
 305    operation (or sequence of operations) caused a loss of precision.
 306    """
 307
 308class Subnormal(DecimalException):
 309    """Exponent < Emin before rounding.
 310
 311    This occurs and signals subnormal whenever the result of a conversion or
 312    operation is subnormal (that is, its adjusted exponent is less than
 313    Emin, before any rounding).  The result in all cases is unchanged.
 314
 315    The subnormal signal may be tested (or trapped) to determine if a given
 316    or operation (or sequence of operations) yielded a subnormal result.
 317    """
 318
 319class Overflow(Inexact, Rounded):
 320    """Numerical overflow.
 321
 322    This occurs and signals overflow if the adjusted exponent of a result
 323    (from a conversion or from an operation that is not an attempt to divide
 324    by zero), after rounding, would be greater than the largest value that
 325    can be handled by the implementation (the value Emax).
 326
 327    The result depends on the rounding mode:
 328
 329    For round-half-up and round-half-even (and for round-half-down and
 330    round-up, if implemented), the result of the operation is [sign,inf],
 331    where sign is the sign of the intermediate result.  For round-down, the
 332    result is the largest finite number that can be represented in the
 333    current precision, with the sign of the intermediate result.  For
 334    round-ceiling, the result is the same as for round-down if the sign of
 335    the intermediate result is 1, or is [0,inf] otherwise.  For round-floor,
 336    the result is the same as for round-down if the sign of the intermediate
 337    result is 0, or is [1,inf] otherwise.  In all cases, Inexact and Rounded
 338    will also be raised.
 339    """
 340
 341    def handle(self, context, sign, *args):
 342        if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN,
 343                                ROUND_HALF_DOWN, ROUND_UP):
 344            return _SignedInfinity[sign]
 345        if sign == 0:
 346            if context.rounding == ROUND_CEILING:
 347                return _SignedInfinity[sign]
 348            return _dec_from_triple(sign, '9'*context.prec,
 349                            context.Emax-context.prec+1)
 350        if sign == 1:
 351            if context.rounding == ROUND_FLOOR:
 352                return _SignedInfinity[sign]
 353            return _dec_from_triple(sign, '9'*context.prec,
 354                             context.Emax-context.prec+1)
 355
 356
 357class Underflow(Inexact, Rounded, Subnormal):
 358    """Numerical underflow with result rounded to 0.
 359
 360    This occurs and signals underflow if a result is inexact and the
 361    adjusted exponent of the result would be smaller (more negative) than
 362    the smallest value that can be handled by the implementation (the value
 363    Emin).  That is, the result is both inexact and subnormal.
 364
 365    The result after an underflow will be a subnormal number rounded, if
 366    necessary, so that its exponent is not less than Etiny.  This may result
 367    in 0 with the sign of the intermediate result and an exponent of Etiny.
 368
 369    In all cases, Inexact, Rounded, and Subnormal will also be raised.
 370    """
 371
 372# List of public traps and flags
 373_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded,
 374           Underflow, InvalidOperation, Subnormal]
 375
 376# Map conditions (per the spec) to signals
 377_condition_map = {ConversionSyntax:InvalidOperation,
 378                  DivisionImpossible:InvalidOperation,
 379                  DivisionUndefined:InvalidOperation,
 380                  InvalidContext:InvalidOperation}
 381
 382##### Context Functions ##################################################
 383
 384# The getcontext() and setcontext() function manage access to a thread-local
 385# current context.  Py2.4 offers direct support for thread locals.  If that
 386# is not available, use threading.currentThread() which is slower but will
 387# work for older Pythons.  If threads are not part of the build, create a
 388# mock threading object with threading.local() returning the module namespace.
 389
 390try:
 391    import threading
 392except ImportError:
 393    # Python was compiled without threads; create a mock object instead
 394    import sys
 395    class MockThreading(object):
 396        def local(self, sys=sys):
 397            return sys.modules[__name__]
 398    threading = MockThreading()
 399    del sys, MockThreading
 400
 401try:
 402    threading.local
 403
 404except AttributeError:
 405
 406    # To fix reloading, force it to create a new context
 407    # Old contexts have different exceptions in their dicts, making problems.
 408    if hasattr(threading.currentThread(), '__decimal_context__'):
 409        del threading.currentThread().__decimal_context__
 410
 411    def setcontext(context):
 412        """Set this thread's context to context."""
 413        if context in (DefaultContext, BasicContext, ExtendedContext):
 414            context = context.copy()
 415            context.clear_flags()
 416        threading.currentThread().__decimal_context__ = context
 417
 418    def getcontext():
 419        """Returns this thread's context.
 420
 421        If this thread does not yet have a context, returns
 422        a new context and sets this thread's context.
 423        New contexts are copies of DefaultContext.
 424        """
 425        try:
 426            return threading.currentThread().__decimal_context__
 427        except AttributeError:
 428            context = Context()
 429            threading.currentThread().__decimal_context__ = context
 430            return context
 431
 432else:
 433
 434    local = threading.local()
 435    if hasattr(local, '__decimal_context__'):
 436        del local.__decimal_context__
 437
 438    def getcontext(_local=local):
 439        """Returns this thread's context.
 440
 441        If this thread does not yet have a context, returns
 442        a new context and sets this thread's context.
 443        New contexts are copies of DefaultContext.
 444        """
 445        try:
 446            return _local.__decimal_context__
 447        except AttributeError:
 448            context = Context()
 449            _local.__decimal_context__ = context
 450            return context
 451
 452    def setcontext(context, _local=local):
 453        """Set this thread's context to context."""
 454        if context in (DefaultContext, BasicContext, ExtendedContext):
 455            context = context.copy()
 456            context.clear_flags()
 457        _local.__decimal_context__ = context
 458
 459    del threading, local        # Don't contaminate the namespace
 460
 461def localcontext(ctx=None):
 462    """Return a context manager for a copy of the supplied context
 463
 464    Uses a copy of the current context if no context is specified
 465    The returned context manager creates a local decimal context
 466    in a with statement:
 467        def sin(x):
 468             with localcontext() as ctx:
 469                 ctx.prec += 2
 470                 # Rest of sin calculation algorithm
 471                 # uses a precision 2 greater than normal
 472             return +s  # Convert result to normal precision
 473
 474         def sin(x):
 475             with localcontext(ExtendedContext):
 476                 # Rest of sin calculation algorithm
 477                 # uses the Extended Context from the
 478                 # General Decimal Arithmetic Specification
 479             return +s  # Convert result to normal context
 480
 481    >>> setcontext(DefaultContext)
 482    >>> print getcontext().prec
 483    28
 484    >>> with localcontext():
 485    ...     ctx = getcontext()
 486    ...     ctx.prec += 2
 487    ...     print ctx.prec
 488    ...
 489    30
 490    >>> with localcontext(ExtendedContext):
 491    ...     print getcontext().prec
 492    ...
 493    9
 494    >>> print getcontext().prec
 495    28
 496    """
 497    if ctx is None: ctx = getcontext()
 498    return _ContextManager(ctx)
 499
 500
 501##### Decimal class #######################################################
 502
 503class Decimal(object):
 504    """Floating point class for decimal arithmetic."""
 505
 506    __slots__ = ('_exp','_int','_sign', '_is_special')
 507    # Generally, the value of the Decimal instance is given by
 508    #  (-1)**_sign * _int * 10**_exp
 509    # Special values are signified by _is_special == True
 510
 511    # We're immutable, so use __new__ not __init__
 512    def __new__(cls, value="0", context=None):
 513        """Create a decimal point instance.
 514
 515        >>> Decimal('3.14')              # string input
 516        Decimal('3.14')
 517        >>> Decimal((0, (3, 1, 4), -2))  # tuple (sign, digit_tuple, exponent)
 518        Decimal('3.14')
 519        >>> Decimal(314)                 # int or long
 520        Decimal('314')
 521        >>> Decimal(Decimal(314))        # another decimal instance
 522        Decimal('314')
 523        >>> Decimal('  3.14  \\n')        # leading and trailing whitespace okay
 524        Decimal('3.14')
 525        """
 526
 527        # Note that the coefficient, self._int, is actually stored as
 528        # a string rather than as a tuple of digits.  This speeds up
 529        # the "digits to integer" and "integer to digits" conversions
 530        # that are used in almost every arithmetic operation on
 531        # Decimals.  This is an internal detail: the as_tuple function
 532        # and the Decimal constructor still deal with tuples of
 533        # digits.
 534
 535        self = object.__new__(cls)
 536
 537        # From a string
 538        # REs insist on real strings, so we can too.
 539        if isinstance(value, basestring):
 540            m = _parser(value.strip())
 541            if m is None:
 542                if context is None:
 543                    context = getcontext()
 544                return context._raise_error(ConversionSyntax,
 545                                "Invalid literal for Decimal: %r" % value)
 546
 547            if m.group('sign') == "-":
 548                self._sign = 1
 549            else:
 550                self._sign = 0
 551            intpart = m.group('int')
 552            if intpart is not None:
 553                # finite number
 554                fracpart = m.group('frac') or ''
 555                exp = int(m.group('exp') or '0')
 556                self._int = str(int(intpart+fracpart))
 557                self._exp = exp - len(fracpart)
 558                self._is_special = False
 559            else:
 560                diag = m.group('diag')
 561                if diag is not None:
 562                    # NaN
 563                    self._int = str(int(diag or '0')).lstrip('0')
 564                    if m.group('signal'):
 565                        self._exp = 'N'
 566                    else:
 567                        self._exp = 'n'
 568                else:
 569                    # infinity
 570                    self._int = '0'
 571                    self._exp = 'F'
 572                self._is_special = True
 573            return self
 574
 575        # From an integer
 576        if isinstance(value, (int,long)):
 577            if value >= 0:
 578                self._sign = 0
 579            else:
 580                self._sign = 1
 581            self._exp = 0
 582            self._int = str(abs(value))
 583            self._is_special = False
 584            return self
 585
 586        # From another decimal
 587        if isinstance(value, Decimal):
 588            self._exp  = value._exp
 589            self._sign = value._sign
 590            self._int  = value._int
 591            self._is_special  = value._is_special
 592            return self
 593
 594        # From an internal working value
 595        if isinstance(value, _WorkRep):
 596            self._sign = value.sign
 597            self._int = str(value.int)
 598            self._exp = int(value.exp)
 599            self._is_special = False
 600            return self
 601
 602        # tuple/list conversion (possibly from as_tuple())
 603        if isinstance(value, (list,tuple)):
 604            if len(value) != 3:
 605                raise ValueError('Invalid tuple size in creation of Decimal '
 606                                 'from list or tuple.  The list or tuple '
 607                                 'should have exactly three elements.')
 608            # process sign.  The isinstance test rejects floats
 609            if not (isinstance(value[0], (int, long)) and value[0] in (0,1)):
 610                raise ValueError("Invalid sign.  The first value in the tuple "
 611                                 "should be an integer; either 0 for a "
 612                                 "positive number or 1 for a negative number.")
 613            self._sign = value[0]
 614            if value[2] == 'F':
 615                # infinity: value[1] is ignored
 616                self._int = '0'
 617                self._exp = value[2]
 618                self._is_special = True
 619            else:
 620                # process and validate the digits in value[1]
 621                digits = []
 622                for digit in value[1]:
 623                    if isinstance(digit, (int, long)) and 0 <= digit <= 9:
 624                        # skip leading zeros
 625                        if digits or digit != 0:
 626                            digits.append(digit)
 627                    else:
 628                        raise ValueError("The second value in the tuple must "
 629                                         "be composed of integers in the range "
 630                                         "0 through 9.")
 631                if value[2] in ('n', 'N'):
 632                    # NaN: digits form the diagnostic
 633                    self._int = ''.join(map(str, digits))
 634                    self._exp = value[2]
 635                    self._is_special = True
 636                elif isinstance(value[2], (int, long)):
 637                    # finite number: digits give the coefficient
 638                    self._int = ''.join(map(str, digits or [0]))
 639                    self._exp = value[2]
 640                    self._is_special = False
 641                else:
 642                    raise ValueError("The third value in the tuple must "
 643                                     "be an integer, or one of the "
 644                                     "strings 'F', 'n', 'N'.")
 645            return self
 646
 647        if isinstance(value, float):
 648            raise TypeError("Cannot convert float to Decimal.  " +
 649                            "First convert the float to a string")
 650
 651        raise TypeError("Cannot convert %r to Decimal" % value)
 652
 653    def _isnan(self):
 654        """Returns whether the number is not actually one.
 655
 656        0 if a number
 657        1 if NaN
 658        2 if sNaN
 659        """
 660        if self._is_special:
 661            exp = self._exp
 662            if exp == 'n':
 663                return 1
 664            elif exp == 'N':
 665                return 2
 666        return 0
 667
 668    def _isinfinity(self):
 669        """Returns whether the number is infinite
 670
 671        0 if finite or not a number
 672        1 if +INF
 673        -1 if -INF
 674        """
 675        if self._exp == 'F':
 676            if self._sign:
 677                return -1
 678            return 1
 679        return 0
 680
 681    def _check_nans(self, other=None, context=None):
 682        """Returns whether the number is not actually one.
 683
 684        if self, other are sNaN, signal
 685        if self, other are NaN return nan
 686        return 0
 687
 688        Done before operations.
 689        """
 690
 691        self_is_nan = self._isnan()
 692        if other is None:
 693            other_is_nan = False
 694        else:
 695            other_is_nan = other._isnan()
 696
 697        if self_is_nan or other_is_nan:
 698            if context is None:
 699                context = getcontext()
 700
 701            if self_is_nan == 2:
 702                return context._raise_error(InvalidOperation, 'sNaN',
 703                                        self)
 704            if other_is_nan == 2:
 705                return context._raise_error(InvalidOperation, 'sNaN',
 706                                        other)
 707            if self_is_nan:
 708                return self._fix_nan(context)
 709
 710            return other._fix_nan(context)
 711        return 0
 712
 713    def _compare_check_nans(self, other, context):
 714        """Version of _check_nans used for the signaling comparisons
 715        compare_signal, __le__, __lt__, __ge__, __gt__.
 716
 717        Signal InvalidOperation if either self or other is a (quiet
 718        or signaling) NaN.  Signaling NaNs take precedence over quiet
 719        NaNs.
 720
 721        Return 0 if neither operand is a NaN.
 722
 723        """
 724        if context is None:
 725            context = getcontext()
 726
 727        if self._is_special or other._is_special:
 728            if self.is_snan():
 729                return context._raise_error(InvalidOperation,
 730                                            'comparison involving sNaN',
 731                                            self)
 732            elif other.is_snan():
 733                return context._raise_error(InvalidOperation,
 734                                            'comparison involving sNaN',
 735                                            other)
 736            elif self.is_qnan():
 737                return context._raise_error(InvalidOperation,
 738                                            'comparison involving NaN',
 739                                            self)
 740            elif other.is_qnan():
 741                return context._raise_error(InvalidOperation,
 742                                            'comparison involving NaN',
 743                                            other)
 744        return 0
 745
 746    def __nonzero__(self):
 747        """Return True if self is nonzero; otherwise return False.
 748
 749        NaNs and infinities are considered nonzero.
 750        """
 751        return self._is_special or self._int != '0'
 752
 753    def _cmp(self, other):
 754        """Compare the two non-NaN decimal instances self and other.
 755
 756        Returns -1 if self < other, 0 if self == other and 1
 757        if self > other.  This routine is for internal use only."""
 758
 759        if self._is_special or other._is_special:
 760            self_inf = self._isinfinity()
 761            other_inf = other._isinfinity()
 762            if self_inf == other_inf:
 763                return 0
 764            elif self_inf < other_inf:
 765                return -1
 766            else:
 767                return 1
 768
 769        # check for zeros;  Decimal('0') == Decimal('-0')
 770        if not self:
 771            if not other:
 772                return 0
 773            else:
 774                return -((-1)**other._sign)
 775        if not other:
 776            return (-1)**self._sign
 777
 778        # If different signs, neg one is less
 779        if other._sign < self._sign:
 780            return -1
 781        if self._sign < other._sign:
 782            return 1
 783
 784        self_adjusted = self.adjusted()
 785        other_adjusted = other.adjusted()
 786        if self_adjusted == other_adjusted:
 787            self_padded = self._int + '0'*(self._exp - other._exp)
 788            other_padded = other._int + '0'*(other._exp - self._exp)
 789            if self_padded == other_padded:
 790                return 0
 791            elif self_padded < other_padded:
 792                return -(-1)**self._sign
 793            else:
 794                return (-1)**self._sign
 795        elif self_adjusted > other_adjusted:
 796            return (-1)**self._sign
 797        else: # self_adjusted < other_adjusted
 798            return -((-1)**self._sign)
 799
 800    # Note: The Decimal standard doesn't cover rich comparisons for
 801    # Decimals.  In particular, the specification is silent on the
 802    # subject of what should happen for a comparison involving a NaN.
 803    # We take the following approach:
 804    #
 805    #   == comparisons involving a NaN always return False
 806    #   != comparisons involving a NaN always return True
 807    #   <, >, <= and >= comparisons involving a (quiet or signaling)
 808    #      NaN signal InvalidOperation, and return False if the
 809    #      InvalidOperation is not trapped.
 810    #
 811    # This behavior is designed to conform as closely as possible to
 812    # that specified by IEEE 754.
 813
 814    def __eq__(self, other):
 815        other = _convert_other(other)
 816        if other is NotImplemented:
 817            return other
 818        if self.is_nan() or other.is_nan():
 819            return False
 820        return self._cmp(other) == 0
 821
 822    def __ne__(self, other):
 823        other = _convert_other(other)
 824        if other is NotImplemented:
 825            return other
 826        if self.is_nan() or other.is_nan():
 827            return True
 828        return self._cmp(other) != 0
 829
 830    def __lt__(self, other, context=None):
 831        other = _convert_other(other)
 832        if other is NotImplemented:
 833            return other
 834        ans = self._compare_check_nans(other, context)
 835        if ans:
 836            return False
 837        return self._cmp(other) < 0
 838
 839    def __le__(self, other, context=None):
 840        other = _convert_other(other)
 841        if other is NotImplemented:
 842            return other
 843        ans = self._compare_check_nans(other, context)
 844        if ans:
 845            return False
 846        return self._cmp(other) <= 0
 847
 848    def __gt__(self, other, context=None):
 849        other = _convert_other(other)
 850        if other is NotImplemented:
 851            return other
 852        ans = self._compare_check_nans(other, context)
 853        if ans:
 854            return False
 855        return self._cmp(other) > 0
 856
 857    def __ge__(self, other, context=None):
 858        other = _convert_other(other)
 859        if other is NotImplemented:
 860            return other
 861        ans = self._compare_check_nans(other, context)
 862        if ans:
 863            return False
 864        return self._cmp(other) >= 0
 865
 866    def compare(self, other, context=None):
 867        """Compares one to another.
 868
 869        -1 => a < b
 870        0  => a = b
 871        1  => a > b
 872        NaN => one is NaN
 873        Like __cmp__, but returns Decimal instances.
 874        """
 875        other = _convert_other(other, raiseit=True)
 876
 877        # Compare(NaN, NaN) = NaN
 878        if (self._is_special or other and other._is_special):
 879            ans = self._check_nans(other, context)
 880            if ans:
 881                return ans
 882
 883        return Decimal(self._cmp(other))
 884
 885    def __hash__(self):
 886        """x.__hash__() <==> hash(x)"""
 887        # Decimal integers must hash the same as the ints
 888        #
 889        # The hash of a nonspecial noninteger Decimal must depend only
 890        # on the value of that Decimal, and not on its representation.
 891        # For example: hash(Decimal('100E-1')) == hash(Decimal('10')).
 892        if self._is_special:
 893            if self._isnan():
 894                raise TypeError('Cannot hash a NaN value.')
 895            return hash(str(self))
 896        if not self:
 897            return 0
 898        if self._isinteger():
 899            op = _WorkRep(self.to_integral_value())
 900            # to make computation feasible for Decimals with large
 901            # exponent, we use the fact that hash(n) == hash(m) for
 902            # any two nonzero integers n and m such that (i) n and m
 903            # have the same sign, and (ii) n is congruent to m modulo
 904            # 2**64-1.  So we can replace hash((-1)**s*c*10**e) with
 905            # hash((-1)**s*c*pow(10, e, 2**64-1).
 906            return hash((-1)**op.sign*op.int*pow(10, op.exp, 2**64-1))
 907        # The value of a nonzero nonspecial Decimal instance is
 908        # faithfully represented by the triple consisting of its sign,
 909        # its adjusted exponent, and its coefficient with trailing
 910        # zeros removed.
 911        return hash((self._sign,
 912                     self._exp+len(self._int),
 913                     self._int.rstrip('0')))
 914
 915    def as_tuple(self):
 916        """Represents the number as a triple tuple.
 917
 918        To show the internals exactly as they are.
 919        """
 920        return DecimalTuple(self._sign, tuple(map(int, self._int)), self._exp)
 921
 922    def __repr__(self):
 923        """Represents the number as an instance of Decimal."""
 924        # Invariant:  eval(repr(d)) == d
 925        return "Decimal('%s')" % str(self)
 926
 927    def __str__(self, eng=False, context=None):
 928        """Return string representation of the number in scientific notation.
 929
 930        Captures all of the information in the underlying representation.
 931        """
 932
 933        sign = ['', '-'][self._sign]
 934        if self._is_special:
 935            if self._exp == 'F':
 936                return sign + 'Infinity'
 937            elif self._exp == 'n':
 938                return sign + 'NaN' + self._int
 939            else: # self._exp == 'N'
 940                return sign + 'sNaN' + self._int
 941
 942        # number of digits of self._int to left of decimal point
 943        leftdigits = self._exp + len(self._int)
 944
 945        # dotplace is number of digits of self._int to the left of the
 946        # decimal point in the mantissa of the output string (that is,
 947        # after adjusting the exponent)
 948        if self._exp <= 0 and leftdigits > -6:
 949            # no exponent required
 950            dotplace = leftdigits
 951        elif not eng:
 952            # usual scientific notation: 1 digit on left of the point
 953            dotplace = 1
 954        elif self._int == '0':
 955            # engineering notation, zero
 956            dotplace = (leftdigits + 1) % 3 - 1
 957        else:
 958            # engineering notation, nonzero
 959            dotplace = (leftdigits - 1) % 3 + 1
 960
 961        if dotplace <= 0:
 962            intpart = '0'
 963            fracpart = '.' + '0'*(-dotplace) + self._int
 964        elif dotplace >= len(self._int):
 965            intpart = self._int+'0'*(dotplace-len(self._int))
 966            fracpart = ''
 967        else:
 968            intpart = self._int[:dotplace]
 969            fracpart = '.' + self._int[dotplace:]
 970        if leftdigits == dotplace:
 971            exp = ''
 972        else:
 973            if context is None:
 974                context = getcontext()
 975            exp = ['e', 'E'][context.capitals] + "%+d" % (leftdigits-dotplace)
 976
 977        return sign + intpart + fracpart + exp
 978
 979    def to_eng_string(self, context=None):
 980        """Convert to engineering-type string.
 981
 982        Engineering notation has an exponent which is a multiple of 3, so there
 983        are up to 3 digits left of the decimal place.
 984
 985        Same rules for when in exponential and when as a value as in __str__.
 986        """
 987        return self.__str__(eng=True, context=context)
 988
 989    def __neg__(self, context=None):
 990        """Returns a copy with the sign switched.
 991
 992        Rounds, if it has reason.
 993        """
 994        if self._is_special:
 995            ans = self._check_nans(context=context)
 996            if ans:
 997                return ans
 998
 999        if not self:
1000            # -Decimal('0') is Decimal('0'), not Decimal('-0')
1001            ans = self.copy_abs()
1002        else:
1003            ans = self.copy_negate()
1004
1005        if context is None:
1006            context = getcontext()
1007        return ans._fix(context)
1008
1009    def __pos__(self, context=None):
1010        """Returns a copy, unless it is a sNaN.
1011
1012        Rounds the number (if more then precision digits)
1013        """
1014        if self._is_special:
1015            ans = self._check_nans(context=context)
1016            if ans:
1017                return ans
1018
1019        if not self:
1020            # + (-0) = 0
1021            ans = self.copy_abs()
1022        else:
1023            ans = Decimal(self)
1024
1025        if context is None:
1026            context = getcontext()
1027        return ans._fix(context)
1028
1029    def __abs__(self, round=True, context=None):
1030        """Returns the absolute value of self.
1031
1032        If the keyword argument 'round' is false, do not round.  The
1033        expression self.__abs__(round=False) is equivalent to
1034        self.copy_abs().
1035        """
1036        if not round:
1037            return self.copy_abs()
1038
1039        if self._is_special:
1040            ans = self._check_nans(context=context)
1041            if ans:
1042                return ans
1043
1044        if self._sign:
1045            ans = self.__neg__(context=context)
1046        else:
1047            ans = self.__pos__(context=context)
1048
1049        return ans
1050
1051    def __add__(self, other, context=None):
1052        """Returns self + other.
1053
1054        -INF + INF (or the reverse) cause InvalidOperation errors.
1055        """
1056        other = _convert_other(other)
1057        if other is NotImplemented:
1058            return other
1059
1060        if context is None:
1061            context = getcontext()
1062
1063        if self._is_special or other._is_special:
1064            ans = self._check_nans(other, context)
1065            if ans:
1066                return ans
1067
1068            if self._isinfinity():
1069                # If both INF, same sign => same as both, opposite => error.
1070                if self._sign != other._sign and other._isinfinity():
1071                    return context._raise_error(InvalidOperation, '-INF + INF')
1072                return Decimal(self)
1073            if other._isinfinity():
1074                return Decimal(other)  # Can't both be infinity here
1075
1076        exp = min(self._exp, other._exp)
1077        negativezero = 0
1078        if context.rounding == ROUND_FLOOR and self._sign != other._sign:
1079            # If the answer is 0, the sign should be negative, in this case.
1080            negativezero = 1
1081
1082        if not self and not other:
1083            sign = min(self._sign, other._sign)
1084            if negativezero:
1085                sign = 1
1086            ans = _dec_from_triple(sign, '0', exp)
1087            ans = ans._fix(context)
1088            return ans
1089        if not self:
1090            exp = max(exp, other._exp - context.prec-1)
1091            ans = other._rescale(exp, context.rounding)
1092            ans = ans._fix(context)
1093            return ans
1094        if not other:
1095            exp = max(exp, self._exp - context.prec-1)
1096            ans = self._rescale(exp, context.rounding)
1097            ans = ans._fix(context)
1098            return ans
1099
1100        op1 = _WorkRep(self)
1101        op2 = _WorkRep(other)
1102        op1, op2 = _normalize(op1, op2, context.prec)
1103
1104        result = _WorkRep()
1105        if op1.sign != op2.sign:
1106            # Equal and opposite
1107            if op1.int == op2.int:
1108                ans = _dec_from_triple(negativezero, '0', exp)
1109                ans = ans._fix(context)
1110                return ans
1111            if op1.int < op2.int:
1112                op1, op2 = op2, op1
1113                # OK, now abs(op1) > abs(op2)
1114            if op1.sign == 1:
1115                result.sign = 1
1116                op1.sign, op2.sign = op2.sign, op1.sign
1117            else:
1118                result.sign = 0
1119                # So we know the sign, and op1 > 0.
1120        elif op1.sign == 1:
1121            result.sign = 1
1122            op1.sign, op2.sign = (0, 0)
1123        else:
1124            result.sign = 0
1125        # Now, op1 > abs(op2) > 0
1126
1127        if op2.sign == 0:
1128            result.int = op1.int + op2.int
1129        else:
1130            result.int = op1.int - op2.int
1131
1132        result.exp = op1.exp
1133        ans = Decimal(result)
1134        ans = ans._fix(context)
1135        return ans
1136
1137    __radd__ = __add__
1138
1139    def __sub__(self, other, context=None):
1140        """Return self - other"""
1141        other = _convert_other(other)
1142        if other is NotImplemented:
1143            return other
1144
1145        if self._is_special or other._is_special:
1146            ans = self._check_nans(other, context=context)
1147            if ans:
1148                return ans
1149
1150        # self - other is computed as self + other.copy_negate()
1151        return self.__add__(other.copy_negate(), context=context)
1152
1153    def __rsub__(self, other, context=None):
1154        """Return other - self"""
1155        other = _convert_other(other)
1156        if other is NotImplemented:
1157            return other
1158
1159        return other.__sub__(self, context=context)
1160
1161    def __mul__(self, other, context=None):
1162        """Return self * other.
1163
1164        (+-) INF * 0 (or its reverse) raise InvalidOperation.
1165        """
1166        other = _convert_other(other)
1167        if other is NotImplemented:
1168            return other
1169
1170        if context is None:
1171            context = getcontext()
1172
1173        resultsign = self._sign ^ other._sign
1174
1175        if self._is_special or other._is_special:
1176            ans = self._check_nans(other, context)
1177            if ans:
1178                return ans
1179
1180            if self._isinfinity():
1181                if not other:
1182                    return context._raise_error(InvalidOperation, '(+-)INF * 0')
1183                return _SignedInfinity[resultsign]
1184
1185            if other._isinfinity():
1186                if not self:
1187                    return context._raise_error(InvalidOperation, '0 * (+-)INF')
1188                return _SignedInfinity[resultsign]
1189
1190        resultexp = self._exp + other._exp
1191
1192        # Special case for multiplying by zero
1193        if not self or not other:
1194            ans = _dec_from_triple(resultsign, '0', resultexp)
1195            # Fixing in case the exponent is out of bounds
1196            ans = ans._fix(context)
1197            return ans
1198
1199        # Special case for multiplying by power of 10
1200        if self._int == '1':
1201            ans = _dec_from_triple(resultsign, other._int, resultexp)
1202            ans = ans._fix(context)
1203            return ans
1204        if other._int == '1':
1205            ans = _dec_from_triple(resultsign, self._int, resultexp)
1206            ans = ans._fix(context)
1207            return ans
1208
1209        op1 = _WorkRep(self)
1210        op2 = _WorkRep(other)
1211
1212        ans = _dec_from_triple(resultsign, str(op1.int * op2.int), resultexp)
1213        ans = ans._fix(context)
1214
1215        return ans
1216    __rmul__ = __mul__
1217
1218    def __truediv__(self, other, context=None):
1219        """Return self / other."""
1220        other = _convert_other(other)
1221        if other is NotImplemented:
1222            return NotImplemented
1223
1224        if context is None:
1225            context = getcontext()
1226
1227        sign = self._sign ^ other._sign
1228
1229        if self._is_special or other._is_special:
1230            ans = self._check_nans(other, context)
1231            if ans:
1232                return ans
1233
1234            if self._isinfinity() and other._isinfinity():
1235                return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
1236
1237            if self._isinfinity():
1238                return _SignedInfinity[sign]
1239
1240            if other._isinfinity():
1241                context._raise_error(Clamped, 'Division by infinity')
1242                return _dec_from_triple(sign, '0', context.Etiny())
1243
1244        # Special cases for zeroes
1245        if not other:
1246            if not self:
1247                return context._raise_error(DivisionUndefined, '0 / 0')
1248            return context._raise_error(DivisionByZero, 'x / 0', sign)
1249
1250        if not self:
1251            exp = self._exp - other._exp
1252            coeff = 0
1253        else:
1254            # OK, so neither = 0, INF or NaN
1255            shift = len(other._int) - len(self._int) + context.prec + 1
1256            exp = self._exp - other._exp - shift
1257            op1 = _WorkRep(self)
1258            op2 = _WorkRep(other)
1259            if shift >= 0:
1260                coeff, remainder = divmod(op1.int * 10**shift, op2.int)
1261            else:
1262                coeff, remainder = divmod(op1.int, op2.int * 10**-shift)
1263            if remainder:
1264                # result is not exact; adjust to ensure correct rounding
1265                if coeff % 5 == 0:
1266                    coeff += 1
1267            else:
1268                # result is exact; get as close to ideal exponent as possible
1269                ideal_exp = self._exp - other._exp
1270                while exp < ideal_exp and coeff % 10 == 0:
1271                    coeff //= 10
1272                    exp += 1
1273
1274        ans = _dec_from_triple(sign, str(coeff), exp)
1275        return ans._fix(context)
1276
1277    def _divide(self, other, context):
1278        """Return (self // other, self % other), to context.prec precision.
1279
1280        Assumes that neither self nor other is a NaN, that self is not
1281        infinite and that other is nonzero.
1282        """
1283        sign = self._sign ^ other._sign
1284        if other._isinfinity():
1285            ideal_exp = self._exp
1286        else:
1287            ideal_exp = min(self._exp, other._exp)
1288
1289        expdiff = self.adjusted() - other.adjusted()
1290        if not self or other._isinfinity() or expdiff <= -2:
1291            return (_dec_from_triple(sign, '0', 0),
1292                    self._rescale(ideal_exp, context.rounding))
1293        if expdiff <= context.prec:
1294            op1 = _WorkRep(self)
1295            op2 = _WorkRep(other)
1296            if op1.exp >= op2.exp:
1297                op1.int *= 10**(op1.exp - op2.exp)
1298            else:
1299                op2.int *= 10**(op2.exp - op1.exp)
1300            q, r = divmod(op1.int, op2.int)
1301            if q < 10**context.prec:
1302                return (_dec_from_triple(sign, str(q), 0),
1303                        _dec_from_triple(self._sign, str(r), ideal_exp))
1304
1305        # Here the quotient is too large to be representable
1306        ans = context._raise_error(DivisionImpossible,
1307                                   'quotient too large in //, % or divmod')
1308        return ans, ans
1309
1310    def __rtruediv__(self, other, context=None):
1311        """Swaps self/other and returns __truediv__."""
1312        other = _convert_other(other)
1313        if other is NotImplemented:
1314            return other
1315        return other.__truediv__(self, context=context)
1316
1317    __div__ = __truediv__
1318    __rdiv__ = __rtruediv__
1319
1320    def __divmod__(self, other, context=None):
1321        """
1322        Return (self // other, self % other)
1323        """
1324        other = _convert_other(other)
1325        if other is NotImplemented:
1326            return other
1327
1328        if context is None:
1329            context = getcontext()
1330
1331        ans = self._check_nans(other, context)
1332        if ans:
1333            return (ans, ans)
1334
1335        sign = self._sign ^ other._sign
1336        if self._isinfinity():
1337            if other._isinfinity():
1338                ans = context._raise_error(InvalidOperation, 'divmod(INF, INF)')
1339                return ans, ans
1340            else:
1341                return (_SignedInfinity[sign],
1342                        context._raise_error(InvalidOperation, 'INF % x'))
1343
1344        if not other:
1345            if not self:
1346                ans = context._raise_error(DivisionUndefined, 'divmod(0, 0)')
1347                return ans, ans
1348            else:
1349                return (context._raise_error(DivisionByZero, 'x // 0', sign),
1350                        context._raise_error(InvalidOperation, 'x % 0'))
1351
1352        quotient, remainder = self._divide(other, context)
1353        remainder = remainder._fix(context)
1354        return quotient, remainder
1355
1356    def __rdivmod__(self, other, context=None):
1357        """Swaps self/other and returns __divmod__."""
1358        other = _convert_other(other)
1359        if other is NotImplemented:
1360            return other
1361        return other.__divmod__(self, context=context)
1362
1363    def __mod__(self, other, context=None):
1364        """
1365        self % other
1366        """
1367        other = _convert_other(other)
1368        if other is NotImplemented:
1369            return other
1370
1371        if context is None:
1372            context = getcontext()
1373
1374        ans = self._check_nans(other, context)
1375        if ans:
1376            return ans
1377
1378        if self._isinfinity():
1379            return context._raise_error(InvalidOperation, 'INF % x')
1380        elif not other:
1381            if self:
1382                return context._raise_error(InvalidOperation, 'x % 0')
1383            else:
1384                return context._raise_error(DivisionUndefined, '0 % 0')
1385
1386        remainder = self._divide(other, context)[1]
1387        remainder = remainder._fix(context)
1388        return remainder
1389
1390    def __rmod__(self, other, context=None):
1391        """Swaps self/other and returns __mod__."""
1392        other = _convert_other(other)
1393        if other is NotImplemented:
1394            return other
1395        return other.__mod__(self, context=context)
1396
1397    def remainder_near(self, other, context=None):
1398        """
1399        Remainder nearest to 0-  abs(remainder-near) <= other/2
1400        """
1401        if context is None:
1402            context = getcontext()
1403
1404        other = _convert_other(other, raiseit=True)
1405
1406        ans = self._check_nans(other, context)
1407        if ans:
1408            return ans
1409
1410        # self == +/-infinity -> InvalidOperation
1411        if self._isinfinity():
1412            return context._raise_error(InvalidOperation,
1413                                        'remainder_near(infinity, x)')
1414
1415        # other == 0 -> either InvalidOperation or DivisionUndefined
1416        if not other:
1417            if self:
1418                return context._raise_error(InvalidOperation,
1419                                            'remainder_near(x, 0)')
1420            else:
1421                return context._raise_error(DivisionUndefined,
1422                                            'remainder_near(0, 0)')
1423
1424        # other = +/-infinity -> remainder = self
1425        if other._isinfinity():
1426            ans = Decimal(self)
1427            return ans._fix(context)
1428
1429        # self = 0 -> remainder = self, with ideal exponent
1430        ideal_exponent = min(self._exp, other._exp)
1431        if not self:
1432            ans = _dec_from_triple(self._sign, '0', ideal_exponent)
1433            return ans._fix(context)
1434
1435        # catch most cases of large or small quotient
1436        expdiff = self.adjusted() - other.adjusted()
1437        if expdiff >= context.prec + 1:
1438            # expdiff >= prec+1 => abs(self/other) > 10**prec
1439            return context._raise_error(DivisionImpossible)
1440     

Large files files are truncated, but you can click here to view the full file