Deccoeff is an extension type for Python 3.0 that implements nonnegative decimal integers. These integers can be used in arithmetic in the usual way and also treated as strings of decimal digits. The main purpose of Deccoeff is to act as the coefficient type for Decimal instances. Questions, comments, suggestions, etc., should go to Mark Dickinson at dickinsm@gmail.com. This distribution also contains a version of decimal.py that's adapted to use the Deccoeff type, along with all the decimal tests for testing purposes. Installation instructions (unix) -------------------------------- (1) Edit the top line of the Makefile to point to a Python 3.x executable. (2) make (3) make install (4) make test (runs the entire decimal test-suite) Usage ----- To get started, just import Deccoeff from deccoeff (or type 'make run'). dickinsm$ python3.0 Python 3.0rc1+ (py3k:66550M, Sep 22 2008, 14:47:17) [GCC 4.0.1 (Apple Inc. build 5484)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> from deccoeff import * >>> D = Deccoeff Deccoeffs can be created from integers, strings, or other Deccoeffs: >>> D(2) Deccoeff('2') >>> D('1234') Deccoeff('1234') >>> D() Deccoeff('0') >>> D(D(314159)) Deccoeff('314159') Arithmetic works as expected, except that if the result of an arithmetic operation would be negative then OverflowError is raised. >>> D(23)**D(12) Deccoeff('21914624432020321') >>> D(1729) - D(729) Deccoeff('1000') >>> D(729) - D(1729) Traceback (most recent call last): File "", line 1, in OverflowError: difference is negative Deccoeff instances play nicely with other integer types, giving a Deccoeff result. >>> D(1234567) % 100 Deccoeff('67') There's an upper bound on the number of decimal digits a Deccoeff can have; it's made available to Python as deccoeff.MAX_DIGITS. >>> print(MAX_DIGITS) 1000000000 >>> x = D(1) << (MAX_DIGITS - 1) # fine >>> y = D(1) << MAX_DIGITS Traceback (most recent call last): File "", line 1, in OverflowError: Deccoeff instance has too many digits [32860 refs] A Deccoeff instance can be indexed and sliced to give an easy way to extract a subset of its digits. Note that indexing works from a mathematical perspective: x[0] refers to the units digit of x, x[1] refers to the tens digit, and so on. Thus in the usual representation of a nonnegative integer as a decimal string, x[0] is the *last* digit printed, not the first. The builtin function len, when applied to a Deccoeff, gives the number of decimal digits needed to print that Deccoeff, or 0 if the Deccoeff instance is zero. >>> x = D(314159265357989323) >>> x Deccoeff('314159265357989323') >>> x[10:] Deccoeff('31415926') >>> x[1] Deccoeff('2') >>> x[:5] Deccoeff('89323') >>> x[5:] Deccoeff('3141592653579') >>> len(x) 18 Note however that the start and stop arguments to the slice must be nonnegative, and that the step argument is not supported. As you'd expect for a decimal type, the shift operators multiply and divide by powers of 10, not 2. >>> x >> 10 Deccoeff('31415926') >>> x << 10 Deccoeff('3141592653579893230000000000') Internally, a Deccoeff instance is stored as an array of coefficients in base 10**LIMB_DIGITS, for some value of LIMB_DIGITS. While there's little reason for the user to care about the value of LIMB_DIGITS, it can be accessed as deccoeff.LIMB_DIGITS. >>> LIMB_DIGITS 9 Notes ----- The aim is to slowly move all Decimal methods to _Decimal. However, there's a minor problem with inheritance and subclasses of Decimal. For example, suppose MyDecimal is a subclass of Decimal. Then if x and y are instances of MyDecimal, x + y should produce a Decimal instance, not a MyDecimal instance. However, if we move the __add__ code from Decimal to _Decimal, we'll end up with a _Decimal instance instead. So all the _Decimal operations will still need to be wrapped at the Decimal level, during the Python -> C migration period.