Ticket #2365: DecimalField-FloatField.2.diff

File DecimalField-FloatField.2.diff, 143.4 KB (added by adurdin@…, 8 years ago)

Patch -- implements database FloatField and DecimalField, and supporting fields in oldforms and newforms, with tests.

  • django/oldforms/__init__.py

     
    745745            raise validators.CriticalValidationError, gettext("Enter a whole number between 0 and 32,767.")
    746746
    747747class FloatField(TextField):
     748    def __init__(self, field_name, is_required=False, validator_list=None):
     749        if validator_list is None: validator_list = []
     750        validator_list = [validators.isValidFloat] + validator_list
     751        TextField.__init__(self, field_name, is_required=is_required, validator_list=validator_list)
     752 
     753    def html2python(data):
     754        if data == '' or data is None:
     755            return None
     756        return float(data)
     757    html2python = staticmethod(html2python)
     758 
     759class DecimalField(TextField):
    748760    def __init__(self, field_name, max_digits, decimal_places, is_required=False, validator_list=None):
    749761        if validator_list is None: validator_list = []
    750762        self.max_digits, self.decimal_places = max_digits, decimal_places
    751         validator_list = [self.isValidFloat] + validator_list
    752         TextField.__init__(self, field_name, max_digits+2, max_digits+2, is_required, validator_list)
     763        validator_list = [self.isValidDecimal] + validator_list
     764        # Initialise the TextField, making sure it's large enough to fit the number with a - sign and a decimal point.
     765        super(DecimalField, self).__init__(field_name, max_digits+2, max_digits+2, is_required, validator_list)
    753766
    754     def isValidFloat(self, field_data, all_data):
    755         v = validators.IsValidFloat(self.max_digits, self.decimal_places)
     767    def isValidDecimal(self, field_data, all_data):
     768        v = validators.IsValidDecimal(self.max_digits, self.decimal_places)
    756769        try:
    757770            v(field_data, all_data)
    758771        except validators.ValidationError, e:
     
    761774    def html2python(data):
    762775        if data == '' or data is None:
    763776            return None
    764         return float(data)
     777        try:
     778            import decimal
     779        except ImportError:
     780            from django.utils import decimal
     781        try:
     782            return decimal.Decimal(data)
     783        except decimal.InvalidOperation, e:
     784            raise ValueError, e
    765785    html2python = staticmethod(html2python)
    766786
    767787####################
  • django/db/models/fields/__init__.py

     
    668668    def get_manipulator_field_objs(self):
    669669        return [curry(oldforms.FilePathField, path=self.path, match=self.match, recursive=self.recursive)]
    670670
    671 class FloatField(Field):
     671class DecimalField(Field):
    672672    empty_strings_allowed = False
    673673    def __init__(self, verbose_name=None, name=None, max_digits=None, decimal_places=None, **kwargs):
    674674        self.max_digits, self.decimal_places = max_digits, decimal_places
    675675        Field.__init__(self, verbose_name, name, **kwargs)
    676676
     677    def to_python(self, value):
     678        try:
     679            import decimal
     680        except ImportError:
     681            from django.utils import decimal
     682        try:
     683            return decimal.Decimal(value)
     684        except (decimal.InvalidOperation):
     685            raise validators.ValidationError, gettext("This value must be a decimal number.")
     686
     687    def _format(self, value):
     688        if isinstance(value, basestring):
     689            return value
     690        else:
     691            return self.format_number(value)
     692   
     693    def format_number(self, value):
     694        """Formats a number into a string with the requisite number of digits and decimal places."""
     695       
     696        num_chars = self.max_digits
     697        # Allow for a decimal point
     698        if self.decimal_places > 0:
     699            num_chars += 1
     700        # Allow for a minus sign
     701        if value < 0:
     702            num_chars += 1
     703       
     704        return "%.*f" % (self.decimal_places, value)
     705
     706    def get_db_prep_save(self, value):
     707        value = value # self._format(value)
     708        return super(DecimalField, self).get_db_prep_save(value)
     709
     710    def get_db_prep_lookup(self, lookup_type, value):
     711        if lookup_type == 'range':
     712            value = [self._format(v) for v in value]
     713        else:
     714            value = self._format(value)
     715        return super(DecimalField, self).get_db_prep_lookup(lookup_type, value)
     716
    677717    def get_manipulator_field_objs(self):
    678         return [curry(oldforms.FloatField, max_digits=self.max_digits, decimal_places=self.decimal_places)]
     718        return [curry(oldforms.DecimalField, max_digits=self.max_digits, decimal_places=self.decimal_places)]
    679719
     720    def formfield(self, **kwargs):
     721        "Returns a django.newforms.Field instance for this database Field."
     722        defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name),
     723            'max_digits': self.max_digits, 'decimal_places': self.decimal_places}
     724        defaults.update(kwargs)
     725        return forms.DecimalField(**defaults)
     726
     727class FloatField(Field):
     728    empty_strings_allowed = False
     729    def __init__(self, verbose_name=None, name=None, **kwargs):
     730        Field.__init__(self, verbose_name, name, **kwargs)
     731
     732    def get_manipulator_field_objs(self):
     733        return [oldforms.FloatField]
     734
     735    def formfield(self, **kwargs):
     736        "Returns a django.newforms.FloatField instance for this database Field."
     737        defaults = {'required': not self.blank, 'label': capfirst(self.verbose_name)}
     738        defaults.update(kwargs)
     739        return forms.FloatField(**defaults)
     740
    680741class ImageField(FileField):
    681742    def __init__(self, verbose_name=None, name=None, width_field=None, height_field=None, **kwargs):
    682743        self.width_field, self.height_field = width_field, height_field
  • django/db/backends/ado_mssql/creation.py

     
    55    'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
    66    'DateField':         'smalldatetime',
    77    'DateTimeField':     'smalldatetime',
     8    'DecimalField':      'numeric(%(max_digits)s, %(decimal_places)s)',
    89    'FileField':         'varchar(100)',
    910    'FilePathField':     'varchar(100)',
    10     'FloatField':        'numeric(%(max_digits)s, %(decimal_places)s)',
     11    'FloatField':        'double precision',
    1112    'ImageField':        'varchar(100)',
    1213    'IntegerField':      'int',
    1314    'IPAddressField':    'char(15)',
  • django/db/backends/postgresql/introspection.py

     
    7979    1114: 'DateTimeField',
    8080    1184: 'DateTimeField',
    8181    1266: 'TimeField',
    82     1700: 'FloatField',
     82    1700: 'DecimalField',
    8383}
  • django/db/backends/postgresql/creation.py

     
    99    'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
    1010    'DateField':         'date',
    1111    'DateTimeField':     'timestamp with time zone',
     12    'DecimalField':      'numeric(%(max_digits)s, %(decimal_places)s)',
    1213    'FileField':         'varchar(100)',
    1314    'FilePathField':     'varchar(100)',
    14     'FloatField':        'numeric(%(max_digits)s, %(decimal_places)s)',
     15    'FloatField':        'double precision',
    1516    'ImageField':        'varchar(100)',
    1617    'IntegerField':      'integer',
    1718    'IPAddressField':    'inet',
  • django/db/backends/sqlite3/base.py

     
    1717        module = 'sqlite3'
    1818    raise ImproperlyConfigured, "Error loading %s module: %s" % (module, e)
    1919
     20try:
     21    # Only exists in Python 2.4+
     22    import decimal
     23except ImportError:
     24    # Import copy of decimal.py from Python 2.4
     25    from django.utils import decimal
     26
    2027DatabaseError = Database.DatabaseError
    2128
    2229Database.register_converter("bool", lambda s: str(s) == '1')
     
    2532Database.register_converter("datetime", util.typecast_timestamp)
    2633Database.register_converter("timestamp", util.typecast_timestamp)
    2734Database.register_converter("TIMESTAMP", util.typecast_timestamp)
     35Database.register_converter("decimal", util.typecast_decimal)
     36Database.register_adapter(decimal.Decimal, util.rev_typecast_decimal)
    2837
    2938def utf8rowFactory(cursor, row):
    3039    def utf8(s):
  • django/db/backends/sqlite3/creation.py

     
    88    'CommaSeparatedIntegerField':   'varchar(%(maxlength)s)',
    99    'DateField':                    'date',
    1010    'DateTimeField':                'datetime',
     11    'DecimalField':                 'decimal',
    1112    'FileField':                    'varchar(100)',
    1213    'FilePathField':                'varchar(100)',
    13     'FloatField':                   'numeric(%(max_digits)s, %(decimal_places)s)',
     14    'FloatField':                   'real',
    1415    'ImageField':                   'varchar(100)',
    1516    'IntegerField':                 'integer',
    1617    'IPAddressField':               'char(15)',
  • django/db/backends/util.py

     
    11import datetime
    22from time import time
    33
     4try:
     5    # Only exists in Python 2.4+
     6    import decimal
     7except ImportError:
     8    # Import copy of decimal.py from Python 2.4
     9    from django.utils import decimal
     10
    411class CursorDebugWrapper(object):
    512    def __init__(self, cursor, db):
    613        self.cursor = cursor
     
    8592    if not s: return False
    8693    return str(s)[0].lower() == 't'
    8794
     95def typecast_decimal(s):
     96    if s is None: return None
     97    return decimal.Decimal(s)
     98
    8899###############################################
    89100# Converters from Python to database (string) #
    90101###############################################
     
    92103def rev_typecast_boolean(obj, d):
    93104    return obj and '1' or '0'
    94105
     106def rev_typecast_decimal(d):
     107    if d is None: return None
     108    return str(d)
     109
    95110##################################################################################
    96111# Helper functions for dictfetch* for databases that don't natively support them #
    97112##################################################################################
  • django/db/backends/mysql/base.py

     
    2323    FIELD_TYPE.DATETIME: util.typecast_timestamp,
    2424    FIELD_TYPE.DATE: util.typecast_date,
    2525    FIELD_TYPE.TIME: util.typecast_time,
     26    FIELD_TYPE.DECIMAL: util.typecast_decimal,
    2627})
    2728
    2829# This should match the numerical portion of the version numbers (we can treat
  • django/db/backends/mysql/introspection.py

     
    7676DATA_TYPES_REVERSE = {
    7777    FIELD_TYPE.BLOB: 'TextField',
    7878    FIELD_TYPE.CHAR: 'CharField',
    79     FIELD_TYPE.DECIMAL: 'FloatField',
     79    FIELD_TYPE.DECIMAL: 'DecimalField',
    8080    FIELD_TYPE.DATE: 'DateField',
    8181    FIELD_TYPE.DATETIME: 'DateTimeField',
    8282    FIELD_TYPE.DOUBLE: 'FloatField',
  • django/db/backends/mysql/creation.py

     
    99    'CommaSeparatedIntegerField': 'varchar(%(maxlength)s)',
    1010    'DateField':         'date',
    1111    'DateTimeField':     'datetime',
     12    'DecimalField':      'decimal(%(max_digits)s, %(decimal_places)s)',
    1213    'FileField':         'varchar(100)',
    1314    'FilePathField':     'varchar(100)',
    14     'FloatField':        'numeric(%(max_digits)s, %(decimal_places)s)',
     15    'FloatField':        'double precision',
    1516    'ImageField':        'varchar(100)',
    1617    'IntegerField':      'integer',
    1718    'IPAddressField':    'char(15)',
  • django/db/backends/oracle/introspection.py

     
    4646    1114: 'DateTimeField',
    4747    1184: 'DateTimeField',
    4848    1266: 'TimeField',
    49     1700: 'FloatField',
     49    1700: 'DecimalField',
    5050}
  • django/db/backends/oracle/creation.py

     
    55    'CommaSeparatedIntegerField': 'varchar2(%(maxlength)s)',
    66    'DateField':         'date',
    77    'DateTimeField':     'date',
     8    'DecimalField':      'number(%(max_digits)s, %(decimal_places)s)',
    89    'FileField':         'varchar2(100)',
    910    'FilePathField':     'varchar2(100)',
    10     'FloatField':        'number(%(max_digits)s, %(decimal_places)s)',
     11    'FloatField':        'double precision',
    1112    'ImageField':        'varchar2(100)',
    1213    'IntegerField':      'integer',
    1314    'IPAddressField':    'char(15)',
  • django/db/backends/postgresql_psycopg2/introspection.py

     
    7979    1114: 'DateTimeField',
    8080    1184: 'DateTimeField',
    8181    1266: 'TimeField',
    82     1700: 'FloatField',
     82    1700: 'DecimalField',
    8383}
  • django/core/validators.py

     
    2525    r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
    2626    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
    2727    r')@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}$', re.IGNORECASE)  # domain
     28decimal_re = re.compile(r'^-?(?P<digits>\d+)(\.(?P<decimals>\d+))?$')
    2829integer_re = re.compile(r'^-?\d+$')
    2930ip4_re = re.compile(r'^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$')
    3031phone_re = re.compile(r'^[A-PR-Y0-9]{3}-[A-PR-Y0-9]{3}-[A-PR-Y0-9]{4}$', re.IGNORECASE)
     
    403404        if val != int(val):
    404405            raise ValidationError, gettext("This value must be a power of %s.") % self.power_of
    405406
    406 class IsValidFloat(object):
     407class IsValidDecimal(object):
    407408    def __init__(self, max_digits, decimal_places):
    408409        self.max_digits, self.decimal_places = max_digits, decimal_places
    409410
    410411    def __call__(self, field_data, all_data):
    411         data = str(field_data)
    412         try:
    413             float(data)
    414         except ValueError:
     412        match = decimal_re.search(str(field_data))
     413        if not match:
    415414            raise ValidationError, gettext("Please enter a valid decimal number.")
    416         # Negative floats require more space to input.
    417         max_allowed_length = data.startswith('-') and (self.max_digits + 2) or (self.max_digits + 1)
    418         if len(data) > max_allowed_length:
     415       
     416        digits = len(match.group('digits') or '')
     417        decimals = len(match.group('decimals') or '')
     418       
     419        if digits + decimals > self.max_digits:
    419420            raise ValidationError, ngettext("Please enter a valid decimal number with at most %s total digit.",
    420421                "Please enter a valid decimal number with at most %s total digits.", self.max_digits) % self.max_digits
    421         if (not '.' in data and len(data) > (max_allowed_length - self.decimal_places - 1)) or ('.' in data and len(data) > (max_allowed_length - (self.decimal_places - len(data.split('.')[1])))):
     422        if digits > (self.max_digits - self.decimal_places):
    422423            raise ValidationError, ngettext( "Please enter a valid decimal number with a whole part of at most %s digit.",
    423424                "Please enter a valid decimal number with a whole part of at most %s digits.", str(self.max_digits-self.decimal_places)) % str(self.max_digits-self.decimal_places)
    424         if '.' in data and len(data.split('.')[1]) > self.decimal_places:
     425        if decimals > self.decimal_places:
    425426            raise ValidationError, ngettext("Please enter a valid decimal number with at most %s decimal place.",
    426427                "Please enter a valid decimal number with at most %s decimal places.", self.decimal_places) % self.decimal_places
    427428
     429def isValidFloat(field_data, all_data):
     430    data = str(field_data)
     431    try:
     432        float(data)
     433    except ValueError:
     434        raise ValidationError, gettext("Please enter a valid floating point number.")
     435
    428436class HasAllowableSize(object):
    429437    """
    430438    Checks that the file-upload field data is a certain size. min_size and
  • django/core/management.py

     
    804804                if field_type == 'CharField' and row[3]:
    805805                    extra_params['maxlength'] = row[3]
    806806
    807                 if field_type == 'FloatField':
     807                if field_type == 'DecimalField':
    808808                    extra_params['max_digits'] = row[4]
    809809                    extra_params['decimal_places'] = row[5]
    810810
     
    879879                e.add(opts, '"%s": You can\'t use "id" as a field name, because each model automatically gets an "id" field if none of the fields have primary_key=True. You need to either remove/rename your "id" field or add primary_key=True to a field.' % f.name)
    880880            if isinstance(f, models.CharField) and f.maxlength in (None, 0):
    881881                e.add(opts, '"%s": CharFields require a "maxlength" attribute.' % f.name)
    882             if isinstance(f, models.FloatField):
     882            if isinstance(f, models.DecimalField):
    883883                if f.decimal_places is None:
    884                     e.add(opts, '"%s": FloatFields require a "decimal_places" attribute.' % f.name)
     884                    e.add(opts, '"%s": DecimalFields require a "decimal_places" attribute.' % f.name)
    885885                if f.max_digits is None:
    886                     e.add(opts, '"%s": FloatFields require a "max_digits" attribute.' % f.name)
     886                    e.add(opts, '"%s": DecimalFields require a "max_digits" attribute.' % f.name)
    887887            if isinstance(f, models.FileField) and not f.upload_to:
    888888                e.add(opts, '"%s": FileFields require an "upload_to" attribute.' % f.name)
    889889            if isinstance(f, models.ImageField):
  • django/newforms/fields.py

     
    1717    'RegexField', 'EmailField', 'URLField', 'BooleanField',
    1818    'ChoiceField', 'NullBooleanField', 'MultipleChoiceField',
    1919    'ComboField', 'MultiValueField',
     20    'FloatField', 'DecimalField',
    2021    'SplitDateTimeField',
    2122)
    2223
     
    2829except NameError:
    2930    from sets import Set as set # Python 2.3 fallback
    3031
     32try:
     33    from decimal import Decimal # Only available in Python 2.4+
     34except ImportError:
     35    from django.utils.decimal import Decimal # Use bundled version for Python 2.3
     36
    3137class Field(object):
    3238    widget = TextInput # Default widget to use when rendering this type of Field.
    3339    hidden_widget = HiddenInput # Default widget to use when rendering this as "hidden".
     
    128134            raise ValidationError(gettext(u'Ensure this value is greater than or equal to %s.') % self.min_value)
    129135        return value
    130136
     137class FloatField(Field):
     138    def __init__(self, max_value=None, min_value=None, required=True, widget=None, label=None, initial=None):
     139        self.max_value, self.min_value = max_value, min_value
     140        Field.__init__(self, required, widget, label, initial)
     141       
     142    def clean(self, value):
     143        """
     144        Validates that float() can be called on the input. Returns a float.
     145        Returns None for empty values.
     146        """
     147        super(FloatField, self).clean(value)
     148        if not self.required and value in EMPTY_VALUES:
     149            return None
     150        try:
     151            value = float(value)
     152        except (ValueError, TypeError):
     153            raise ValidationError(gettext(u'Enter a number.'))
     154        if self.max_value is not None and value > self.max_value:
     155            raise ValidationError(gettext(u'Ensure this value is less than or equal to %s.') % self.max_value)
     156        if self.min_value is not None and value < self.min_value:
     157            raise ValidationError(gettext(u'Ensure this value is greater than or equal to %s.') % self.min_value)
     158        return value
     159
     160decimal_re = re.compile(r'^-?(?P<digits>\d+)(\.(?P<decimals>\d+))?$')
     161
     162class DecimalField(Field):
     163    def __init__(self, max_value=None, min_value=None, max_digits=None, decimal_places=None, required=True, widget=None, label=None, initial=None):
     164        self.max_value, self.min_value = max_value, min_value
     165        self.max_digits, self.decimal_places = max_digits, decimal_places
     166        Field.__init__(self, required, widget, label, initial)
     167       
     168    def clean(self, value):
     169        """
     170        Validates that the input is a decimal number. Returns a decimal.Decimal
     171        instance. Returns None for empty values. Ensures that there are no more
     172        than max_digits in the number, and no more than decimal_places digits
     173        after the decimal point.
     174        """
     175        super(DecimalField, self).clean(value)
     176        if not self.required and value in EMPTY_VALUES:
     177            return None
     178        value = value.strip()
     179        match = decimal_re.search(value)
     180        if not match:
     181            raise ValidationError(gettext(u'Enter a number.'))
     182        else:
     183            value = Decimal(value)
     184        digits = len(match.group('digits') or '')
     185        decimals = len(match.group('decimals') or '')
     186        if self.max_value is not None and value > self.max_value:
     187            raise ValidationError(gettext(u'Ensure this value is less than or equal to %s.') % self.max_value)
     188        if self.min_value is not None and value < self.min_value:
     189            raise ValidationError(gettext(u'Ensure this value is greater than or equal to %s.') % self.min_value)
     190        if self.max_digits is not None and (digits + decimals) > self.max_digits:
     191            raise ValidationError(gettext(u'Ensure that there are no more than %s digits in total.') % self.max_digits)
     192        if self.decimal_places is not None and decimals > self.decimal_places:
     193            raise ValidationError(gettext(u'Ensure that there are no more than %s decimal places.') % self.decimal_places)
     194        if self.max_digits is not None and self.decimal_places is not None and digits > (self.max_digits - self.decimal_places):
     195            raise ValidationError(gettext(u'Ensure that there are no more than %s digits before the decimal point.') % (self.max_digits - self.decimal_places))
     196        return value
     197
    131198DEFAULT_DATE_INPUT_FORMATS = (
    132199    '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
    133200    '%b %d %Y', '%b %d, %Y',            # 'Oct 25 2006', 'Oct 25, 2006'
  • django/contrib/admin/templatetags/admin_list.py

     
    157157            # Booleans are special: We use images.
    158158            elif isinstance(f, models.BooleanField) or isinstance(f, models.NullBooleanField):
    159159                result_repr = _boolean_icon(field_val)
    160             # FloatFields are special: Zero-pad the decimals.
    161             elif isinstance(f, models.FloatField):
     160            # DecimalFields are special: Zero-pad the decimals.
     161            elif isinstance(f, models.DecimalField):
    162162                if field_val is not None:
    163163                    result_repr = ('%%.%sf' % f.decimal_places) % field_val
    164164                else:
  • django/contrib/admin/views/doc.py

     
    294294    'CommaSeparatedIntegerField': _('Comma-separated integers'),
    295295    'DateField'                 : _('Date (without time)'),
    296296    'DateTimeField'             : _('Date (with time)'),
     297    'DecimalField'              : _('Decimal number'),
    297298    'EmailField'                : _('E-mail address'),
    298299    'FileField'                 : _('File path'),
    299300    'FilePathField'             : _('File path'),
    300     'FloatField'                : _('Decimal number'),
     301    'FloatField'                : _('Floating point number'),
    301302    'ForeignKey'                : _('Integer'),
    302303    'ImageField'                : _('File path'),
    303304    'IntegerField'              : _('Integer'),
  • django/utils/decimal.py

     
     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 the module is to support arithmetic using familiar
     33"schoolhouse" rules and to avoid the some of 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',
     132
     133    # Functions for manipulating contexts
     134    'setcontext', 'getcontext'
     135]
     136
     137import copy
     138
     139#Rounding
     140ROUND_DOWN = 'ROUND_DOWN'
     141ROUND_HALF_UP = 'ROUND_HALF_UP'
     142ROUND_HALF_EVEN = 'ROUND_HALF_EVEN'
     143ROUND_CEILING = 'ROUND_CEILING'
     144ROUND_FLOOR = 'ROUND_FLOOR'
     145ROUND_UP = 'ROUND_UP'
     146ROUND_HALF_DOWN = 'ROUND_HALF_DOWN'
     147
     148#Rounding decision (not part of the public API)
     149NEVER_ROUND = 'NEVER_ROUND'    # Round in division (non-divmod), sqrt ONLY
     150ALWAYS_ROUND = 'ALWAYS_ROUND'  # Every operation rounds at end.
     151
     152#Errors
     153
     154class DecimalException(ArithmeticError):
     155    """Base exception class.
     156
     157    Used exceptions derive from this.
     158    If an exception derives from another exception besides this (such as
     159    Underflow (Inexact, Rounded, Subnormal) that indicates that it is only
     160    called if the others are present.  This isn't actually used for
     161    anything, though.
     162
     163    handle  -- Called when context._raise_error is called and the
     164               trap_enabler is set.  First argument is self, second is the
     165               context.  More arguments can be given, those being after
     166               the explanation in _raise_error (For example,
     167               context._raise_error(NewError, '(-x)!', self._sign) would
     168               call NewError().handle(context, self._sign).)
     169
     170    To define a new exception, it should be sufficient to have it derive
     171    from DecimalException.
     172    """
     173    def handle(self, context, *args):
     174        pass
     175
     176
     177class Clamped(DecimalException):
     178    """Exponent of a 0 changed to fit bounds.
     179
     180    This occurs and signals clamped if the exponent of a result has been
     181    altered in order to fit the constraints of a specific concrete
     182    representation. This may occur when the exponent of a zero result would
     183    be outside the bounds of a representation, or  when a large normal
     184    number would have an encoded exponent that cannot be represented. In
     185    this latter case, the exponent is reduced to fit and the corresponding
     186    number of zero digits are appended to the coefficient ("fold-down").
     187    """
     188
     189
     190class InvalidOperation(DecimalException):
     191    """An invalid operation was performed.
     192
     193    Various bad things cause this:
     194
     195    Something creates a signaling NaN
     196    -INF + INF
     197     0 * (+-)INF
     198     (+-)INF / (+-)INF
     199    x % 0
     200    (+-)INF % x
     201    x._rescale( non-integer )
     202    sqrt(-x) , x > 0
     203    0 ** 0
     204    x ** (non-integer)
     205    x ** (+-)INF
     206    An operand is invalid
     207    """
     208    def handle(self, context, *args):
     209        if args:
     210            if args[0] == 1: #sNaN, must drop 's' but keep diagnostics
     211                return Decimal( (args[1]._sign, args[1]._int, 'n') )
     212        return NaN
     213
     214class ConversionSyntax(InvalidOperation):
     215    """Trying to convert badly formed string.
     216
     217    This occurs and signals invalid-operation if an string is being
     218    converted to a number and it does not conform to the numeric string
     219    syntax. The result is [0,qNaN].
     220    """
     221
     222    def handle(self, context, *args):
     223        return (0, (0,), 'n') #Passed to something which uses a tuple.
     224
     225class DivisionByZero(DecimalException, ZeroDivisionError):
     226    """Division by 0.
     227
     228    This occurs and signals division-by-zero if division of a finite number
     229    by zero was attempted (during a divide-integer or divide operation, or a
     230    power operation with negative right-hand operand), and the dividend was
     231    not zero.
     232
     233    The result of the operation is [sign,inf], where sign is the exclusive
     234    or of the signs of the operands for divide, or is 1 for an odd power of
     235    -0, for power.
     236    """
     237
     238    def handle(self, context, sign, double = None, *args):
     239        if double is not None:
     240            return (Infsign[sign],)*2
     241        return Infsign[sign]
     242
     243class DivisionImpossible(InvalidOperation):
     244    """Cannot perform the division adequately.
     245
     246    This occurs and signals invalid-operation if the integer result of a
     247    divide-integer or remainder operation had too many digits (would be
     248    longer than precision). The result is [0,qNaN].
     249    """
     250
     251    def handle(self, context, *args):
     252        return (NaN, NaN)
     253
     254class DivisionUndefined(InvalidOperation, ZeroDivisionError):
     255    """Undefined result of division.
     256
     257    This occurs and signals invalid-operation if division by zero was
     258    attempted (during a divide-integer, divide, or remainder operation), and
     259    the dividend is also zero. The result is [0,qNaN].
     260    """
     261
     262    def handle(self, context, tup=None, *args):
     263        if tup is not None:
     264            return (NaN, NaN) #for 0 %0, 0 // 0
     265        return NaN
     266
     267class Inexact(DecimalException):
     268    """Had to round, losing information.
     269
     270    This occurs and signals inexact whenever the result of an operation is
     271    not exact (that is, it needed to be rounded and any discarded digits
     272    were non-zero), or if an overflow or underflow condition occurs. The
     273    result in all cases is unchanged.
     274
     275    The inexact signal may be tested (or trapped) to determine if a given
     276    operation (or sequence of operations) was inexact.
     277    """
     278    pass
     279
     280class InvalidContext(InvalidOperation):
     281    """Invalid context.  Unknown rounding, for example.
     282
     283    This occurs and signals invalid-operation if an invalid context was
     284    detected during an operation. This can occur if contexts are not checked
     285    on creation and either the precision exceeds the capability of the
     286    underlying concrete representation or an unknown or unsupported rounding
     287    was specified. These aspects of the context need only be checked when
     288    the values are required to be used. The result is [0,qNaN].
     289    """
     290
     291    def handle(self, context, *args):
     292        return NaN
     293
     294class Rounded(DecimalException):
     295    """Number got rounded (not  necessarily changed during rounding).
     296
     297    This occurs and signals rounded whenever the result of an operation is
     298    rounded (that is, some zero or non-zero digits were discarded from the
     299    coefficient), or if an overflow or underflow condition occurs. The
     300    result in all cases is unchanged.
     301
     302    The rounded signal may be tested (or trapped) to determine if a given
     303    operation (or sequence of operations) caused a loss of precision.
     304    """
     305    pass
     306
     307class Subnormal(DecimalException):
     308    """Exponent < Emin before rounding.
     309
     310    This occurs and signals subnormal whenever the result of a conversion or
     311    operation is subnormal (that is, its adjusted exponent is less than
     312    Emin, before any rounding). The result in all cases is unchanged.
     313
     314    The subnormal signal may be tested (or trapped) to determine if a given
     315    or operation (or sequence of operations) yielded a subnormal result.
     316    """
     317    pass
     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 Infsign[sign]
     345        if sign == 0:
     346            if context.rounding == ROUND_CEILING:
     347                return Infsign[sign]
     348            return Decimal((sign, (9,)*context.prec,
     349                            context.Emax-context.prec+1))
     350        if sign == 1:
     351            if context.rounding == ROUND_FLOOR:
     352                return Infsign[sign]
     353            return Decimal( (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:
     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
     461
     462##### Decimal class ###########################################
     463
     464class Decimal(object):
     465    """Floating point class for decimal arithmetic."""
     466
     467    __slots__ = ('_exp','_int','_sign', '_is_special')
     468    # Generally, the value of the Decimal instance is given by
     469    #  (-1)**_sign * _int * 10**_exp
     470    # Special values are signified by _is_special == True
     471
     472    # We're immutable, so use __new__ not __init__
     473    def __new__(cls, value="0", context=None):
     474        """Create a decimal point instance.
     475
     476        >>> Decimal('3.14')              # string input
     477        Decimal("3.14")
     478        >>> Decimal((0, (3, 1, 4), -2))  # tuple input (sign, digit_tuple, exponent)
     479        Decimal("3.14")
     480        >>> Decimal(314)                 # int or long
     481        Decimal("314")
     482        >>> Decimal(Decimal(314))        # another decimal instance
     483        Decimal("314")
     484        """
     485
     486        self = object.__new__(cls)
     487        self._is_special = False
     488
     489        # From an internal working value
     490        if isinstance(value, _WorkRep):
     491            self._sign = value.sign
     492            self._int = tuple(map(int, str(value.int)))
     493            self._exp = int(value.exp)
     494            return self
     495
     496        # From another decimal
     497        if isinstance(value, Decimal):
     498            self._exp  = value._exp
     499            self._sign = value._sign
     500            self._int  = value._int
     501            self._is_special  = value._is_special
     502            return self
     503
     504        # From an integer
     505        if isinstance(value, (int,long)):
     506            if value >= 0:
     507                self._sign = 0
     508            else:
     509                self._sign = 1
     510            self._exp = 0
     511            self._int = tuple(map(int, str(abs(value))))
     512            return self
     513
     514        # tuple/list conversion (possibly from as_tuple())
     515        if isinstance(value, (list,tuple)):
     516            if len(value) != 3:
     517                raise ValueError, 'Invalid arguments'
     518            if value[0] not in [0,1]:
     519                raise ValueError, 'Invalid sign'
     520            for digit in value[1]:
     521                if not isinstance(digit, (int,long)) or digit < 0:
     522                    raise ValueError, "The second value in the tuple must be composed of non negative integer elements."
     523
     524            self._sign = value[0]
     525            self._int  = tuple(value[1])
     526            if value[2] in ('F','n','N'):
     527                self._exp = value[2]
     528                self._is_special = True
     529            else:
     530                self._exp  = int(value[2])
     531            return self
     532
     533        if isinstance(value, float):
     534            raise TypeError("Cannot convert float to Decimal.  " +
     535                            "First convert the float to a string")
     536
     537        # Other argument types may require the context during interpretation
     538        if context is None:
     539            context = getcontext()
     540
     541        # From a string
     542        # REs insist on real strings, so we can too.
     543        if isinstance(value, basestring):
     544            if _isinfinity(value):
     545                self._exp = 'F'
     546                self._int = (0,)
     547                self._is_special = True
     548                if _isinfinity(value) == 1:
     549                    self._sign = 0
     550                else:
     551                    self._sign = 1
     552                return self
     553            if _isnan(value):
     554                sig, sign, diag = _isnan(value)
     555                self._is_special = True
     556                if len(diag) > context.prec: #Diagnostic info too long
     557                    self._sign, self._int, self._exp = \
     558                                context._raise_error(ConversionSyntax)
     559                    return self
     560                if sig == 1:
     561                    self._exp = 'n' #qNaN
     562                else: #sig == 2
     563                    self._exp = 'N' #sNaN
     564                self._sign = sign
     565                self._int = tuple(map(int, diag)) #Diagnostic info
     566                return self
     567            try:
     568                self._sign, self._int, self._exp = _string2exact(value)
     569            except ValueError:
     570                self._is_special = True
     571                self._sign, self._int, self._exp = context._raise_error(ConversionSyntax)
     572            return self
     573
     574        raise TypeError("Cannot convert %r to Decimal" % value)
     575
     576    def _isnan(self):
     577        """Returns whether the number is not actually one.
     578
     579        0 if a number
     580        1 if NaN
     581        2 if sNaN
     582        """
     583        if self._is_special:
     584            exp = self._exp
     585            if exp == 'n':
     586                return 1
     587            elif exp == 'N':
     588                return 2
     589        return 0
     590
     591    def _isinfinity(self):
     592        """Returns whether the number is infinite
     593
     594        0 if finite or not a number
     595        1 if +INF
     596        -1 if -INF
     597        """
     598        if self._exp == 'F':
     599            if self._sign:
     600                return -1
     601            return 1
     602        return 0
     603
     604    def _check_nans(self, other = None, context=None):
     605        """Returns whether the number is not actually one.
     606
     607        if self, other are sNaN, signal
     608        if self, other are NaN return nan
     609        return 0
     610
     611        Done before operations.
     612        """
     613
     614        self_is_nan = self._isnan()
     615        if other is None:
     616            other_is_nan = False
     617        else:
     618            other_is_nan = other._isnan()
     619
     620        if self_is_nan or other_is_nan:
     621            if context is None:
     622                context = getcontext()
     623
     624            if self_is_nan == 2:
     625                return context._raise_error(InvalidOperation, 'sNaN',
     626                                        1, self)
     627            if other_is_nan == 2:
     628                return context._raise_error(InvalidOperation, 'sNaN',
     629                                        1, other)
     630            if self_is_nan:
     631                return self
     632
     633            return other
     634        return 0
     635
     636    def __nonzero__(self):
     637        """Is the number non-zero?
     638
     639        0 if self == 0
     640        1 if self != 0
     641        """
     642        if self._is_special:
     643            return 1
     644        return sum(self._int) != 0
     645
     646    def __cmp__(self, other, context=None):
     647        other = _convert_other(other)
     648        if other is NotImplemented:
     649            return other
     650
     651        if self._is_special or other._is_special:
     652            ans = self._check_nans(other, context)
     653            if ans:
     654                return 1 # Comparison involving NaN's always reports self > other
     655
     656            # INF = INF
     657            return cmp(self._isinfinity(), other._isinfinity())
     658
     659        if not self and not other:
     660            return 0 #If both 0, sign comparison isn't certain.
     661
     662        #If different signs, neg one is less
     663        if other._sign < self._sign:
     664            return -1
     665        if self._sign < other._sign:
     666            return 1
     667
     668        self_adjusted = self.adjusted()
     669        other_adjusted = other.adjusted()
     670        if self_adjusted == other_adjusted and \
     671           self._int + (0,)*(self._exp - other._exp) == \
     672           other._int + (0,)*(other._exp - self._exp):
     673            return 0 #equal, except in precision. ([0]*(-x) = [])
     674        elif self_adjusted > other_adjusted and self._int[0] != 0:
     675            return (-1)**self._sign
     676        elif self_adjusted < other_adjusted and other._int[0] != 0:
     677            return -((-1)**self._sign)
     678
     679        # Need to round, so make sure we have a valid context
     680        if context is None:
     681            context = getcontext()
     682
     683        context = context._shallow_copy()
     684        rounding = context._set_rounding(ROUND_UP) #round away from 0
     685
     686        flags = context._ignore_all_flags()
     687        res = self.__sub__(other, context=context)
     688
     689        context._regard_flags(*flags)
     690
     691        context.rounding = rounding
     692
     693        if not res:
     694            return 0
     695        elif res._sign:
     696            return -1
     697        return 1
     698
     699    def __eq__(self, other):
     700        if not isinstance(other, (Decimal, int, long)):
     701            return NotImplemented
     702        return self.__cmp__(other) == 0
     703
     704    def __ne__(self, other):
     705        if not isinstance(other, (Decimal, int, long)):
     706            return NotImplemented
     707        return self.__cmp__(other) != 0
     708
     709    def compare(self, other, context=None):
     710        """Compares one to another.
     711
     712        -1 => a < b
     713        0  => a = b
     714        1  => a > b
     715        NaN => one is NaN
     716        Like __cmp__, but returns Decimal instances.
     717        """
     718        other = _convert_other(other)
     719        if other is NotImplemented:
     720            return other
     721
     722        #compare(NaN, NaN) = NaN
     723        if (self._is_special or other and other._is_special):
     724            ans = self._check_nans(other, context)
     725            if ans:
     726                return ans
     727
     728        return Decimal(self.__cmp__(other, context))
     729
     730    def __hash__(self):
     731        """x.__hash__() <==> hash(x)"""
     732        # Decimal integers must hash the same as the ints
     733        # Non-integer decimals are normalized and hashed as strings
     734        # Normalization assures that hast(100E-1) == hash(10)
     735        if self._is_special:
     736            if self._isnan():
     737                raise TypeError('Cannot hash a NaN value.')
     738            return hash(str(self))
     739        i = int(self)
     740        if self == Decimal(i):
     741            return hash(i)
     742        assert self.__nonzero__()   # '-0' handled by integer case
     743        return hash(str(self.normalize()))
     744
     745    def as_tuple(self):
     746        """Represents the number as a triple tuple.
     747
     748        To show the internals exactly as they are.
     749        """
     750        return (self._sign, self._int, self._exp)
     751
     752    def __repr__(self):
     753        """Represents the number as an instance of Decimal."""
     754        # Invariant:  eval(repr(d)) == d
     755        return 'Decimal("%s")' % str(self)
     756
     757    def __str__(self, eng = 0, context=None):
     758        """Return string representation of the number in scientific notation.
     759
     760        Captures all of the information in the underlying representation.
     761        """
     762
     763        if self._isnan():
     764            minus = '-'*self._sign
     765            if self._int == (0,):
     766                info = ''
     767            else:
     768                info = ''.join(map(str, self._int))
     769            if self._isnan() == 2:
     770                return minus + 'sNaN' + info
     771            return minus + 'NaN' + info
     772        if self._isinfinity():
     773            minus = '-'*self._sign
     774            return minus + 'Infinity'
     775
     776        if context is None:
     777            context = getcontext()
     778
     779        tmp = map(str, self._int)
     780        numdigits = len(self._int)
     781        leftdigits = self._exp + numdigits
     782        if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY
     783            if self._exp < 0 and self._exp >= -6: #short, no need for e/E
     784                s = '-'*self._sign + '0.' + '0'*(abs(self._exp))
     785                return s
     786            #exp is closest mult. of 3 >= self._exp
     787            exp = ((self._exp - 1)// 3 + 1) * 3
     788            if exp != self._exp:
     789                s = '0.'+'0'*(exp - self._exp)
     790            else:
     791                s = '0'
     792            if exp != 0:
     793                if context.capitals:
     794                    s += 'E'
     795                else:
     796                    s += 'e'
     797                if exp > 0:
     798                    s += '+' #0.0e+3, not 0.0e3
     799                s += str(exp)
     800            s = '-'*self._sign + s
     801            return s
     802        if eng:
     803            dotplace = (leftdigits-1)%3+1
     804            adjexp = leftdigits -1 - (leftdigits-1)%3
     805        else:
     806            adjexp = leftdigits-1
     807            dotplace = 1
     808        if self._exp == 0:
     809            pass
     810        elif self._exp < 0 and adjexp >= 0:
     811            tmp.insert(leftdigits, '.')
     812        elif self._exp < 0 and adjexp >= -6:
     813            tmp[0:0] = ['0'] * int(-leftdigits)
     814            tmp.insert(0, '0.')
     815        else:
     816            if numdigits > dotplace:
     817                tmp.insert(dotplace, '.')
     818            elif numdigits < dotplace:
     819                tmp.extend(['0']*(dotplace-numdigits))
     820            if adjexp:
     821                if not context.capitals:
     822                    tmp.append('e')
     823                else:
     824                    tmp.append('E')
     825                    if adjexp > 0:
     826                        tmp.append('+')
     827                tmp.append(str(adjexp))
     828        if eng:
     829            while tmp[0:1] == ['0']:
     830                tmp[0:1] = []
     831            if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e':
     832                tmp[0:0] = ['0']
     833        if self._sign:
     834            tmp.insert(0, '-')
     835
     836        return ''.join(tmp)
     837
     838    def to_eng_string(self, context=None):
     839        """Convert to engineering-type string.
     840
     841        Engineering notation has an exponent which is a multiple of 3, so there
     842        are up to 3 digits left of the decimal place.
     843
     844        Same rules for when in exponential and when as a value as in __str__.
     845        """
     846        return self.__str__(eng=1, context=context)
     847
     848    def __neg__(self, context=None):
     849        """Returns a copy with the sign switched.
     850
     851        Rounds, if it has reason.
     852        """
     853        if self._is_special:
     854            ans = self._check_nans(context=context)
     855            if ans:
     856                return ans
     857
     858        if not self:
     859            # -Decimal('0') is Decimal('0'), not Decimal('-0')
     860            sign = 0
     861        elif self._sign:
     862            sign = 0
     863        else:
     864            sign = 1
     865
     866        if context is None:
     867            context = getcontext()
     868        if context._rounding_decision == ALWAYS_ROUND:
     869            return Decimal((sign, self._int, self._exp))._fix(context)
     870        return Decimal( (sign, self._int, self._exp))
     871
     872    def __pos__(self, context=None):
     873        """Returns a copy, unless it is a sNaN.
     874
     875        Rounds the number (if more then precision digits)
     876        """
     877        if self._is_special:
     878            ans = self._check_nans(context=context)
     879            if ans:
     880                return ans
     881
     882        sign = self._sign
     883        if not self:
     884            # + (-0) = 0
     885            sign = 0
     886
     887        if context is None:
     888            context = getcontext()
     889
     890        if context._rounding_decision == ALWAYS_ROUND:
     891            ans = self._fix(context)
     892        else:
     893            ans = Decimal(self)
     894        ans._sign = sign
     895        return ans
     896
     897    def __abs__(self, round=1, context=None):
     898        """Returns the absolute value of self.
     899
     900        If the second argument is 0, do not round.
     901        """
     902        if self._is_special:
     903            ans = self._check_nans(context=context)
     904            if ans:
     905                return ans
     906
     907        if not round:
     908            if context is None:
     909                context = getcontext()
     910            context = context._shallow_copy()
     911            context._set_rounding_decision(NEVER_ROUND)
     912
     913        if self._sign:
     914            ans = self.__neg__(context=context)
     915        else:
     916            ans = self.__pos__(context=context)
     917
     918        return ans
     919
     920    def __add__(self, other, context=None):
     921        """Returns self + other.
     922
     923        -INF + INF (or the reverse) cause InvalidOperation errors.
     924        """
     925        other = _convert_other(other)
     926        if other is NotImplemented:
     927            return other
     928
     929        if context is None:
     930            context = getcontext()
     931
     932        if self._is_special or other._is_special:
     933            ans = self._check_nans(other, context)
     934            if ans:
     935                return ans
     936
     937            if self._isinfinity():
     938                #If both INF, same sign => same as both, opposite => error.
     939                if self._sign != other._sign and other._isinfinity():
     940                    return context._raise_error(InvalidOperation, '-INF + INF')
     941                return Decimal(self)
     942            if other._isinfinity():
     943                return Decimal(other)  #Can't both be infinity here
     944
     945        shouldround = context._rounding_decision == ALWAYS_ROUND
     946
     947        exp = min(self._exp, other._exp)
     948        negativezero = 0
     949        if context.rounding == ROUND_FLOOR and self._sign != other._sign:
     950            #If the answer is 0, the sign should be negative, in this case.
     951            negativezero = 1
     952
     953        if not self and not other:
     954            sign = min(self._sign, other._sign)
     955            if negativezero:
     956                sign = 1
     957            return Decimal( (sign, (0,), exp))
     958        if not self:
     959            exp = max(exp, other._exp - context.prec-1)
     960            ans = other._rescale(exp, watchexp=0, context=context)
     961            if shouldround:
     962                ans = ans._fix(context)
     963            return ans
     964        if not other:
     965            exp = max(exp, self._exp - context.prec-1)
     966            ans = self._rescale(exp, watchexp=0, context=context)
     967            if shouldround:
     968                ans = ans._fix(context)
     969            return ans
     970
     971        op1 = _WorkRep(self)
     972        op2 = _WorkRep(other)
     973        op1, op2 = _normalize(op1, op2, shouldround, context.prec)
     974
     975        result = _WorkRep()
     976        if op1.sign != op2.sign:
     977            # Equal and opposite
     978            if op1.int == op2.int:
     979                if exp < context.Etiny():
     980                    exp = context.Etiny()
     981                    context._raise_error(Clamped)
     982                return Decimal((negativezero, (0,), exp))
     983            if op1.int < op2.int:
     984                op1, op2 = op2, op1
     985                #OK, now abs(op1) > abs(op2)
     986            if op1.sign == 1:
     987                result.sign = 1
     988                op1.sign, op2.sign = op2.sign, op1.sign
     989            else:
     990                result.sign = 0
     991                #So we know the sign, and op1 > 0.
     992        elif op1.sign == 1:
     993            result.sign = 1
     994            op1.sign, op2.sign = (0, 0)
     995        else:
     996            result.sign = 0
     997        #Now, op1 > abs(op2) > 0
     998
     999        if op2.sign == 0:
     1000            result.int = op1.int + op2.int
     1001        else:
     1002            result.int = op1.int - op2.int
     1003
     1004        result.exp = op1.exp
     1005        ans = Decimal(result)
     1006        if shouldround:
     1007            ans = ans._fix(context)
     1008        return ans
     1009
     1010    __radd__ = __add__
     1011
     1012    def __sub__(self, other, context=None):
     1013        """Return self + (-other)"""
     1014        other = _convert_other(other)
     1015        if other is NotImplemented:
     1016            return other
     1017
     1018        if self._is_special or other._is_special:
     1019            ans = self._check_nans(other, context=context)
     1020            if ans:
     1021                return ans
     1022
     1023        # -Decimal(0) = Decimal(0), which we don't want since
     1024        # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.)
     1025        # so we change the sign directly to a copy
     1026        tmp = Decimal(other)
     1027        tmp._sign = 1-tmp._sign
     1028
     1029        return self.__add__(tmp, context=context)
     1030
     1031    def __rsub__(self, other, context=None):
     1032        """Return other + (-self)"""
     1033        other = _convert_other(other)
     1034        if other is NotImplemented:
     1035            return other
     1036
     1037        tmp = Decimal(self)
     1038        tmp._sign = 1 - tmp._sign
     1039        return other.__add__(tmp, context=context)
     1040
     1041    def _increment(self, round=1, context=None):
     1042        """Special case of add, adding 1eExponent
     1043
     1044        Since it is common, (rounding, for example) this adds
     1045        (sign)*one E self._exp to the number more efficiently than add.
     1046
     1047        For example:
     1048        Decimal('5.624e10')._increment() == Decimal('5.625e10')
     1049        """
     1050        if self._is_special:
     1051            ans = self._check_nans(context=context)
     1052            if ans:
     1053                return ans
     1054
     1055            return Decimal(self) # Must be infinite, and incrementing makes no difference
     1056
     1057        L = list(self._int)
     1058        L[-1] += 1
     1059        spot = len(L)-1
     1060        while L[spot] == 10:
     1061            L[spot] = 0
     1062            if spot == 0:
     1063                L[0:0] = [1]
     1064                break
     1065            L[spot-1] += 1
     1066            spot -= 1
     1067        ans = Decimal((self._sign, L, self._exp))
     1068
     1069        if context is None:
     1070            context = getcontext()
     1071        if round and context._rounding_decision == ALWAYS_ROUND:
     1072            ans = ans._fix(context)
     1073        return ans
     1074
     1075    def __mul__(self, other, context=None):
     1076        """Return self * other.
     1077
     1078        (+-) INF * 0 (or its reverse) raise InvalidOperation.
     1079        """
     1080        other = _convert_other(other)
     1081        if other is NotImplemented:
     1082            return other
     1083
     1084        if context is None:
     1085            context = getcontext()
     1086
     1087        resultsign = self._sign ^ other._sign
     1088
     1089        if self._is_special or other._is_special:
     1090            ans = self._check_nans(other, context)
     1091            if ans:
     1092                return ans
     1093
     1094            if self._isinfinity():
     1095                if not other:
     1096                    return context._raise_error(InvalidOperation, '(+-)INF * 0')
     1097                return Infsign[resultsign]
     1098
     1099            if other._isinfinity():
     1100                if not self:
     1101                    return context._raise_error(InvalidOperation, '0 * (+-)INF')
     1102                return Infsign[resultsign]
     1103
     1104        resultexp = self._exp + other._exp
     1105        shouldround = context._rounding_decision == ALWAYS_ROUND
     1106
     1107        # Special case for multiplying by zero
     1108        if not self or not other:
     1109            ans = Decimal((resultsign, (0,), resultexp))
     1110            if shouldround:
     1111                #Fixing in case the exponent is out of bounds
     1112                ans = ans._fix(context)
     1113            return ans
     1114
     1115        # Special case for multiplying by power of 10
     1116        if self._int == (1,):
     1117            ans = Decimal((resultsign, other._int, resultexp))
     1118            if shouldround:
     1119                ans = ans._fix(context)
     1120            return ans
     1121        if other._int == (1,):
     1122            ans = Decimal((resultsign, self._int, resultexp))
     1123            if shouldround:
     1124                ans = ans._fix(context)
     1125            return ans
     1126
     1127        op1 = _WorkRep(self)
     1128        op2 = _WorkRep(other)
     1129
     1130        ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp))
     1131        if shouldround:
     1132            ans = ans._fix(context)
     1133
     1134        return ans
     1135    __rmul__ = __mul__
     1136
     1137    def __div__(self, other, context=None):
     1138        """Return self / other."""
     1139        return self._divide(other, context=context)
     1140    __truediv__ = __div__
     1141
     1142    def _divide(self, other, divmod = 0, context=None):
     1143        """Return a / b, to context.prec precision.
     1144
     1145        divmod:
     1146        0 => true division
     1147        1 => (a //b, a%b)
     1148        2 => a //b
     1149        3 => a%b
     1150
     1151        Actually, if divmod is 2 or 3 a tuple is returned, but errors for
     1152        computing the other value are not raised.
     1153        """
     1154        other = _convert_other(other)
     1155        if other is NotImplemented:
     1156            if divmod in (0, 1):
     1157                return NotImplemented
     1158            return (NotImplemented, NotImplemented)
     1159
     1160        if context is None:
     1161            context = getcontext()
     1162
     1163        sign = self._sign ^ other._sign
     1164
     1165        if self._is_special or other._is_special:
     1166            ans = self._check_nans(other, context)
     1167            if ans:
     1168                if divmod:
     1169                    return (ans, ans)
     1170                return ans
     1171
     1172            if self._isinfinity() and other._isinfinity():
     1173                if divmod:
     1174                    return (context._raise_error(InvalidOperation,
     1175                                            '(+-)INF // (+-)INF'),
     1176                            context._raise_error(InvalidOperation,
     1177                                            '(+-)INF % (+-)INF'))
     1178                return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF')
     1179
     1180            if self._isinfinity():
     1181                if divmod == 1:
     1182                    return (Infsign[sign],
     1183                            context._raise_error(InvalidOperation, 'INF % x'))
     1184                elif divmod == 2:
     1185                    return (Infsign[sign], NaN)
     1186                elif divmod == 3:
     1187                    return (Infsign[sign],
     1188                            context._raise_error(InvalidOperation, 'INF % x'))
     1189                return Infsign[sign]
     1190
     1191            if other._isinfinity():
     1192                if divmod:
     1193                    return (Decimal((sign, (0,), 0)), Decimal(self))
     1194                context._raise_error(Clamped, 'Division by infinity')
     1195                return Decimal((sign, (0,), context.Etiny()))
     1196
     1197        # Special cases for zeroes
     1198        if not self and not other:
     1199            if divmod:
     1200                return context._raise_error(DivisionUndefined, '0 / 0', 1)
     1201            return context._raise_error(DivisionUndefined, '0 / 0')
     1202
     1203        if not self:
     1204            if divmod:
     1205                otherside = Decimal(self)
     1206                otherside._exp = min(self._exp, other._exp)
     1207                return (Decimal((sign, (0,), 0)),  otherside)
     1208            exp = self._exp - other._exp
     1209            if exp < context.Etiny():
     1210                exp = context.Etiny()
     1211                context._raise_error(Clamped, '0e-x / y')
     1212            if exp > context.Emax:
     1213                exp = context.Emax
     1214                context._raise_error(Clamped, '0e+x / y')
     1215            return Decimal( (sign, (0,), exp) )
     1216
     1217        if not other:
     1218            if divmod:
     1219                return context._raise_error(DivisionByZero, 'divmod(x,0)',
     1220                                           sign, 1)
     1221            return context._raise_error(DivisionByZero, 'x / 0', sign)
     1222
     1223        #OK, so neither = 0, INF or NaN
     1224
     1225        shouldround = context._rounding_decision == ALWAYS_ROUND
     1226
     1227        #If we're dividing into ints, and self < other, stop.
     1228        #self.__abs__(0) does not round.
     1229        if divmod and (self.__abs__(0, context) < other.__abs__(0, context)):
     1230
     1231            if divmod == 1 or divmod == 3:
     1232                exp = min(self._exp, other._exp)
     1233                ans2 = self._rescale(exp, context=context, watchexp=0)
     1234                if shouldround:
     1235                    ans2 = ans2._fix(context)
     1236                return (Decimal( (sign, (0,), 0) ),
     1237                        ans2)
     1238
     1239            elif divmod == 2:
     1240                #Don't round the mod part, if we don't need it.
     1241                return (Decimal( (sign, (0,), 0) ), Decimal(self))
     1242
     1243        op1 = _WorkRep(self)
     1244        op2 = _WorkRep(other)
     1245        op1, op2, adjust = _adjust_coefficients(op1, op2)
     1246        res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) )
     1247        if divmod and res.exp > context.prec + 1:
     1248            return context._raise_error(DivisionImpossible)
     1249
     1250        prec_limit = 10 ** context.prec
     1251        while 1:
     1252            while op2.int <= op1.int:
     1253                res.int += 1
     1254                op1.int -= op2.int
     1255            if res.exp == 0 and divmod:
     1256                if res.int >= prec_limit and shouldround:
     1257                    return context._raise_error(DivisionImpossible)
     1258                otherside = Decimal(op1)
     1259                frozen = context._ignore_all_flags()
     1260
     1261                exp = min(self._exp, other._exp)
     1262                otherside = otherside._rescale(exp, context=context, watchexp=0)
     1263                context._regard_flags(*frozen)
     1264                if shouldround:
     1265                    otherside = otherside._fix(context)
     1266                return (Decimal(res), otherside)
     1267
     1268            if op1.int == 0 and adjust >= 0 and not divmod:
     1269                break
     1270            if res.int >= prec_limit and shouldround:
     1271                if divmod:
     1272                    return context._raise_error(DivisionImpossible)
     1273                shouldround=1
     1274                # Really, the answer is a bit higher, so adding a one to
     1275                # the end will make sure the rounding is right.
     1276                if op1.int != 0:
     1277                    res.int *= 10
     1278                    res.int += 1
     1279                    res.exp -= 1
     1280
     1281                break
     1282            res.int *= 10
     1283            res.exp -= 1
     1284            adjust += 1
     1285            op1.int *= 10
     1286            op1.exp -= 1
     1287
     1288            if res.exp == 0 and divmod and op2.int > op1.int:
     1289                #Solves an error in precision.  Same as a previous block.
     1290
     1291                if res.int >= prec_limit and shouldround:
     1292                    return context._raise_error(DivisionImpossible)
     1293                otherside = Decimal(op1)
     1294                frozen = context._ignore_all_flags()
     1295
     1296                exp = min(self._exp, other._exp)
     1297                otherside = otherside._rescale(exp, context=context)
     1298
     1299                context._regard_flags(*frozen)
     1300
     1301                return (Decimal(res), otherside)
     1302
     1303        ans = Decimal(res)
     1304        if shouldround:
     1305            ans = ans._fix(context)
     1306        return ans
     1307
     1308    def __rdiv__(self, other, context=None):
     1309        """Swaps self/other and returns __div__."""
     1310        other = _convert_other(other)
     1311        if other is NotImplemented:
     1312            return other
     1313        return other.__div__(self, context=context)
     1314    __rtruediv__ = __rdiv__
     1315
     1316    def __divmod__(self, other, context=None):
     1317        """
     1318        (self // other, self % other)
     1319        """
     1320        return self._divide(other, 1, context)
     1321
     1322    def __rdivmod__(self, other, context=None):
     1323        """Swaps self/other and returns __divmod__."""
     1324        other = _convert_other(other)
     1325        if other is NotImplemented:
     1326            return other
     1327        return other.__divmod__(self, context=context)
     1328
     1329    def __mod__(self, other, context=None):
     1330        """
     1331        self % other
     1332        """
     1333        other = _convert_other(other)
     1334        if other is NotImplemented:
     1335            return other
     1336
     1337        if self._is_special or other._is_special:
     1338            ans = self._check_nans(other, context)
     1339            if ans:
     1340                return ans
     1341
     1342        if self and not other:
     1343            return context._raise_error(InvalidOperation, 'x % 0')
     1344
     1345        return self._divide(other, 3, context)[1]
     1346
     1347    def __rmod__(self, other, context=None):
     1348        """Swaps self/other and returns __mod__."""
     1349        other = _convert_other(other)
     1350        if other is NotImplemented:
     1351            return other
     1352        return other.__mod__(self, context=context)
     1353
     1354    def remainder_near(self, other, context=None):
     1355        """
     1356        Remainder nearest to 0-  abs(remainder-near) <= other/2
     1357        """
     1358        other = _convert_other(other)
     1359        if other is NotImplemented:
     1360            return other
     1361
     1362        if self._is_special or other._is_special:
     1363            ans = self._check_nans(other, context)
     1364            if ans:
     1365                return ans
     1366        if self and not other:
     1367            return context._raise_error(InvalidOperation, 'x % 0')
     1368
     1369        if context is None:
     1370            context = getcontext()
     1371        # If DivisionImpossible causes an error, do not leave Rounded/Inexact
     1372        # ignored in the calling function.
     1373        context = context._shallow_copy()
     1374        flags = context._ignore_flags(Rounded, Inexact)
     1375        #keep DivisionImpossible flags
     1376        (side, r) = self.__divmod__(other, context=context)
     1377
     1378        if r._isnan():
     1379            context._regard_flags(*flags)
     1380            return r
     1381
     1382        context = context._shallow_copy()
     1383        rounding = context._set_rounding_decision(NEVER_ROUND)
     1384
     1385        if other._sign:
     1386            comparison = other.__div__(Decimal(-2), context=context)
     1387        else:
     1388            comparison = other.__div__(Decimal(2), context=context)
     1389
     1390        context._set_rounding_decision(rounding)
     1391        context._regard_flags(*flags)
     1392
     1393        s1, s2 = r._sign, comparison._sign
     1394        r._sign, comparison._sign = 0, 0
     1395
     1396        if r < comparison:
     1397            r._sign, comparison._sign = s1, s2
     1398            #Get flags now
     1399            self.__divmod__(other, context=context)
     1400            return r._fix(context)
     1401        r._sign, comparison._sign = s1, s2
     1402
     1403        rounding = context._set_rounding_decision(NEVER_ROUND)
     1404
     1405        (side, r) = self.__divmod__(other, context=context)
     1406        context._set_rounding_decision(rounding)
     1407        if r._isnan():
     1408            return r
     1409
     1410        decrease = not side._iseven()
     1411        rounding = context._set_rounding_decision(NEVER_ROUND)
     1412        side = side.__abs__(context=context)
     1413        context._set_rounding_decision(rounding)
     1414
     1415        s1, s2 = r._sign, comparison._sign
     1416        r._sign, comparison._sign = 0, 0
     1417        if r > comparison or decrease and r == comparison:
     1418            r._sign, comparison._sign = s1, s2
     1419            context.prec += 1
     1420            if len(side.__add__(Decimal(1), context=context)._int) >= context.prec:
     1421                context.prec -= 1
     1422                return context._raise_error(DivisionImpossible)[1]
     1423            context.prec -= 1
     1424            if self._sign == other._sign:
     1425                r = r.__sub__(other, context=context)
     1426            else:
     1427                r = r.__add__(other, context=context)
     1428        else:
     1429            r._sign, comparison._sign = s1, s2
     1430
     1431        return r._fix(context)
     1432
     1433    def __floordiv__(self, other, context=None):
     1434        """self // other"""
     1435        return self._divide(other, 2, context)[0]
     1436
     1437    def __rfloordiv__(self, other, context=None):
     1438        """Swaps self/other and returns __floordiv__."""
     1439        other = _convert_other(other)
     1440        if other is NotImplemented:
     1441            return other
     1442        return other.__floordiv__(self, context=context)
     1443
     1444    def __float__(self):
     1445        """Float representation."""
     1446        return float(str(self))
     1447
     1448    def __int__(self):
     1449        """Converts self to a int, truncating if necessary."""
     1450        if self._is_special:
     1451            if self._isnan():
     1452                context = getcontext()
     1453                return context._raise_error(InvalidContext)
     1454            elif self._isinfinity():
     1455                raise OverflowError, "Cannot convert infinity to long"
     1456        if self._exp >= 0:
     1457            s = ''.join(map(str, self._int)) + '0'*self._exp
     1458        else:
     1459            s = ''.join(map(str, self._int))[:self._exp]
     1460        if s == '':
     1461            s = '0'
     1462        sign = '-'*self._sign
     1463        return int(sign + s)
     1464
     1465    def __long__(self):
     1466        """Converts to a long.
     1467
     1468        Equivalent to long(int(self))
     1469        """
     1470        return long(self.__int__())
     1471
     1472    def _fix(self, context):
     1473        """Round if it is necessary to keep self within prec precision.
     1474
     1475        Rounds and fixes the exponent.  Does not raise on a sNaN.
     1476
     1477        Arguments:
     1478        self - Decimal instance
     1479        context - context used.
     1480        """
     1481        if self._is_special:
     1482            return self
     1483        if context is None:
     1484            context = getcontext()
     1485        prec = context.prec
     1486        ans = self._fixexponents(context)
     1487        if len(ans._int) > prec:
     1488            ans = ans._round(prec, context=context)
     1489            ans = ans._fixexponents(context)
     1490        return ans
     1491
     1492    def _fixexponents(self, context):
     1493        """Fix the exponents and return a copy with the exponent in bounds.
     1494        Only call if known to not be a special value.
     1495        """
     1496        folddown = context._clamp
     1497        Emin = context.Emin
     1498        ans = self
     1499        ans_adjusted = ans.adjusted()
     1500        if ans_adjusted < Emin:
     1501            Etiny = context.Etiny()
     1502            if ans._exp < Etiny:
     1503                if not ans:
     1504                    ans = Decimal(self)
     1505                    ans._exp = Etiny
     1506                    context._raise_error(Clamped)
     1507                    return ans
     1508                ans = ans._rescale(Etiny, context=context)
     1509                #It isn't zero, and exp < Emin => subnormal
     1510                context._raise_error(Subnormal)
     1511                if context.flags[Inexact]:
     1512                    context._raise_error(Underflow)
     1513            else:
     1514                if ans:
     1515                    #Only raise subnormal if non-zero.
     1516                    context._raise_error(Subnormal)
     1517        else:
     1518            Etop = context.Etop()
     1519            if folddown and ans._exp > Etop:
     1520                context._raise_error(Clamped)
     1521                ans = ans._rescale(Etop, context=context)
     1522            else:
     1523                Emax = context.Emax
     1524                if ans_adjusted > Emax:
     1525                    if not ans:
     1526                        ans = Decimal(self)
     1527                        ans._exp = Emax
     1528                        context._raise_error(Clamped)
     1529                        return ans
     1530                    context._raise_error(Inexact)
     1531                    context._raise_error(Rounded)
     1532                    return context._raise_error(Overflow, 'above Emax', ans._sign)
     1533        return ans
     1534
     1535    def _round(self, prec=None, rounding=None, context=None):
     1536        """Returns a rounded version of self.
     1537
     1538        You can specify the precision or rounding method.  Otherwise, the
     1539        context determines it.
     1540        """
     1541
     1542        if self._is_special:
     1543            ans = self._check_nans(context=context)
     1544            if ans:
     1545                return ans
     1546
     1547            if self._isinfinity():
     1548                return Decimal(self)
     1549
     1550        if context is None:
     1551            context = getcontext()
     1552
     1553        if rounding is None:
     1554            rounding = context.rounding
     1555        if prec is None:
     1556            prec = context.prec
     1557
     1558        if not self:
     1559            if prec <= 0:
     1560                dig = (0,)
     1561                exp = len(self._int) - prec + self._exp
     1562            else:
     1563                dig = (0,) * prec
     1564                exp = len(self._int) + self._exp - prec
     1565            ans = Decimal((self._sign, dig, exp))
     1566            context._raise_error(Rounded)
     1567            return ans
     1568
     1569        if prec == 0:
     1570            temp = Decimal(self)
     1571            temp._int = (0,)+temp._int
     1572            prec = 1
     1573        elif prec < 0:
     1574            exp = self._exp + len(self._int) - prec - 1
     1575            temp = Decimal( (self._sign, (0, 1), exp))
     1576            prec = 1
     1577        else:
     1578            temp = Decimal(self)
     1579
     1580        numdigits = len(temp._int)
     1581        if prec == numdigits:
     1582            return temp
     1583
     1584        # See if we need to extend precision
     1585        expdiff = prec - numdigits
     1586        if expdiff > 0:
     1587            tmp = list(temp._int)
     1588            tmp.extend([0] * expdiff)
     1589            ans =  Decimal( (temp._sign, tmp, temp._exp - expdiff))
     1590            return ans
     1591
     1592        #OK, but maybe all the lost digits are 0.
     1593        lostdigits = self._int[expdiff:]
     1594        if lostdigits == (0,) * len(lostdigits):
     1595            ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff))
     1596            #Rounded, but not Inexact
     1597            context._raise_error(Rounded)
     1598            return ans
     1599
     1600        # Okay, let's round and lose data
     1601
     1602        this_function = getattr(temp, self._pick_rounding_function[rounding])
     1603        #Now we've got the rounding function
     1604
     1605        if prec != context.prec:
     1606            context = context._shallow_copy()
     1607            context.prec = prec
     1608        ans = this_function(prec, expdiff, context)
     1609        context._raise_error(Rounded)
     1610        context._raise_error(Inexact, 'Changed in rounding')
     1611
     1612        return ans
     1613
     1614    _pick_rounding_function = {}
     1615
     1616    def _round_down(self, prec, expdiff, context):
     1617        """Also known as round-towards-0, truncate."""
     1618        return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
     1619
     1620    def _round_half_up(self, prec, expdiff, context, tmp = None):
     1621        """Rounds 5 up (away from 0)"""
     1622
     1623        if tmp is None:
     1624            tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff))
     1625        if self._int[prec] >= 5:
     1626            tmp = tmp._increment(round=0, context=context)
     1627            if len(tmp._int) > prec:
     1628                return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
     1629        return tmp
     1630
     1631    def _round_half_even(self, prec, expdiff, context):
     1632        """Round 5 to even, rest to nearest."""
     1633
     1634        tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
     1635        half = (self._int[prec] == 5)
     1636        if half:
     1637            for digit in self._int[prec+1:]:
     1638                if digit != 0:
     1639                    half = 0
     1640                    break
     1641        if half:
     1642            if self._int[prec-1] & 1 == 0:
     1643                return tmp
     1644        return self._round_half_up(prec, expdiff, context, tmp)
     1645
     1646    def _round_half_down(self, prec, expdiff, context):
     1647        """Round 5 down"""
     1648
     1649        tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff))
     1650        half = (self._int[prec] == 5)
     1651        if half:
     1652            for digit in self._int[prec+1:]:
     1653                if digit != 0:
     1654                    half = 0
     1655                    break
     1656        if half:
     1657            return tmp
     1658        return self._round_half_up(prec, expdiff, context, tmp)
     1659
     1660    def _round_up(self, prec, expdiff, context):
     1661        """Rounds away from 0."""
     1662        tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) )
     1663        for digit in self._int[prec:]:
     1664            if digit != 0:
     1665                tmp = tmp._increment(round=1, context=context)
     1666                if len(tmp._int) > prec:
     1667                    return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1))
     1668                else:
     1669                    return tmp
     1670        return tmp
     1671
     1672    def _round_ceiling(self, prec, expdiff, context):
     1673        """Rounds up (not away from 0 if negative.)"""
     1674        if self._sign:
     1675            return self._round_down(prec, expdiff, context)
     1676        else:
     1677            return self._round_up(prec, expdiff, context)
     1678
     1679    def _round_floor(self, prec, expdiff, context):
     1680        """Rounds down (not towards 0 if negative)"""
     1681        if not self._sign:
     1682            return self._round_down(prec, expdiff, context)
     1683        else:
     1684            return self._round_up(prec, expdiff, context)
     1685
     1686    def __pow__(self, n, modulo = None, context=None):
     1687        """Return self ** n (mod modulo)
     1688
     1689        If modulo is None (default), don't take it mod modulo.
     1690        """
     1691        n = _convert_other(n)
     1692        if n is NotImplemented:
     1693            return n
     1694
     1695        if context is None:
     1696            context = getcontext()
     1697
     1698        if self._is_special or n._is_special or n.adjusted() > 8:
     1699            #Because the spot << doesn't work with really big exponents
     1700            if n._isinfinity() or n.adjusted() > 8:
     1701                return context._raise_error(InvalidOperation, 'x ** INF')
     1702
     1703            ans = self._check_nans(n, context)
     1704            if ans:
     1705                return ans
     1706
     1707        if not n._isinteger():
     1708            return context._raise_error(InvalidOperation, 'x ** (non-integer)')
     1709
     1710        if not self and not n:
     1711            return context._raise_error(InvalidOperation, '0 ** 0')
     1712
     1713        if not n:
     1714            return Decimal(1)
     1715
     1716        if self == Decimal(1):
     1717            return Decimal(1)
     1718
     1719        sign = self._sign and not n._iseven()
     1720        n = int(n)
     1721
     1722        if self._isinfinity():
     1723            if modulo:
     1724                return context._raise_error(InvalidOperation, 'INF % x')
     1725            if n > 0:
     1726                return Infsign[sign]
     1727            return Decimal( (sign, (0,), 0) )
     1728
     1729        #with ludicrously large exponent, just raise an overflow and return inf.
     1730        if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \
     1731           and self:
     1732
     1733            tmp = Decimal('inf')
     1734            tmp._sign = sign
     1735            context._raise_error(Rounded)
     1736            context._raise_error(Inexact)
     1737            context._raise_error(Overflow, 'Big power', sign)
     1738            return tmp
     1739
     1740        elength = len(str(abs(n)))
     1741        firstprec = context.prec
     1742
     1743        if not modulo and firstprec + elength + 1 > DefaultContext.Emax:
     1744            return context._raise_error(Overflow, 'Too much precision.', sign)
     1745
     1746        mul = Decimal(self)
     1747        val = Decimal(1)
     1748        context = context._shallow_copy()
     1749        context.prec = firstprec + elength + 1
     1750        if n < 0:
     1751            #n is a long now, not Decimal instance
     1752            n = -n
     1753            mul = Decimal(1).__div__(mul, context=context)
     1754
     1755        spot = 1
     1756        while spot <= n:
     1757            spot <<= 1
     1758
     1759        spot >>= 1
     1760        #Spot is the highest power of 2 less than n
     1761        while spot:
     1762            val = val.__mul__(val, context=context)
     1763            if val._isinfinity():
     1764                val = Infsign[sign]
     1765                break
     1766            if spot & n:
     1767                val = val.__mul__(mul, context=context)
     1768            if modulo is not None:
     1769                val = val.__mod__(modulo, context=context)
     1770            spot >>= 1
     1771        context.prec = firstprec
     1772
     1773        if context._rounding_decision == ALWAYS_ROUND:
     1774            return val._fix(context)
     1775        return val
     1776
     1777    def __rpow__(self, other, context=None):
     1778        """Swaps self/other and returns __pow__."""
     1779        other = _convert_other(other)
     1780        if other is NotImplemented:
     1781            return other
     1782        return other.__pow__(self, context=context)
     1783
     1784    def normalize(self, context=None):
     1785        """Normalize- strip trailing 0s, change anything equal to 0 to 0e0"""
     1786
     1787        if self._is_special:
     1788            ans = self._check_nans(context=context)
     1789            if ans:
     1790                return ans
     1791
     1792        dup = self._fix(context)
     1793        if dup._isinfinity():
     1794            return dup
     1795
     1796        if not dup:
     1797            return Decimal( (dup._sign, (0,), 0) )
     1798        end = len(dup._int)
     1799        exp = dup._exp
     1800        while dup._int[end-1] == 0:
     1801            exp += 1
     1802            end -= 1
     1803        return Decimal( (dup._sign, dup._int[:end], exp) )
     1804
     1805
     1806    def quantize(self, exp, rounding=None, context=None, watchexp=1):
     1807        """Quantize self so its exponent is the same as that of exp.
     1808
     1809        Similar to self._rescale(exp._exp) but with error checking.
     1810        """
     1811        if self._is_special or exp._is_special:
     1812            ans = self._check_nans(exp, context)
     1813            if ans:
     1814                return ans
     1815
     1816            if exp._isinfinity() or self._isinfinity():
     1817                if exp._isinfinity() and self._isinfinity():
     1818                    return self  #if both are inf, it is OK
     1819                if context is None:
     1820                    context = getcontext()
     1821                return context._raise_error(InvalidOperation,
     1822                                        'quantize with one INF')
     1823        return self._rescale(exp._exp, rounding, context, watchexp)
     1824
     1825    def same_quantum(self, other):
     1826        """Test whether self and other have the same exponent.
     1827
     1828        same as self._exp == other._exp, except NaN == sNaN
     1829        """
     1830        if self._is_special or other._is_special:
     1831            if self._isnan() or other._isnan():
     1832                return self._isnan() and other._isnan() and True
     1833            if self._isinfinity() or other._isinfinity():
     1834                return self._isinfinity() and other._isinfinity() and True
     1835        return self._exp == other._exp
     1836
     1837    def _rescale(self, exp, rounding=None, context=None, watchexp=1):
     1838        """Rescales so that the exponent is exp.
     1839
     1840        exp = exp to scale to (an integer)
     1841        rounding = rounding version
     1842        watchexp: if set (default) an error is returned if exp is greater
     1843        than Emax or less than Etiny.
     1844        """
     1845        if context is None:
     1846            context = getcontext()
     1847
     1848        if self._is_special:
     1849            if self._isinfinity():
     1850                return context._raise_error(InvalidOperation, 'rescale with an INF')
     1851
     1852            ans = self._check_nans(context=context)
     1853            if ans:
     1854                return ans
     1855
     1856        if watchexp and (context.Emax  < exp or context.Etiny() > exp):
     1857            return context._raise_error(InvalidOperation, 'rescale(a, INF)')
     1858
     1859        if not self:
     1860            ans = Decimal(self)
     1861            ans._int = (0,)
     1862            ans._exp = exp
     1863            return ans
     1864
     1865        diff = self._exp - exp
     1866        digits = len(self._int) + diff
     1867
     1868        if watchexp and digits > context.prec:
     1869            return context._raise_error(InvalidOperation, 'Rescale > prec')
     1870
     1871        tmp = Decimal(self)
     1872        tmp._int = (0,) + tmp._int
     1873        digits += 1
     1874
     1875        if digits < 0:
     1876            tmp._exp = -digits + tmp._exp
     1877            tmp._int = (0,1)
     1878            digits = 1
     1879        tmp = tmp._round(digits, rounding, context=context)
     1880
     1881        if tmp._int[0] == 0 and len(tmp._int) > 1:
     1882            tmp._int = tmp._int[1:]
     1883        tmp._exp = exp
     1884
     1885        tmp_adjusted = tmp.adjusted()
     1886        if tmp and tmp_adjusted < context.Emin:
     1887            context._raise_error(Subnormal)
     1888        elif tmp and tmp_adjusted > context.Emax:
     1889            return context._raise_error(InvalidOperation, 'rescale(a, INF)')
     1890        return tmp
     1891
     1892    def to_integral(self, rounding=None, context=None):
     1893        """Rounds to the nearest integer, without raising inexact, rounded."""
     1894        if self._is_special:
     1895            ans = self._check_nans(context=context)
     1896            if ans:
     1897                return ans
     1898        if self._exp >= 0:
     1899            return self
     1900        if context is None:
     1901            context = getcontext()
     1902        flags = context._ignore_flags(Rounded, Inexact)
     1903        ans = self._rescale(0, rounding, context=context)
     1904        context._regard_flags(flags)
     1905        return ans
     1906
     1907    def sqrt(self, context=None):
     1908        """Return the square root of self.
     1909
     1910        Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn))
     1911        Should quadratically approach the right answer.
     1912        """
     1913        if self._is_special:
     1914            ans = self._check_nans(context=context)
     1915            if ans:
     1916                return ans
     1917
     1918            if self._isinfinity() and self._sign == 0:
     1919                return Decimal(self)
     1920
     1921        if not self:
     1922            #exponent = self._exp / 2, using round_down.
     1923            #if self._exp < 0:
     1924            #    exp = (self._exp+1) // 2
     1925            #else:
     1926            exp = (self._exp) // 2
     1927            if self._sign == 1:
     1928                #sqrt(-0) = -0
     1929                return Decimal( (1, (0,), exp))
     1930            else:
     1931                return Decimal( (0, (0,), exp))
     1932
     1933        if context is None:
     1934            context = getcontext()
     1935
     1936        if self._sign == 1:
     1937            return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0')
     1938
     1939        tmp = Decimal(self)
     1940
     1941        expadd = tmp._exp // 2
     1942        if tmp._exp & 1:
     1943            tmp._int += (0,)
     1944            tmp._exp = 0
     1945        else:
     1946            tmp._exp = 0
     1947
     1948        context = context._shallow_copy()
     1949        flags = context._ignore_all_flags()
     1950        firstprec = context.prec
     1951        context.prec = 3
     1952        if tmp.adjusted() & 1 == 0:
     1953            ans = Decimal( (0, (8,1,9), tmp.adjusted()  - 2) )
     1954            ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)),
     1955                                          context=context), context=context)
     1956            ans._exp -= 1 + tmp.adjusted() // 2
     1957        else:
     1958            ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) )
     1959            ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)),
     1960                                          context=context), context=context)
     1961            ans._exp -= 1 + tmp.adjusted()  // 2
     1962
     1963        #ans is now a linear approximation.
     1964
     1965        Emax, Emin = context.Emax, context.Emin
     1966        context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin
     1967
     1968        half = Decimal('0.5')
     1969
     1970        maxp = firstprec + 2
     1971        rounding = context._set_rounding(ROUND_HALF_EVEN)
     1972        while 1:
     1973            context.prec = min(2*context.prec - 2, maxp)
     1974            ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context),
     1975                                           context=context), context=context)
     1976            if context.prec == maxp:
     1977                break
     1978
     1979        #round to the answer's precision-- the only error can be 1 ulp.
     1980        context.prec = firstprec
     1981        prevexp = ans.adjusted()
     1982        ans = ans._round(context=context)
     1983
     1984        #Now, check if the other last digits are better.
     1985        context.prec = firstprec + 1
     1986        # In case we rounded up another digit and we should actually go lower.
     1987        if prevexp != ans.adjusted():
     1988            ans._int += (0,)
     1989            ans._exp -= 1
     1990
     1991
     1992        lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context)
     1993        context._set_rounding(ROUND_UP)
     1994        if lower.__mul__(lower, context=context) > (tmp):
     1995            ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context)
     1996
     1997        else:
     1998            upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context)
     1999            context._set_rounding(ROUND_DOWN)
     2000            if upper.__mul__(upper, context=context) < tmp:
     2001                ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context)
     2002
     2003        ans._exp += expadd
     2004
     2005        context.prec = firstprec
     2006        context.rounding = rounding
     2007        ans = ans._fix(context)
     2008
     2009        rounding = context._set_rounding_decision(NEVER_ROUND)
     2010        if not ans.__mul__(ans, context=context) == self:
     2011            # Only rounded/inexact if here.
     2012            context._regard_flags(flags)
     2013            context._raise_error(Rounded)
     2014            context._raise_error(Inexact)
     2015        else:
     2016            #Exact answer, so let's set the exponent right.
     2017            #if self._exp < 0:
     2018            #    exp = (self._exp +1)// 2
     2019            #else:
     2020            exp = self._exp // 2
     2021            context.prec += ans._exp - exp
     2022            ans = ans._rescale(exp, context=context)
     2023            context.prec = firstprec
     2024            context._regard_flags(flags)
     2025        context.Emax, context.Emin = Emax, Emin
     2026
     2027        return ans._fix(context)
     2028
     2029    def max(self, other, context=None):
     2030        """Returns the larger value.
     2031
     2032        like max(self, other) except if one is not a number, returns
     2033        NaN (and signals if one is sNaN).  Also rounds.
     2034        """
     2035        other = _convert_other(other)
     2036        if other is NotImplemented:
     2037            return other
     2038
     2039        if self._is_special or other._is_special:
     2040            # if one operand is a quiet NaN and the other is number, then the
     2041            # number is always returned
     2042            sn = self._isnan()
     2043            on = other._isnan()
     2044            if sn or on:
     2045                if on == 1 and sn != 2:
     2046                    return self
     2047                if sn == 1 and on != 2:
     2048                    return other
     2049                return self._check_nans(other, context)
     2050
     2051        ans = self
     2052        c = self.__cmp__(other)
     2053        if c == 0:
     2054            # if both operands are finite and equal in numerical value
     2055            # then an ordering is applied:
     2056            #
     2057            # if the signs differ then max returns the operand with the
     2058            # positive sign and min returns the operand with the negative sign
     2059            #
     2060            # if the signs are the same then the exponent is used to select
     2061            # the result.
     2062            if self._sign != other._sign:
     2063                if self._sign:
     2064                    ans = other
     2065            elif self._exp < other._exp and not self._sign:
     2066                ans = other
     2067            elif self._exp > other._exp and self._sign:
     2068                ans = other
     2069        elif c == -1:
     2070            ans = other
     2071
     2072        if context is None:
     2073            context = getcontext()
     2074        if context._rounding_decision == ALWAYS_ROUND:
     2075            return ans._fix(context)
     2076        return ans
     2077
     2078    def min(self, other, context=None):
     2079        """Returns the smaller value.
     2080
     2081        like min(self, other) except if one is not a number, returns
     2082        NaN (and signals if one is sNaN).  Also rounds.
     2083        """
     2084        other = _convert_other(other)
     2085        if other is NotImplemented:
     2086            return other
     2087
     2088        if self._is_special or other._is_special:
     2089            # if one operand is a quiet NaN and the other is number, then the
     2090            # number is always returned
     2091            sn = self._isnan()
     2092            on = other._isnan()
     2093            if sn or on:
     2094                if on == 1 and sn != 2:
     2095                    return self
     2096                if sn == 1 and on != 2:
     2097                    return other
     2098                return self._check_nans(other, context)
     2099
     2100        ans = self
     2101        c = self.__cmp__(other)
     2102        if c == 0:
     2103            # if both operands are finite and equal in numerical value
     2104            # then an ordering is applied:
     2105            #
     2106            # if the signs differ then max returns the operand with the
     2107            # positive sign and min returns the operand with the negative sign
     2108            #
     2109            # if the signs are the same then the exponent is used to select
     2110            # the result.
     2111            if self._sign != other._sign:
     2112                if other._sign:
     2113                    ans = other
     2114            elif self._exp > other._exp and not self._sign:
     2115                ans = other
     2116            elif self._exp < other._exp and self._sign:
     2117                ans = other
     2118        elif c == 1:
     2119            ans = other
     2120
     2121        if context is None:
     2122            context = getcontext()
     2123        if context._rounding_decision == ALWAYS_ROUND:
     2124            return ans._fix(context)
     2125        return ans
     2126
     2127    def _isinteger(self):
     2128        """Returns whether self is an integer"""
     2129        if self._exp >= 0:
     2130            return True
     2131        rest = self._int[self._exp:]
     2132        return rest == (0,)*len(rest)
     2133
     2134    def _iseven(self):
     2135        """Returns 1 if self is even.  Assumes self is an integer."""
     2136        if self._exp > 0:
     2137            return 1
     2138        return self._int[-1+self._exp] & 1 == 0
     2139
     2140    def adjusted(self):
     2141        """Return the adjusted exponent of self"""
     2142        try:
     2143            return self._exp + len(self._int) - 1
     2144        #If NaN or Infinity, self._exp is string
     2145        except TypeError:
     2146            return 0
     2147
     2148    # support for pickling, copy, and deepcopy
     2149    def __reduce__(self):
     2150        return (self.__class__, (str(self),))
     2151
     2152    def __copy__(self):
     2153        if type(self) == Decimal:
     2154            return self     # I'm immutable; therefore I am my own clone
     2155        return self.__class__(str(self))
     2156
     2157    def __deepcopy__(self, memo):
     2158        if type(self) == Decimal:
     2159            return self     # My components are also immutable
     2160        return self.__class__(str(self))
     2161
     2162##### Context class ###########################################
     2163
     2164
     2165# get rounding method function:
     2166rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')]
     2167for name in rounding_functions:
     2168    #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value.
     2169    globalname = name[1:].upper()
     2170    val = globals()[globalname]
     2171    Decimal._pick_rounding_function[val] = name
     2172
     2173del name, val, globalname, rounding_functions
     2174
     2175class Context(object):
     2176    """Contains the context for a Decimal instance.
     2177
     2178    Contains:
     2179    prec - precision (for use in rounding, division, square roots..)
     2180    rounding - rounding type. (how you round)
     2181    _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round?
     2182    traps - If traps[exception] = 1, then the exception is
     2183                    raised when it is caused.  Otherwise, a value is
     2184                    substituted in.
     2185    flags  - When an exception is caused, flags[exception] is incremented.
     2186             (Whether or not the trap_enabler is set)
     2187             Should be reset by user of Decimal instance.
     2188    Emin -   Minimum exponent
     2189    Emax -   Maximum exponent
     2190    capitals -      If 1, 1*10^1 is printed as 1E+1.
     2191                    If 0, printed as 1e1
     2192    _clamp - If 1, change exponents if too high (Default 0)
     2193    """
     2194
     2195    def __init__(self, prec=None, rounding=None,
     2196                 traps=None, flags=None,
     2197                 _rounding_decision=None,
     2198                 Emin=None, Emax=None,
     2199                 capitals=None, _clamp=0,
     2200                 _ignored_flags=None):
     2201        if flags is None:
     2202            flags = []
     2203        if _ignored_flags is None:
     2204            _ignored_flags = []
     2205        if not isinstance(flags, dict):
     2206            flags = dict([(s,s in flags) for s in _signals])
     2207            del s
     2208        if traps is not None and not isinstance(traps, dict):
     2209            traps = dict([(s,s in traps) for s in _signals])
     2210            del s
     2211        for name, val in locals().items():
     2212            if val is None:
     2213                setattr(self, name, copy.copy(getattr(DefaultContext, name)))
     2214            else:
     2215                setattr(self, name, val)
     2216        del self.self
     2217
     2218    def __repr__(self):
     2219        """Show the current context."""
     2220        s = []
     2221        s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self))
     2222        s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']')
     2223        s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']')
     2224        return ', '.join(s) + ')'
     2225
     2226    def clear_flags(self):
     2227        """Reset all flags to zero"""
     2228        for flag in self.flags:
     2229            self.flags[flag] = 0
     2230
     2231    def _shallow_copy(self):
     2232        """Returns a shallow copy from self."""
     2233        nc = Context(self.prec, self.rounding, self.traps, self.flags,
     2234                         self._rounding_decision, self.Emin, self.Emax,
     2235                         self.capitals, self._clamp, self._ignored_flags)
     2236        return nc
     2237
     2238    def copy(self):
     2239        """Returns a deep copy from self."""
     2240        nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(),
     2241                         self._rounding_decision, self.Emin, self.Emax,
     2242                         self.capitals, self._clamp, self._ignored_flags)
     2243        return nc
     2244    __copy__ = copy
     2245
     2246    def _raise_error(self, condition, explanation = None, *args):
     2247        """Handles an error
     2248
     2249        If the flag is in _ignored_flags, returns the default response.
     2250        Otherwise, it increments the flag, then, if the corresponding
     2251        trap_enabler is set, it reaises the exception.  Otherwise, it returns
     2252        the default value after incrementing the flag.
     2253        """
     2254        error = _condition_map.get(condition, condition)
     2255        if error in self._ignored_flags:
     2256            #Don't touch the flag
     2257            return error().handle(self, *args)
     2258
     2259        self.flags[error] += 1
     2260        if not self.traps[error]:
     2261            #The errors define how to handle themselves.
     2262            return condition().handle(self, *args)
     2263
     2264        # Errors should only be risked on copies of the context
     2265        #self._ignored_flags = []
     2266        raise error, explanation
     2267
     2268    def _ignore_all_flags(self):
     2269        """Ignore all flags, if they are raised"""
     2270        return self._ignore_flags(*_signals)
     2271
     2272    def _ignore_flags(self, *flags):
     2273        """Ignore the flags, if they are raised"""
     2274        # Do not mutate-- This way, copies of a context leave the original
     2275        # alone.
     2276        self._ignored_flags = (self._ignored_flags + list(flags))
     2277        return list(flags)
     2278
     2279    def _regard_flags(self, *flags):
     2280        """Stop ignoring the flags, if they are raised"""
     2281        if flags and isinstance(flags[0], (tuple,list)):
     2282            flags = flags[0]
     2283        for flag in flags:
     2284            self._ignored_flags.remove(flag)
     2285
     2286    def __hash__(self):
     2287        """A Context cannot be hashed."""
     2288        # We inherit object.__hash__, so we must deny this explicitly
     2289        raise TypeError, "Cannot hash a Context."
     2290
     2291    def Etiny(self):
     2292        """Returns Etiny (= Emin - prec + 1)"""
     2293        return int(self.Emin - self.prec + 1)
     2294
     2295    def Etop(self):
     2296        """Returns maximum exponent (= Emax - prec + 1)"""
     2297        return int(self.Emax - self.prec + 1)
     2298
     2299    def _set_rounding_decision(self, type):
     2300        """Sets the rounding decision.
     2301
     2302        Sets the rounding decision, and returns the current (previous)
     2303        rounding decision.  Often used like:
     2304
     2305        context = context._shallow_copy()
     2306        # That so you don't change the calling context
     2307        # if an error occurs in the middle (say DivisionImpossible is raised).
     2308
     2309        rounding = context._set_rounding_decision(NEVER_ROUND)
     2310        instance = instance / Decimal(2)
     2311        context._set_rounding_decision(rounding)
     2312
     2313        This will make it not round for that operation.
     2314        """
     2315
     2316        rounding = self._rounding_decision
     2317        self._rounding_decision = type
     2318        return rounding
     2319
     2320    def _set_rounding(self, type):
     2321        """Sets the rounding type.
     2322
     2323        Sets the rounding type, and returns the current (previous)
     2324        rounding type.  Often used like:
     2325
     2326        context = context.copy()
     2327        # so you don't change the calling context
     2328        # if an error occurs in the middle.
     2329        rounding = context._set_rounding(ROUND_UP)
     2330        val = self.__sub__(other, context=context)
     2331        context._set_rounding(rounding)
     2332
     2333        This will make it round up for that operation.
     2334        """
     2335        rounding = self.rounding
     2336        self.rounding= type
     2337        return rounding
     2338
     2339    def create_decimal(self, num='0'):
     2340        """Creates a new Decimal instance but using self as context."""
     2341        d = Decimal(num, context=self)
     2342        return d._fix(self)
     2343
     2344    #Methods
     2345    def abs(self, a):
     2346        """Returns the absolute value of the operand.
     2347
     2348        If the operand is negative, the result is the same as using the minus
     2349        operation on the operand. Otherwise, the result is the same as using
     2350        the plus operation on the operand.
     2351
     2352        >>> ExtendedContext.abs(Decimal('2.1'))
     2353        Decimal("2.1")
     2354        >>> ExtendedContext.abs(Decimal('-100'))
     2355        Decimal("100")
     2356        >>> ExtendedContext.abs(Decimal('101.5'))
     2357        Decimal("101.5")
     2358        >>> ExtendedContext.abs(Decimal('-101.5'))
     2359        Decimal("101.5")
     2360        """
     2361        return a.__abs__(context=self)
     2362
     2363    def add(self, a, b):
     2364        """Return the sum of the two operands.
     2365
     2366        >>> ExtendedContext.add(Decimal('12'), Decimal('7.00'))
     2367        Decimal("19.00")
     2368        >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4'))
     2369        Decimal("1.02E+4")
     2370        """
     2371        return a.__add__(b, context=self)
     2372
     2373    def _apply(self, a):
     2374        return str(a._fix(self))
     2375
     2376    def compare(self, a, b):
     2377        """Compares values numerically.
     2378
     2379        If the signs of the operands differ, a value representing each operand
     2380        ('-1' if the operand is less than zero, '0' if the operand is zero or
     2381        negative zero, or '1' if the operand is greater than zero) is used in
     2382        place of that operand for the comparison instead of the actual
     2383        operand.
     2384
     2385        The comparison is then effected by subtracting the second operand from
     2386        the first and then returning a value according to the result of the
     2387        subtraction: '-1' if the result is less than zero, '0' if the result is
     2388        zero or negative zero, or '1' if the result is greater than zero.
     2389
     2390        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3'))
     2391        Decimal("-1")
     2392        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1'))
     2393        Decimal("0")
     2394        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10'))
     2395        Decimal("0")
     2396        >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1'))
     2397        Decimal("1")
     2398        >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3'))
     2399        Decimal("1")
     2400        >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1'))
     2401        Decimal("-1")
     2402        """
     2403        return a.compare(b, context=self)
     2404
     2405    def divide(self, a, b):
     2406        """Decimal division in a specified context.
     2407
     2408        >>> ExtendedContext.divide(Decimal('1'), Decimal('3'))
     2409        Decimal("0.333333333")
     2410        >>> ExtendedContext.divide(Decimal('2'), Decimal('3'))
     2411        Decimal("0.666666667")
     2412        >>> ExtendedContext.divide(Decimal('5'), Decimal('2'))
     2413        Decimal("2.5")
     2414        >>> ExtendedContext.divide(Decimal('1'), Decimal('10'))
     2415        Decimal("0.1")
     2416        >>> ExtendedContext.divide(Decimal('12'), Decimal('12'))
     2417        Decimal("1")
     2418        >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2'))
     2419        Decimal("4.00")
     2420        >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0'))
     2421        Decimal("1.20")
     2422        >>> ExtendedContext.divide(Decimal('1000'), Decimal('100'))
     2423        Decimal("10")
     2424        >>> ExtendedContext.divide(Decimal('1000'), Decimal('1'))
     2425        Decimal("1000")
     2426        >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2'))
     2427        Decimal("1.20E+6")
     2428        """
     2429        return a.__div__(b, context=self)
     2430
     2431    def divide_int(self, a, b):
     2432        """Divides two numbers and returns the integer part of the result.
     2433
     2434        >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3'))
     2435        Decimal("0")
     2436        >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3'))
     2437        Decimal("3")
     2438        >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3'))
     2439        Decimal("3")
     2440        """
     2441        return a.__floordiv__(b, context=self)
     2442
     2443    def divmod(self, a, b):
     2444        return a.__divmod__(b, context=self)
     2445
     2446    def max(self, a,b):
     2447        """max compares two values numerically and returns the maximum.
     2448
     2449        If either operand is a NaN then the general rules apply.
     2450        Otherwise, the operands are compared as as though by the compare
     2451        operation. If they are numerically equal then the left-hand operand
     2452        is chosen as the result. Otherwise the maximum (closer to positive
     2453        infinity) of the two operands is chosen as the result.
     2454
     2455        >>> ExtendedContext.max(Decimal('3'), Decimal('2'))
     2456        Decimal("3")
     2457        >>> ExtendedContext.max(Decimal('-10'), Decimal('3'))
     2458        Decimal("3")
     2459        >>> ExtendedContext.max(Decimal('1.0'), Decimal('1'))
     2460        Decimal("1")
     2461        >>> ExtendedContext.max(Decimal('7'), Decimal('NaN'))
     2462        Decimal("7")
     2463        """
     2464        return a.max(b, context=self)
     2465
     2466    def min(self, a,b):
     2467        """min compares two values numerically and returns the minimum.
     2468
     2469        If either operand is a NaN then the general rules apply.
     2470        Otherwise, the operands are compared as as though by the compare
     2471        operation. If they are numerically equal then the left-hand operand
     2472        is chosen as the result. Otherwise the minimum (closer to negative
     2473        infinity) of the two operands is chosen as the result.
     2474
     2475        >>> ExtendedContext.min(Decimal('3'), Decimal('2'))
     2476        Decimal("2")
     2477        >>> ExtendedContext.min(Decimal('-10'), Decimal('3'))
     2478        Decimal("-10")
     2479        >>> ExtendedContext.min(Decimal('1.0'), Decimal('1'))
     2480        Decimal("1.0")
     2481        >>> ExtendedContext.min(Decimal('7'), Decimal('NaN'))
     2482        Decimal("7")
     2483        """
     2484        return a.min(b, context=self)
     2485
     2486    def minus(self, a):
     2487        """Minus corresponds to unary prefix minus in Python.
     2488
     2489        The operation is evaluated using the same rules as subtract; the
     2490        operation minus(a) is calculated as subtract('0', a) where the '0'
     2491        has the same exponent as the operand.
     2492
     2493        >>> ExtendedContext.minus(Decimal('1.3'))
     2494        Decimal("-1.3")
     2495        >>> ExtendedContext.minus(Decimal('-1.3'))
     2496        Decimal("1.3")
     2497        """
     2498        return a.__neg__(context=self)
     2499
     2500    def multiply(self, a, b):
     2501        """multiply multiplies two operands.
     2502
     2503        If either operand is a special value then the general rules apply.
     2504        Otherwise, the operands are multiplied together ('long multiplication'),
     2505        resulting in a number which may be as long as the sum of the lengths
     2506        of the two operands.
     2507
     2508        >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3'))
     2509        Decimal("3.60")
     2510        >>> ExtendedContext.multiply(Decimal('7'), Decimal('3'))
     2511        Decimal("21")
     2512        >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8'))
     2513        Decimal("0.72")
     2514        >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0'))
     2515        Decimal("-0.0")
     2516        >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321'))
     2517        Decimal("4.28135971E+11")
     2518        """
     2519        return a.__mul__(b, context=self)
     2520
     2521    def normalize(self, a):
     2522        """normalize reduces an operand to its simplest form.
     2523
     2524        Essentially a plus operation with all trailing zeros removed from the
     2525        result.
     2526
     2527        >>> ExtendedContext.normalize(Decimal('2.1'))
     2528        Decimal("2.1")
     2529        >>> ExtendedContext.normalize(Decimal('-2.0'))
     2530        Decimal("-2")
     2531        >>> ExtendedContext.normalize(Decimal('1.200'))
     2532        Decimal("1.2")
     2533        >>> ExtendedContext.normalize(Decimal('-120'))
     2534        Decimal("-1.2E+2")
     2535        >>> ExtendedContext.normalize(Decimal('120.00'))
     2536        Decimal("1.2E+2")
     2537        >>> ExtendedContext.normalize(Decimal('0.00'))
     2538        Decimal("0")
     2539        """
     2540        return a.normalize(context=self)
     2541
     2542    def plus(self, a):
     2543        """Plus corresponds to unary prefix plus in Python.
     2544
     2545        The operation is evaluated using the same rules as add; the
     2546        operation plus(a) is calculated as add('0', a) where the '0'
     2547        has the same exponent as the operand.
     2548
     2549        >>> ExtendedContext.plus(Decimal('1.3'))
     2550        Decimal("1.3")
     2551        >>> ExtendedContext.plus(Decimal('-1.3'))
     2552        Decimal("-1.3")
     2553        """
     2554        return a.__pos__(context=self)
     2555
     2556    def power(self, a, b, modulo=None):
     2557        """Raises a to the power of b, to modulo if given.
     2558
     2559        The right-hand operand must be a whole number whose integer part (after
     2560        any exponent has been applied) has no more than 9 digits and whose
     2561        fractional part (if any) is all zeros before any rounding. The operand
     2562        may be positive, negative, or zero; if negative, the absolute value of
     2563        the power is used, and the left-hand operand is inverted (divided into
     2564        1) before use.
     2565
     2566        If the increased precision needed for the intermediate calculations
     2567        exceeds the capabilities of the implementation then an Invalid operation
     2568        condition is raised.
     2569
     2570        If, when raising to a negative power, an underflow occurs during the
     2571        division into 1, the operation is not halted at that point but
     2572        continues.
     2573
     2574        >>> ExtendedContext.power(Decimal('2'), Decimal('3'))
     2575        Decimal("8")
     2576        >>> ExtendedContext.power(Decimal('2'), Decimal('-3'))
     2577        Decimal("0.125")
     2578        >>> ExtendedContext.power(Decimal('1.7'), Decimal('8'))
     2579        Decimal("69.7575744")
     2580        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2'))
     2581        Decimal("0")
     2582        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1'))
     2583        Decimal("0")
     2584        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0'))
     2585        Decimal("1")
     2586        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1'))
     2587        Decimal("Infinity")
     2588        >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2'))
     2589        Decimal("Infinity")
     2590        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2'))
     2591        Decimal("0")
     2592        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1'))
     2593        Decimal("-0")
     2594        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0'))
     2595        Decimal("1")
     2596        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1'))
     2597        Decimal("-Infinity")
     2598        >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2'))
     2599        Decimal("Infinity")
     2600        >>> ExtendedContext.power(Decimal('0'), Decimal('0'))
     2601        Decimal("NaN")
     2602        """
     2603        return a.__pow__(b, modulo, context=self)
     2604
     2605    def quantize(self, a, b):
     2606        """Returns a value equal to 'a' (rounded) and having the exponent of 'b'.
     2607
     2608        The coefficient of the result is derived from that of the left-hand
     2609        operand. It may be rounded using the current rounding setting (if the
     2610        exponent is being increased), multiplied by a positive power of ten (if
     2611        the exponent is being decreased), or is unchanged (if the exponent is
     2612        already equal to that of the right-hand operand).
     2613
     2614        Unlike other operations, if the length of the coefficient after the
     2615        quantize operation would be greater than precision then an Invalid
     2616        operation condition is raised. This guarantees that, unless there is an
     2617        error condition, the exponent of the result of a quantize is always
     2618        equal to that of the right-hand operand.
     2619
     2620        Also unlike other operations, quantize will never raise Underflow, even
     2621        if the result is subnormal and inexact.
     2622
     2623        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001'))
     2624        Decimal("2.170")
     2625        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01'))
     2626        Decimal("2.17")
     2627        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1'))
     2628        Decimal("2.2")
     2629        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0'))
     2630        Decimal("2")
     2631        >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1'))
     2632        Decimal("0E+1")
     2633        >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity'))
     2634        Decimal("-Infinity")
     2635        >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity'))
     2636        Decimal("NaN")
     2637        >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1'))
     2638        Decimal("-0")
     2639        >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5'))
     2640        Decimal("-0E+5")
     2641        >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2'))
     2642        Decimal("NaN")
     2643        >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2'))
     2644        Decimal("NaN")
     2645        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1'))
     2646        Decimal("217.0")
     2647        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0'))
     2648        Decimal("217")
     2649        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1'))
     2650        Decimal("2.2E+2")
     2651        >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2'))
     2652        Decimal("2E+2")
     2653        """
     2654        return a.quantize(b, context=self)
     2655
     2656    def remainder(self, a, b):
     2657        """Returns the remainder from integer division.
     2658
     2659        The result is the residue of the dividend after the operation of
     2660        calculating integer division as described for divide-integer, rounded to
     2661        precision digits if necessary. The sign of the result, if non-zero, is
     2662        the same as that of the original dividend.
     2663
     2664        This operation will fail under the same conditions as integer division
     2665        (that is, if integer division on the same two operands would fail, the
     2666        remainder cannot be calculated).
     2667
     2668        >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3'))
     2669        Decimal("2.1")
     2670        >>> ExtendedContext.remainder(Decimal('10'), Decimal('3'))
     2671        Decimal("1")
     2672        >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3'))
     2673        Decimal("-1")
     2674        >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1'))
     2675        Decimal("0.2")
     2676        >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3'))
     2677        Decimal("0.1")
     2678        >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3'))
     2679        Decimal("1.0")
     2680        """
     2681        return a.__mod__(b, context=self)
     2682
     2683    def remainder_near(self, a, b):
     2684        """Returns to be "a - b * n", where n is the integer nearest the exact
     2685        value of "x / b" (if two integers are equally near then the even one
     2686        is chosen). If the result is equal to 0 then its sign will be the
     2687        sign of a.
     2688
     2689        This operation will fail under the same conditions as integer division
     2690        (that is, if integer division on the same two operands would fail, the
     2691        remainder cannot be calculated).
     2692
     2693        >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3'))
     2694        Decimal("-0.9")
     2695        >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6'))
     2696        Decimal("-2")
     2697        >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3'))
     2698        Decimal("1")
     2699        >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3'))
     2700        Decimal("-1")
     2701        >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1'))
     2702        Decimal("0.2")
     2703        >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3'))
     2704        Decimal("0.1")
     2705        >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3'))
     2706        Decimal("-0.3")
     2707        """
     2708        return a.remainder_near(b, context=self)
     2709
     2710    def same_quantum(self, a, b):
     2711        """Returns True if the two operands have the same exponent.
     2712
     2713        The result is never affected by either the sign or the coefficient of
     2714        either operand.
     2715
     2716        >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001'))
     2717        False
     2718        >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01'))
     2719        True
     2720        >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1'))
     2721        False
     2722        >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf'))
     2723        True
     2724        """
     2725        return a.same_quantum(b)
     2726
     2727    def sqrt(self, a):
     2728        """Returns the square root of a non-negative number to context precision.
     2729
     2730        If the result must be inexact, it is rounded using the round-half-even
     2731        algorithm.
     2732
     2733        >>> ExtendedContext.sqrt(Decimal('0'))
     2734        Decimal("0")
     2735        >>> ExtendedContext.sqrt(Decimal('-0'))
     2736        Decimal("-0")
     2737        >>> ExtendedContext.sqrt(Decimal('0.39'))
     2738        Decimal("0.624499800")
     2739        >>> ExtendedContext.sqrt(Decimal('100'))
     2740        Decimal("10")
     2741        >>> ExtendedContext.sqrt(Decimal('1'))
     2742        Decimal("1")
     2743        >>> ExtendedContext.sqrt(Decimal('1.0'))
     2744        Decimal("1.0")
     2745        >>> ExtendedContext.sqrt(Decimal('1.00'))
     2746        Decimal("1.0")
     2747        >>> ExtendedContext.sqrt(Decimal('7'))
     2748        Decimal("2.64575131")
     2749        >>> ExtendedContext.sqrt(Decimal('10'))
     2750        Decimal("3.16227766")
     2751        >>> ExtendedContext.prec
     2752        9
     2753        """
     2754        return a.sqrt(context=self)
     2755
     2756    def subtract(self, a, b):
     2757        """Return the sum of the two operands.
     2758
     2759        >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07'))
     2760        Decimal("0.23")
     2761        >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30'))
     2762        Decimal("0.00")
     2763        >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07'))
     2764        Decimal("-0.77")
     2765        """
     2766        return a.__sub__(b, context=self)
     2767
     2768    def to_eng_string(self, a):
     2769        """Converts a number to a string, using scientific notation.
     2770
     2771        The operation is not affected by the context.
     2772        """
     2773        return a.to_eng_string(context=self)
     2774
     2775    def to_sci_string(self, a):
     2776        """Converts a number to a string, using scientific notation.
     2777
     2778        The operation is not affected by the context.
     2779        """
     2780        return a.__str__(context=self)
     2781
     2782    def to_integral(self, a):
     2783        """Rounds to an integer.
     2784
     2785        When the operand has a negative exponent, the result is the same
     2786        as using the quantize() operation using the given operand as the
     2787        left-hand-operand, 1E+0 as the right-hand-operand, and the precision
     2788        of the operand as the precision setting, except that no flags will
     2789        be set. The rounding mode is taken from the context.
     2790
     2791        >>> ExtendedContext.to_integral(Decimal('2.1'))
     2792        Decimal("2")
     2793        >>> ExtendedContext.to_integral(Decimal('100'))
     2794        Decimal("100")
     2795        >>> ExtendedContext.to_integral(Decimal('100.0'))
     2796        Decimal("100")
     2797        >>> ExtendedContext.to_integral(Decimal('101.5'))
     2798        Decimal("102")
     2799        >>> ExtendedContext.to_integral(Decimal('-101.5'))
     2800        Decimal("-102")
     2801        >>> ExtendedContext.to_integral(Decimal('10E+5'))
     2802        Decimal("1.0E+6")
     2803        >>> ExtendedContext.to_integral(Decimal('7.89E+77'))
     2804        Decimal("7.89E+77")
     2805        >>> ExtendedContext.to_integral(Decimal('-Inf'))
     2806        Decimal("-Infinity")
     2807        """
     2808        return a.to_integral(context=self)
     2809
     2810class _WorkRep(object):
     2811    __slots__ = ('sign','int','exp')
     2812    # sign: 0 or 1
     2813    # int:  int or long
     2814    # exp:  None, int, or string
     2815
     2816    def __init__(self, value=None):
     2817        if value is None:
     2818            self.sign = None
     2819            self.int = 0
     2820            self.exp = None
     2821        elif isinstance(value, Decimal):
     2822            self.sign = value._sign
     2823            cum = 0
     2824            for digit  in value._int:
     2825                cum = cum * 10 + digit
     2826            self.int = cum
     2827            self.exp = value._exp
     2828        else:
     2829            # assert isinstance(value, tuple)
     2830            self.sign = value[0]
     2831            self.int = value[1]
     2832            self.exp = value[2]
     2833
     2834    def __repr__(self):
     2835        return "(%r, %r, %r)" % (self.sign, self.int, self.exp)
     2836
     2837    __str__ = __repr__
     2838
     2839
     2840
     2841def _normalize(op1, op2, shouldround = 0, prec = 0):
     2842    """Normalizes op1, op2 to have the same exp and length of coefficient.
     2843
     2844    Done during addition.
     2845    """
     2846    # Yes, the exponent is a long, but the difference between exponents
     2847    # must be an int-- otherwise you'd get a big memory problem.
     2848    numdigits = int(op1.exp - op2.exp)
     2849    if numdigits < 0:
     2850        numdigits = -numdigits
     2851        tmp = op2
     2852        other = op1
     2853    else:
     2854        tmp = op1
     2855        other = op2
     2856
     2857
     2858    if shouldround and numdigits > prec + 1:
     2859        # Big difference in exponents - check the adjusted exponents
     2860        tmp_len = len(str(tmp.int))
     2861        other_len = len(str(other.int))
     2862        if numdigits > (other_len + prec + 1 - tmp_len):
     2863            # If the difference in adjusted exps is > prec+1, we know
     2864            # other is insignificant, so might as well put a 1 after the precision.
     2865            # (since this is only for addition.)  Also stops use of massive longs.
     2866
     2867            extend = prec + 2 - tmp_len
     2868            if extend <= 0:
     2869                extend = 1
     2870            tmp.int *= 10 ** extend
     2871            tmp.exp -= extend
     2872            other.int = 1
     2873            other.exp = tmp.exp
     2874            return op1, op2
     2875
     2876    tmp.int *= 10 ** numdigits
     2877    tmp.exp -= numdigits
     2878    return op1, op2
     2879
     2880def _adjust_coefficients(op1, op2):
     2881    """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int.
     2882
     2883    Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp.
     2884
     2885    Used on _WorkRep instances during division.
     2886    """
     2887    adjust = 0
     2888    #If op1 is smaller, make it larger
     2889    while op2.int > op1.int:
     2890        op1.int *= 10
     2891        op1.exp -= 1
     2892        adjust += 1
     2893
     2894    #If op2 is too small, make it larger
     2895    while op1.int >= (10 * op2.int):
     2896        op2.int *= 10
     2897        op2.exp -= 1
     2898        adjust -= 1
     2899
     2900    return op1, op2, adjust
     2901
     2902##### Helper Functions ########################################
     2903
     2904def _convert_other(other):
     2905    """Convert other to Decimal.
     2906
     2907    Verifies that it's ok to use in an implicit construction.
     2908    """
     2909    if isinstance(other, Decimal):
     2910        return other
     2911    if isinstance(other, (int, long)):
     2912        return Decimal(other)
     2913    return NotImplemented
     2914
     2915_infinity_map = {
     2916    'inf' : 1,
     2917    'infinity' : 1,
     2918    '+inf' : 1,
     2919    '+infinity' : 1,
     2920    '-inf' : -1,
     2921    '-infinity' : -1
     2922}
     2923
     2924def _isinfinity(num):
     2925    """Determines whether a string or float is infinity.
     2926
     2927    +1 for negative infinity; 0 for finite ; +1 for positive infinity
     2928    """
     2929    num = str(num).lower()
     2930    return _infinity_map.get(num, 0)
     2931
     2932def _isnan(num):
     2933    """Determines whether a string or float is NaN
     2934
     2935    (1, sign, diagnostic info as string) => NaN
     2936    (2, sign, diagnostic info as string) => sNaN
     2937    0 => not a NaN
     2938    """
     2939    num = str(num).lower()
     2940    if not num:
     2941        return 0
     2942
     2943    #get the sign, get rid of trailing [+-]
     2944    sign = 0
     2945    if num[0] == '+':
     2946        num = num[1:]
     2947    elif num[0] == '-':  #elif avoids '+-nan'
     2948        num = num[1:]
     2949        sign = 1
     2950
     2951    if num.startswith('nan'):
     2952        if len(num) > 3 and not num[3:].isdigit(): #diagnostic info
     2953            return 0
     2954        return (1, sign, num[3:].lstrip('0'))
     2955    if num.startswith('snan'):
     2956        if len(num) > 4 and not num[4:].isdigit():
     2957            return 0
     2958        return (2, sign, num[4:].lstrip('0'))
     2959    return 0
     2960
     2961
     2962##### Setup Specific Contexts ################################
     2963
     2964# The default context prototype used by Context()
     2965# Is mutable, so that new contexts can have different default values
     2966
     2967DefaultContext = Context(
     2968        prec=28, rounding=ROUND_HALF_EVEN,
     2969        traps=[DivisionByZero, Overflow, InvalidOperation],
     2970        flags=[],
     2971        _rounding_decision=ALWAYS_ROUND,
     2972        Emax=999999999,
     2973        Emin=-999999999,
     2974        capitals=1
     2975)
     2976
     2977# Pre-made alternate contexts offered by the specification
     2978# Don't change these; the user should be able to select these
     2979# contexts and be able to reproduce results from other implementations
     2980# of the spec.
     2981
     2982BasicContext = Context(
     2983        prec=9, rounding=ROUND_HALF_UP,
     2984        traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow],
     2985        flags=[],
     2986)
     2987
     2988ExtendedContext = Context(
     2989        prec=9, rounding=ROUND_HALF_EVEN,
     2990        traps=[],
     2991        flags=[],
     2992)
     2993
     2994
     2995##### Useful Constants (internal use only) ####################
     2996
     2997#Reusable defaults
     2998Inf = Decimal('Inf')
     2999negInf = Decimal('-Inf')
     3000
     3001#Infsign[sign] is infinity w/ that sign
     3002Infsign = (Inf, negInf)
     3003
     3004NaN = Decimal('NaN')
     3005
     3006
     3007##### crud for parsing strings #################################
     3008import re
     3009
     3010# There's an optional sign at the start, and an optional exponent
     3011# at the end.  The exponent has an optional sign and at least one
     3012# digit.  In between, must have either at least one digit followed
     3013# by an optional fraction, or a decimal point followed by at least
     3014# one digit.  Yuck.
     3015
     3016_parser = re.compile(r"""
     3017#    \s*
     3018    (?P<sign>[-+])?
     3019    (
     3020        (?P<int>\d+) (\. (?P<frac>\d*))?
     3021    |
     3022        \. (?P<onlyfrac>\d+)
     3023    )
     3024    ([eE](?P<exp>[-+]? \d+))?
     3025#    \s*
     3026    $
     3027""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces.
     3028
     3029del re
     3030
     3031# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly
     3032
     3033def _string2exact(s):
     3034    m = _parser(s)
     3035    if m is None:
     3036        raise ValueError("invalid literal for Decimal: %r" % s)
     3037
     3038    if m.group('sign') == "-":
     3039        sign = 1
     3040    else:
     3041        sign = 0
     3042
     3043    exp = m.group('exp')
     3044    if exp is None:
     3045        exp = 0
     3046    else:
     3047        exp = int(exp)
     3048
     3049    intpart = m.group('int')
     3050    if intpart is None:
     3051        intpart = ""
     3052        fracpart = m.group('onlyfrac')
     3053    else:
     3054        fracpart = m.group('frac')
     3055        if fracpart is None:
     3056            fracpart = ""
     3057
     3058    exp -= len(fracpart)
     3059
     3060    mantissa = intpart + fracpart
     3061    tmp = map(int, mantissa)
     3062    backup = tmp
     3063    while tmp and tmp[0] == 0:
     3064        del tmp[0]
     3065
     3066    # It's a zero
     3067    if not tmp:
     3068        if backup:
     3069            return (sign, tuple(backup), exp)
     3070        return (sign, (0,), exp)
     3071    mantissa = tuple(tmp)
     3072
     3073    return (sign, mantissa, exp)
     3074
     3075
     3076if __name__ == '__main__':
     3077    import doctest, sys
     3078    doctest.testmod(sys.modules[__name__])
  • tests/modeltests/invalid_models/models.py

     
    88
    99class FieldErrors(models.Model):
    1010    charfield = models.CharField()
    11     floatfield = models.FloatField()
     11    decimalfield = models.DecimalField()
    1212    filefield = models.FileField()
    1313    prepopulate = models.CharField(maxlength=10, prepopulate_from='bad')
    1414    choices = models.CharField(maxlength=10, choices='bad')
     
    9898    m2m_4 = models.ManyToManyField('self', symmetrical=False)
    9999
    100100model_errors = """invalid_models.fielderrors: "charfield": CharFields require a "maxlength" attribute.
    101 invalid_models.fielderrors: "floatfield": FloatFields require a "decimal_places" attribute.
    102 invalid_models.fielderrors: "floatfield": FloatFields require a "max_digits" attribute.
     101invalid_models.fielderrors: "decimalfield": DecimalFields require a "decimal_places" attribute.
     102invalid_models.fielderrors: "decimalfield": DecimalFields require a "max_digits" attribute.
    103103invalid_models.fielderrors: "filefield": FileFields require an "upload_to" attribute.
    104104invalid_models.fielderrors: "prepopulate": prepopulate_from should be a list or tuple.
    105105invalid_models.fielderrors: "choices": "choices" should be iterable (e.g., a tuple or list).
  • tests/regressiontests/forms/tests.py

     
    33>>> from django.newforms import *
    44>>> import datetime
    55>>> import re
     6>>> try:
     7...     from decimal import Decimal
     8... except ImportError:
     9...     from django.utils.decimal import Decimal
    610
    711###########
    812# Widgets #
     
    988992...
    989993ValidationError: [u'Ensure this value is less than or equal to 20.']
    990994
     995# FloatField ##################################################################
     996
     997>>> f = FloatField()
     998>>> f.clean('')
     999Traceback (most recent call last):
     1000...
     1001ValidationError: [u'This field is required.']
     1002>>> f.clean(None)
     1003Traceback (most recent call last):
     1004...
     1005ValidationError: [u'This field is required.']
     1006>>> f.clean('1')
     10071.0
     1008>>> isinstance(f.clean('1'), float)
     1009True
     1010>>> f.clean('23')
     101123.0
     1012>>> f.clean('3.14')
     10133.1400000000000001
     1014>>> f.clean('a')
     1015Traceback (most recent call last):
     1016...
     1017ValidationError: [u'Enter a number.']
     1018>>> f.clean('1.0 ')
     10191.0
     1020>>> f.clean(' 1.0')
     10211.0
     1022>>> f.clean(' 1.0 ')
     10231.0
     1024>>> f.clean('1.0a')
     1025Traceback (most recent call last):
     1026...
     1027ValidationError: [u'Enter a number.']
     1028
     1029>>> f = FloatField(required=False)
     1030>>> f.clean('')
     1031
     1032>>> f.clean(None)
     1033
     1034>>> f.clean('1')
     10351.0
     1036
     1037FloatField accepts min_value and max_value just like IntegerField:
     1038>>> f = FloatField(max_value=1.5, min_value=0.5)
     1039
     1040>>> f.clean('1.6')
     1041Traceback (most recent call last):
     1042...
     1043ValidationError: [u'Ensure this value is less than or equal to 1.5.']
     1044>>> f.clean('0.4')
     1045Traceback (most recent call last):
     1046...
     1047ValidationError: [u'Ensure this value is greater than or equal to 0.5.']
     1048>>> f.clean('1.5')
     10491.5
     1050>>> f.clean('0.5')
     10510.5
     1052
     1053# DecimalField ################################################################
     1054
     1055>>> f = DecimalField(max_digits=4, decimal_places=2)
     1056>>> f.clean('')
     1057Traceback (most recent call last):
     1058...
     1059ValidationError: [u'This field is required.']
     1060>>> f.clean(None)
     1061Traceback (most recent call last):
     1062...
     1063ValidationError: [u'This field is required.']
     1064>>> f.clean('1')
     1065Decimal("1")
     1066>>> isinstance(f.clean('1'), Decimal)
     1067True
     1068>>> f.clean('23')
     1069Decimal("23")
     1070>>> f.clean('3.14')
     1071Decimal("3.14")
     1072>>> f.clean('a')
     1073Traceback (most recent call last):
     1074...
     1075ValidationError: [u'Enter a number.']
     1076>>> f.clean('1.0 ')
     1077Decimal("1.0")
     1078>>> f.clean(' 1.0')
     1079Decimal("1.0")
     1080>>> f.clean(' 1.0 ')
     1081Decimal("1.0")
     1082>>> f.clean('1.0a')
     1083Traceback (most recent call last):
     1084...
     1085ValidationError: [u'Enter a number.']
     1086>>> f.clean('123.45')
     1087Traceback (most recent call last):
     1088...
     1089ValidationError: [u'Ensure that there are no more than 4 digits in total.']
     1090>>> f.clean('1.234')
     1091Traceback (most recent call last):
     1092...
     1093ValidationError: [u'Ensure that there are no more than 2 decimal places.']
     1094>>> f.clean('123.4')
     1095Traceback (most recent call last):
     1096...
     1097ValidationError: [u'Ensure that there are no more than 2 digits before the decimal point.']
     1098>>> f = DecimalField(max_digits=4, decimal_places=2, required=False)
     1099>>> f.clean('')
     1100
     1101>>> f.clean(None)
     1102
     1103>>> f.clean('1')
     1104Decimal("1")
     1105
     1106DecimalField accepts min_value and max_value just like IntegerField:
     1107>>> f = DecimalField(max_digits=4, decimal_places=2, max_value=Decimal('1.5'), min_value=Decimal('0.5'))
     1108
     1109>>> f.clean('1.6')
     1110Traceback (most recent call last):
     1111...
     1112ValidationError: [u'Ensure this value is less than or equal to 1.5.']
     1113>>> f.clean('0.4')
     1114Traceback (most recent call last):
     1115...
     1116ValidationError: [u'Ensure this value is greater than or equal to 0.5.']
     1117>>> f.clean('1.5')
     1118Decimal("1.5")
     1119>>> f.clean('0.5')
     1120Decimal("0.5")
     1121
    9911122# DateField ###################################################################
    9921123
    9931124>>> import datetime
  • tests/regressiontests/decimal_vs_float/tests.py

     
     1r"""
     2Create a manipulator that has a DecimalField and a FloatField
     3
     4>>> from django import oldforms
     5>>> class TestManipulator(oldforms.Manipulator):
     6...     def __init__(self):
     7...         self.fields = (
     8...             oldforms.DecimalField(field_name="decimal", max_digits=4, decimal_places=2),
     9...             oldforms.FloatField(field_name="float"),
     10...         )
     11...
     12
     13Test that the field validation works, and that the appropriate types are returned from the fields.
     14
     15>>> from django.utils.datastructures import MultiValueDict
     16>>> manipulator = TestManipulator()
     17>>> data = MultiValueDict({'decimal': ["abc"], 'float': ["abc"]})
     18>>> manipulator.get_validation_errors(data)
     19{'decimal': ['Please enter a valid decimal number.'], 'float': ['Please enter a valid floating point number.']}
     20>>> data = MultiValueDict({'decimal': ["0.2123"], 'float': ["0.200"]})
     21>>> manipulator.get_validation_errors(data)
     22{'decimal': ['Please enter a valid decimal number with at most 4 total digits.']}
     23>>> data = MultiValueDict({'decimal': ["0.212"], 'float': ["0.200"]})
     24>>> manipulator.get_validation_errors(data)
     25{'decimal': ['Please enter a valid decimal number with at most 2 decimal places.']}
     26>>> data = MultiValueDict({'decimal': ["0.20"], 'float': ["0.200"]})
     27>>> manipulator.get_validation_errors(data)
     28{}
     29>>> manipulator.do_html2python(data)
     30>>> data
     31<MultiValueDict: {'decimal': [Decimal("0.20")], 'float': [0.20000000000000001]}>
     32"""
     33
     34if __name__ == "__main__":
     35    import doctest
     36    doctest.testmod()
  • tests/regressiontests/decimal_vs_float/models.py

     
     1from django.db import models
     2try:
     3    from decimal import Decimal
     4except ImportError:
     5    from django.utils.decimal import Decimal
     6
     7class DecimalVsFloat(models.Model):
     8    fixed = models.DecimalField(max_digits=3, decimal_places=1, null=True)
     9    floating = models.FloatField(null=True)
     10
     11    def __str__(self):
     12        return "%r %r" % (self.fixed, self.floating)
     13
     14__test__ = {'ROUNDTRIP_TESTS': r"""
     15
     16Create some useful numbers for testing against
     17
     18>>> fixed = Decimal('0.2')
     19>>> floating = 1.2 - 1.0
     20>>> delta = 5e-17
     21
     22Ensure the numbers precisely survive a round-trip to the database.
     23
     24>>> n = DecimalVsFloat.objects.create(fixed=fixed, floating=floating)
     25>>> n = DecimalVsFloat.objects.get(pk=n.id)
     26>>> type(n.fixed) == Decimal
     27True
     28>>> type(n.floating) == float
     29True
     30>>> n.fixed
     31Decimal("0.2")
     32
     33Need to do a delta test here because MySQL seems to convert 0.19999999999999996 to 0.20000000000000001
     34
     35>>> n.floating + delta >= floating >= n.floating - delta
     36True
     37>>> n = DecimalVsFloat.objects.create(fixed=None, floating=None)
     38>>> print DecimalVsFloat.objects.get(pk=n.id)
     39None None
     40
     41
     42Note: if you assign a float to a DecimalField or a Decimal to a FloatField,
     43that's your own problem; the behaviour will depend on the database.
     44
     45"""}
     46
     47if __name__ == "__main__":
     48    import doctest
     49    doctest.testmod()
  • docs/model-api.txt

     
    184184The admin represents this as two ``<input type="text">`` fields, with
    185185JavaScript shortcuts.
    186186
     187``DecimalField``
     188~~~~~~~~~~~~~~
     189
     190A fixed-precision decimal number, represented in Python by a ``Decimal`` instance.
     191Has two **required** arguments:
     192
     193    ======================  ===================================================
     194    Argument                Description
     195    ======================  ===================================================
     196    ``max_digits``          The maximum number of digits allowed in the number.
     197
     198    ``decimal_places``      The number of decimal places to store with the
     199                            number.
     200    ======================  ===================================================
     201
     202For example, to store numbers up to 999 with a resolution of 2 decimal places,
     203you'd use::
     204
     205    models.DecimalField(..., max_digits=5, decimal_places=2)
     206
     207And to store numbers up to approximately one billion with a resolution of 10
     208decimal places::
     209
     210    models.DecimalField(..., max_digits=19, decimal_places=10)
     211
     212The admin represents this as an ``<input type="text">`` (a single-line input).
     213
    187214``EmailField``
    188215~~~~~~~~~~~~~~
    189216
     
    281308``FloatField``
    282309~~~~~~~~~~~~~~
    283310
    284 A floating-point number. Has two **required** arguments:
     311A floating-point number represented in Python by a ``float`` instance.
    285312
    286     ======================  ===================================================
    287     Argument                Description
    288     ======================  ===================================================
    289     ``max_digits``          The maximum number of digits allowed in the number.
    290 
    291     ``decimal_places``      The number of decimal places to store with the
    292                             number.
    293     ======================  ===================================================
    294 
    295 For example, to store numbers up to 999 with a resolution of 2 decimal places,
    296 you'd use::
    297 
    298     models.FloatField(..., max_digits=5, decimal_places=2)
    299 
    300 And to store numbers up to approximately one billion with a resolution of 10
    301 decimal places::
    302 
    303     models.FloatField(..., max_digits=19, decimal_places=10)
    304 
    305313The admin represents this as an ``<input type="text">`` (a single-line input).
    306314
    307315``ImageField``
  • docs/forms.txt

     
    546546    * isValidANSIDate
    547547    * isValidANSITime
    548548    * isValidEmail
     549    * isValidFloat
    549550    * isValidImage
    550551    * isValidImageURL
    551552    * isValidPhone
     
    635636    Takes an integer argument and when called as a validator, checks that the
    636637    field being validated is a power of the integer.
    637638
    638 ``IsValidFloat``
     639``IsValidDecimal``
    639640    Takes a maximum number of digits and number of decimal places (in that
    640     order) and validates whether the field is a float with less than the
    641     maximum number of digits and decimal place.
     641    order) and validates whether the field is a decimal with no more than the
     642    maximum number of digits and decimal places.
    642643
    643644``MatchesRegularExpression``
    644645    Takes a regular expression (a string) as a parameter and validates the
Back to Top