[Python-checkins] r68608 - in sandbox/trunk/decimal/decimal_in_c: README deccoeff.c
mark.dickinson
python-checkins at python.org
Wed Jan 14 12:44:26 CET 2009
Author: mark.dickinson
Date: Wed Jan 14 12:44:26 2009
New Revision: 68608
Log:
Reorganize Decimal coefficient code slightly, expand comments, add docstring
for Deccoeff.digit_length, and call limbs_as_unicode from deccoeff_str
to remove duplication of code.
Modified:
sandbox/trunk/decimal/decimal_in_c/README
sandbox/trunk/decimal/decimal_in_c/deccoeff.c
Modified: sandbox/trunk/decimal/decimal_in_c/README
==============================================================================
--- sandbox/trunk/decimal/decimal_in_c/README (original)
+++ sandbox/trunk/decimal/decimal_in_c/README Wed Jan 14 12:44:26 2009
@@ -129,3 +129,17 @@
>>> 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.
Modified: sandbox/trunk/decimal/decimal_in_c/deccoeff.c
==============================================================================
--- sandbox/trunk/decimal/decimal_in_c/deccoeff.c (original)
+++ sandbox/trunk/decimal/decimal_in_c/deccoeff.c Wed Jan 14 12:44:26 2009
@@ -245,7 +245,7 @@
static long
limb_hash(limb_t x) {
- return (long)x;
+ return (long)(x % LONG_MAX);
}
/* smallest nonnegative i such that x < 10**i; undefined if x == 0 */
@@ -332,6 +332,8 @@
limb_lshift(limb_t *res, limb_t a, Py_ssize_t n, limb_t b) {
if (!(0 <= n && n <= LIMB_DIGITS))
limb_error("limb_lshift: invalid shift index");
+ if (b != limb_mask(b, n))
+ limb_error("limb_lshift: b out of range");
if (LIMB_DIGITS == n) {
*res = b;
return a;
@@ -346,7 +348,9 @@
limb_rshift(limb_t *res, limb_t a, Py_ssize_t n, limb_t b) {
limb_t rem;
if (!(0 <= n && n <= LIMB_DIGITS))
- limb_error("limb_lshift: invalid shift index");
+ limb_error("limb_rshift: invalid shift index");
+ if (b != limb_mask(b, n))
+ limb_error("limb_rshift: b out of range");
if (LIMB_DIGITS == n) {
*res = b;
return a;
@@ -412,8 +416,8 @@
#error "unrecognised value for LIMB_DIGITS"
#endif
-/* res[0:a_size+b_size] := a*b, assuming b_size <= MIN(MAX_PARTIALS, a_size).
- This is a dropin replacement for limbs_mul. */
+/* res[0:a_size+b_size] := a*b, assuming b_size <= MIN(MAX_PARTIALS,
+ a_size). */
static void
limbs_fastmultiply_init(limb_t *res, const limb_t *a, Py_ssize_t a_size,
@@ -447,7 +451,7 @@
res[0:a_size+b_size] := a*b + res[0:a_size],
- assuming b_size <= MIN(MAX_PARTIALS, a_size) */
+ still assuming b_size <= MIN(MAX_PARTIALS, a_size) */
static void
limbs_fastmultiply_add(limb_t *res, const limb_t *a, Py_ssize_t a_size,
@@ -479,7 +483,8 @@
assert(acc == 0);
}
-/* res[0:a_size+b_size] := a * b */
+/* res[0:a_size+b_size] := a * b. This is a dropin replacement for
+ limbs_mul. */
static void
limbs_fastmultiply(limb_t *res, const limb_t *a, Py_ssize_t a_size,
@@ -497,6 +502,8 @@
if (b_size < MAX_PARTIALS)
limbs_fastmultiply_init(res, a, a_size, b, b_size);
else {
+ /* break b up into chunks of size <= MAX_PARTIALS,
+ and do a separate multiply for each chunk */
limbs_fastmultiply_init(res, a, a_size, b, MAX_PARTIALS);
b_size -= MAX_PARTIALS;
b += MAX_PARTIALS;
@@ -511,9 +518,6 @@
}
}
-#undef LIMB_BASE
-
-
/*********************************
* Arithmetic on arrays of limbs *
*********************************/
@@ -522,22 +526,6 @@
don't take care of memory allocation; they all assume that sufficient space
is provided for their results. */
-/* Rational approximations to log(10)/log(2), used for base conversion:
- 485/146 = 3.321917808219...
- log2(10) = 3.321928094887...
- 2136/643 = 3.321928460342...
-
- Note that for correctness of scale_Py_ssize_t, it's required that LOG2_10UP
- * LOG2_10UQ * LIMB_DIGITS * PyLong_SHIFT and LOG2_10LP * LOG2_10LQ *
- LIMB_DIGITS * PyLong_SHIFT both fit into a Py_ssize_t. The values below
- are okay even if LIMB_DIGITS = 19 and PyLong_SHIFT = 64.
-*/
-
-#define LOG2_10LP 485
-#define LOG2_10LQ 146
-#define LOG2_10UP 2136
-#define LOG2_10UQ 643
-
/* add n-limb numbers a and b, producing an n-limb result res and a carry */
static bool
@@ -672,7 +660,7 @@
instead. This code left in for testing and debugging purposes. */
static void
-limbs_mul(limb_t *res, const limb_t *a, Py_ssize_t a_size,
+limbs_multiply(limb_t *res, const limb_t *a, Py_ssize_t a_size,
const limb_t *b, Py_ssize_t b_size)
{
Py_ssize_t i, j;
@@ -687,9 +675,9 @@
}
}
-/* divide a_size-limb number a by single limb x, giving a_size-limb quotient
- res and returning the (single limb) remainder. If the input high is
- nonzero, it's treated as digit a_size of a. */
+/* divide a_size-limb number a by single nonzero limb x, giving a_size-limb
+ quotient res and returning the (single limb) remainder. If the input high
+ is nonzero, it's treated as digit a_size of a. */
static limb_t
limbs_div1(limb_t *res, const limb_t *a, Py_ssize_t a_size,
@@ -707,7 +695,7 @@
standard: see Knuth, TAOCP, Volume 4. */
static void
-limbs_div(limb_t *quot, limb_t *rem, const limb_t *a, Py_ssize_t a_size,
+limbs_divmod(limb_t *quot, limb_t *rem, const limb_t *a, Py_ssize_t a_size,
const limb_t *b, Py_ssize_t b_size, limb_t *w)
{
limb_t scale, top, a_top, b_top, q, dummy;
@@ -949,18 +937,14 @@
assert(digits_in_limb == LIMB_DIGITS);
}
-/* Base conversion, from base 2**15 to base LIMB_BASE.
+/* Base conversion, from base PyLong_BASE to base LIMB_BASE.
- Convert an array of (base 2**15) digits for a Python long to an
- array of limbs representing the same number. Returns the number of
- limbs of a filled. The result is normalized, in the sense that if
- the returned size a_size is nonzero then a[a_size-1] is nonzero.
+ Convert an array of digits for a Python long to an array of limbs
+ representing the same number. Returns the number of limbs of a filled.
+ The result is normalized, in the sense that if the returned size a_size is
+ nonzero then a[a_size-1] is nonzero.
- a should have at least:
-
- ceiling(b_size * log(2**15)/log(LIMB_BASE))
-
- limbs available.
+ a should have sufficient space to store the converted result.
*/
static Py_ssize_t
@@ -979,7 +963,8 @@
return a_size;
}
-/* base conversion, from base LIMB_BASE to base 2**30. */
+/* base conversion, from base LIMB_BASE to base PyLong_BASE.
+ b should have sufficient space to store the converted result. */
static Py_ssize_t
limbs_to_longdigits(digit *b, const limb_t *a, Py_ssize_t a_size)
@@ -1017,23 +1002,17 @@
* Karatsuba multiplication *
****************************/
-/* Note that for a balanced multiplication, where you don't want to
- keep the original multiplicands, one can do the multiplication
- without any additional workspace necessary:
-
- to multiply a0 a1 * b0 b1, with result in z0 z1 z2 z3
- (1) a0 - a1 -> z2
- (2) b0 - b1 -> z3
- (3) a0 * b0 -> z0 z1
- (4) b1 -> a0
- (5) z2 * z3 -> b0 b1
- (6) a0 * a1 -> z2 z3
- (7)
-*/
-
+/* Karatsuba multiplication algorithm. There are two functions here: the
+ first, limbs_kmul, does Karatsuba multiplication in the more-or-less
+ balanced case, where the multiplier and multiplicand have roughly the same
+ number of limbs.
+
+ The second function, limbs_mul_dispatch, performs multiplication for
+ arbitrary sizes, splitting one or other of the arguments if necessary
+ before calling the balanced Karatsuba function. */
-/* Unbalanced karatsuba multiplication: multiply a and b, putting result (of
- size a_size + b_size) in res. w provides workspace.
+/* Basic karatsuba multiplication: multiply a and b, putting result (of size
+ a_size + b_size) in res. w provides workspace.
Preconditions: 1 <= k < a_size <= b_size <= 2*k, and k is a
power of 2.
@@ -1066,45 +1045,22 @@
+-----+-+-----+
0 n-k k n
- Sizes:
- a0 k
- a1 m-k
- b0 n-k
- b1 k
- c k
- d k
- a0*b0 n
- a1*b1 m
- c*d 2*k
*/
-
-/* notes:
-
- (1) there's no real need to pass w_size around, but it helps guard
- against errors
- (2) slice notation in the comments below is as in Python:
- res[2n:4n] means the number represented by res[2*n] through
- res[4*n-1], inclusive.
-*/
-
-/* decide how to handle a particular size of multiplication, and
- dispatch to the appropriate function to do the computation */
-
-/* strategy: wlog suppose 1 <= m <= n.
+/* strategy for limbs_mul_dispatch: wlog suppose 1 <= m <= n.
(1) if m == 1, do a basecase multiplication.
Otherwise, let k be the largest power of 2 strictly less than m
(so k < m <= 2*k). Then:
- (2) If n <= 2*k, do a Karatsuba multiplication. Else
+ (2) If n <= 2*k, do a Karatsuba multiplication.
(3) Otherwise, split n as n[:2k] and n[2k:], and do an m*(2k) Karatsuba
multiplication and a m * (n-2k) multiplication (via a recursive call to
limbs_mul_dispatch). Add the results.
- Question: how much workspace do we need for this?
+ How much workspace do we need for this?
Write W(m, n) for the amount of workspace needed; assume 1 <= m <= n.
@@ -1138,6 +1094,9 @@
#define KARATSUBA_CUTOFF 72
+/* we don't absolutely have to pass w_size around, but doing so
+ helps guard against errors */
+
/* limbs_kmul and limbs_mul_dispatch call each other recursively,
so we need a forward declaration */
@@ -1280,12 +1239,22 @@
static PyTypeObject deccoeff_DeccoeffType;
+/* output contents of a deccoeff, for debugging */
+
+static void
+deccoeff_printf(const char *name, deccoeff *v)
+{
+ limbs_printf(name, v->ob_limbs, Py_SIZE(v));
+ printf("Number of limbs: %ld\n", Py_SIZE(v));
+}
+
/* allocate a new decimal integer with 'size' limbs */
static deccoeff *
_deccoeff_new(Py_ssize_t size)
{
/* XXX check for overflow */
+ assert(size >= 0);
return PyObject_NEW_VAR(deccoeff, &deccoeff_DeccoeffType, size);
}
@@ -1302,9 +1271,10 @@
return v;
}
-/* returns its argument (with reference count unaffected) if the argument has
- MAX_DIGITS or fewer digits. Otherwise it decrements the reference count
- for its argument, sets OverflowError, and returns NULL. */
+/* deccoeff_checksize returns its argument (with reference count unaffected)
+ if the argument has MAX_DIGITS or fewer digits. Otherwise it decrements
+ the reference count for its argument, sets OverflowError, and returns
+ NULL. */
static deccoeff *
deccoeff_checksize(deccoeff *v)
@@ -1333,6 +1303,8 @@
return NULL;
}
+/* Make a copy of a deccoeff */
+
static deccoeff *
_deccoeff_copy(deccoeff *a)
{
@@ -1367,6 +1339,10 @@
return z;
}
+/* convert an array of unicode characters into a Deccoeff instance.
+ May raise OverflowError if the character array is too long, or
+ ValueError if the array is invalid. */
+
static deccoeff *
_deccoeff_from_unicode_and_size(const Py_UNICODE *s, Py_ssize_t s_len) {
Py_ssize_t z_size;
@@ -1391,9 +1367,15 @@
"nondigit character in input");
return NULL;
}
+
return deccoeff_normalize(z);
}
+/* Variant of the above that converts an array of unicode digits containing a
+ decimal point at position int_len (but no sign). The decimal point is
+ simply ignored. This is used to parse the coefficient of a Decimal
+ instance. */
+
static deccoeff *
_deccoeff_from_pointed_unicode_and_size(const Py_UNICODE *s, Py_ssize_t s_len,
Py_ssize_t int_len) {
@@ -1416,17 +1398,109 @@
}
+/***********************************
+ * Deccoeff <-> PyLong conversions *
+ ***********************************/
+
+/* Rational approximations to log2(10):
+
+ LOG2_10LP/LOG2_10LQ is a lower bound for log2(10);
+ LOG2_10UP/LOG2_10UQ is an upper bound.
+
+ 485/146 = 3.321917808219...
+ log2(10) = 3.321928094887...
+ 2136/643 = 3.321928460342...
+
+ For correctness of scale_Py_ssize_t, it's required that LOG2_10UP *
+ LOG2_10UQ * LIMB_DIGITS * PyLong_SHIFT and LOG2_10LP * LOG2_10LQ *
+ LIMB_DIGITS * PyLong_SHIFT both fit into a Py_ssize_t. The values below
+ are okay even if we're using 64-bit types to hold limbs and digits: in that
+ case, LIMB_DIGITS <= 19 and PyLong_SHIFT <= 64.
+*/
+
+#define LOG2_10LP 485
+#define LOG2_10LQ 146
+#define LOG2_10UP 2136
+#define LOG2_10UQ 643
+
+/* Compute ceiling(n*p/q) without intermediate overflow. If the result
+ would be larger than PY_SSIZE_T_MAX, return -1. Assumes that
+ n is nonnegative, and that (q-1)*(p+1) <= PY_SSIZE_T_MAX. */
+
+static Py_ssize_t
+scale_Py_ssize_t(Py_ssize_t n, int p, int q) {
+ Py_ssize_t hi, low;
+ assert (n >= 0);
+ hi = n/q;
+ if (hi > PY_SSIZE_T_MAX/p)
+ return -1;
+ hi *= p;
+ low = (n%q*p+q-1)/q;
+ if (hi > PY_SSIZE_T_MAX-low)
+ return -1;
+ return hi+low;
+}
+
+/* Create a Deccoeff from a Python integer. */
+
+static deccoeff *
+deccoeff_from_PyLong(PyLongObject *a)
+{
+ Py_ssize_t a_size, z_size;
+ deccoeff *z;
+
+ a_size = Py_SIZE(a);
+ if (a_size < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "Can't convert negative integer to " CLASS_NAME);
+ return NULL;
+ }
+ z_size = scale_Py_ssize_t(a_size,
+ LOG2_10LQ * PyLong_SHIFT,
+ LOG2_10LP * LIMB_DIGITS);
+ if (z_size == -1)
+ PyErr_SetString(PyExc_OverflowError,
+ "Overflow in int to " CLASS_NAME " conversion\n");
+ z = _deccoeff_new(z_size);
+ if (z==NULL)
+ return NULL;
+ Py_SIZE(z) = limbs_from_longdigits(z->ob_limbs, a->ob_digit, a_size);
+ return deccoeff_checksize(z);
+}
+
+/* Convert a Python integer to a Deccoeff */
+
+static PyLongObject *
+deccoeff_long(deccoeff *a)
+{
+ Py_ssize_t a_size, z_size;
+ PyLongObject *z;
+
+ a_size = Py_SIZE(a);
+ z_size = scale_Py_ssize_t(a_size,
+ LOG2_10UP * LIMB_DIGITS,
+ LOG2_10UQ * PyLong_SHIFT);
+ if (z_size == -1)
+ PyErr_SetString(PyExc_OverflowError,
+ "Overflow in " CLASS_NAME " to int conversion\n");
+ z = _PyLong_New(z_size);
+ if (z == NULL)
+ return NULL;
+ Py_SIZE(z) = limbs_to_longdigits(z->ob_digit, a->ob_limbs, a_size);
+ return z;
+}
+
/***************************
* Arithmetic on deccoeffs *
***************************/
-/* General rules: if the result of any arithmetic operation falls
- outside the range [0, 10**MAX_DIGITS) then OverflowError is raised.
- Results are always normalized. */
+/* General rules: if the result of any arithmetic operation falls outside the
+ range [0, 10**MAX_DIGITS) then OverflowError is raised. Results are always
+ normalized. */
-/* determine whether another Python object is compatible with deccoeff, in the
- sense that it can be used in mixed-type arithmetic with deccoeff */
+/* determine whether another Python object can be used in mixed-type arithmetic
+ with deccoeff */
static bool
compatible_with_deccoeff(PyObject *v)
@@ -1434,11 +1508,7 @@
return (v->ob_type == &deccoeff_DeccoeffType || PyIndex_Check(v));
}
-/* convert an arbitrary PyObject to a deccoeff. If conversion is implemented
- for this type, return false and put the result of the attempted conversion
- (which may be NULL on failure) in *z. Otherwise, return true. */
-
-static deccoeff *deccoeff_from_PyLong(PyLongObject *a);
+/* convert an arbitrary PyObject to a Deccoeff. Returns a new reference. */
static deccoeff *
convert_to_deccoeff(PyObject *v)
@@ -1465,28 +1535,31 @@
}
}
+/* wrap a binary operation on deccoeffs to give a binary
+ operation on PyObjects */
+
#define DECCOEFF_WRAP_BINOP(PO_func, DC_func) \
static PyObject * \
PO_func(PyObject *v, PyObject *w) \
{ \
- deccoeff *a, *b; \
- PyObject *z = NULL; \
- if (!compatible_with_deccoeff(v)) { \
- Py_INCREF(Py_NotImplemented); \
- z = Py_NotImplemented; \
- } \
- else if ((a = convert_to_deccoeff(v)) != NULL) { \
- if (!compatible_with_deccoeff(w)) { \
- Py_INCREF(Py_NotImplemented); \
- z = Py_NotImplemented; \
- } \
- else if ((b = convert_to_deccoeff(w)) != NULL) { \
- z = (PyObject *)(DC_func(a, b)); \
- Py_DECREF(b); \
- } \
- Py_DECREF(a); \
- } \
- return z; \
+ deccoeff *a, *b; \
+ PyObject *z = NULL; \
+ if (!compatible_with_deccoeff(v)) { \
+ Py_INCREF(Py_NotImplemented); \
+ z = Py_NotImplemented; \
+ } \
+ else if ((a = convert_to_deccoeff(v)) != NULL) { \
+ if (!compatible_with_deccoeff(w)) { \
+ Py_INCREF(Py_NotImplemented); \
+ z = Py_NotImplemented; \
+ } \
+ else if ((b = convert_to_deccoeff(w)) != NULL) { \
+ z = (PyObject *)(DC_func(a, b)); \
+ Py_DECREF(b); \
+ } \
+ Py_DECREF(a); \
+ } \
+ return z; \
}
/* addition */
@@ -1635,7 +1708,7 @@
*r = NULL;
return NULL;
}
- limbs_div(quot->ob_limbs, rem->ob_limbs, a->ob_limbs, a_size,
+ limbs_divmod(quot->ob_limbs, rem->ob_limbs, a->ob_limbs, a_size,
b->ob_limbs, b_size, w->ob_limbs);
Py_DECREF(w);
}
@@ -2066,71 +2139,6 @@
return z;
}
-/* Compute ceiling(n*p/q) without intermediate overflow. If the result
- would be larger than PY_SSIZE_T_MAX, return -1. Assumes that
- n is nonnegative, and that (q-1)*(p+1) <= PY_SSIZE_T_MAX. */
-
-static Py_ssize_t
-scale_Py_ssize_t(Py_ssize_t n, int p, int q) {
- Py_ssize_t hi, low;
- assert (n >= 0);
- hi = n/q;
- if (hi > PY_SSIZE_T_MAX/p)
- return -1;
- hi *= p;
- low = (n%q*p+q-1)/q;
- if (hi > PY_SSIZE_T_MAX-low)
- return -1;
- return hi+low;
-}
-
-/* Create a deccoeff from a Python integer. */
-
-static deccoeff *
-deccoeff_from_PyLong(PyLongObject *a)
-{
- Py_ssize_t a_size, z_size;
- deccoeff *z;
-
- a_size = Py_SIZE(a);
- if (a_size < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "Can't convert negative integer to " CLASS_NAME);
- return NULL;
- }
- z_size = scale_Py_ssize_t(a_size,
- LOG2_10LQ * PyLong_SHIFT,
- LOG2_10LP * LIMB_DIGITS);
- if (z_size == -1)
- PyErr_SetString(PyExc_OverflowError,
- "Overflow in int to " CLASS_NAME " conversion\n");
- z = _deccoeff_new(z_size);
- if (z==NULL)
- return NULL;
- Py_SIZE(z) = limbs_from_longdigits(z->ob_limbs, a->ob_digit, a_size);
- return deccoeff_checksize(z);
-}
-
-static PyLongObject *
-deccoeff_long(deccoeff *a)
-{
- Py_ssize_t a_size, z_size;
- PyLongObject *z;
-
- a_size = Py_SIZE(a);
- z_size = scale_Py_ssize_t(a_size,
- LOG2_10UP * LIMB_DIGITS,
- LOG2_10UQ * PyLong_SHIFT);
- if (z_size == -1)
- PyErr_SetString(PyExc_OverflowError,
- "Overflow in " CLASS_NAME " to int conversion\n");
- z = _PyLong_New(z_size);
- if (z == NULL)
- return NULL;
- Py_SIZE(z) = limbs_to_longdigits(z->ob_digit, a->ob_limbs, a_size);
- return z;
-}
-
static PyObject *
deccoeff_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
@@ -2193,6 +2201,16 @@
return PyLong_FromSsize_t(_deccoeff_length(v));
}
+PyDoc_STRVAR(deccoeff_digit_length_doc,
+"\
+Deccoeff.digit_length(self) -> integer\n\
+\n\
+Number of decimal digits required to represent self.\n\
+\n\
+If self is positive, return the least nonnegative integer\n\
+k such that self < 10**k. If self is zero, return 0.\n\
+");
+
static void
deccoeff_dealloc(PyObject *v)
{
@@ -2248,7 +2266,7 @@
static PyMethodDef deccoeff_methods[] = {
{"digit_length", (PyCFunction)deccoeff_digit_length, METH_NOARGS,
- "Number of digits."},
+ deccoeff_digit_length_doc},
{NULL, NULL}
};
@@ -2276,7 +2294,7 @@
0, /*nb_xor*/
0, /*nb_or*/
(unaryfunc) deccoeff_long, /*nb_int*/
- (unaryfunc) deccoeff_long, /*nb_long*/
+ 0, /*nb_long*/
0, /*nb_float*/
0, /*nb_inplace_add*/
0, /*nb_inplace_subtract*/
@@ -2295,18 +2313,17 @@
(unaryfunc) deccoeff_long, /*nb_index*/
};
+/* str(deccoeff) */
+
static PyObject *
deccoeff_str(deccoeff *v)
{
- Py_ssize_t sz, nlimbs;
- limb_t *limb_pointer, *last_limb, limb_value;
+ Py_ssize_t size, nlimbs;
PyObject *str;
- int i;
Py_UNICODE *p;
nlimbs = Py_SIZE(v);
if (nlimbs == 0) {
- /* return empty string */
str = PyUnicode_FromUnicode(NULL, 1);
if (str == NULL)
return NULL;
@@ -2315,35 +2332,21 @@
*--p = '0';
return str;
}
+ size = _deccoeff_length(v);
- sz = _deccoeff_length(v);
-
- str = PyUnicode_FromUnicode(NULL, sz);
+ assert(size >= 0);
+ str = PyUnicode_FromUnicode(NULL, size);
if (str == NULL)
return NULL;
- p = PyUnicode_AS_UNICODE(str) + sz;
- *p = '\0';
+ p = PyUnicode_AS_UNICODE(str);
- /* fill in digits from right to left; start with the least
- significant limb_t */
- limb_pointer = v -> ob_limbs;
- last_limb = limb_pointer + nlimbs - 1;
- while (limb_pointer < last_limb) {
- limb_value = *limb_pointer++;
- for (i=0; i < LIMB_DIGITS; i++)
- *--p = limb_to_wdigit(
- limb_rshift(&limb_value,
- limb_value, 1, LIMB_ZERO));
- }
- /* most significant limb_t */
- limb_value = *limb_pointer;
- assert(limb_bool(limb_value));
- while (limb_bool(limb_value))
- *--p = limb_to_wdigit(
- limb_rshift(&limb_value, limb_value, 1, LIMB_ZERO));
+ limbs_as_unicode(p, size, v->ob_limbs);
+ *(p+size) = '\0';
return str;
}
+/* repr(Deccoeff_instance) looks like "Deccoeff('123')" */
+
static PyObject *
deccoeff_repr(deccoeff *v)
{
@@ -2410,10 +2413,10 @@
/* A finite decimal object needs a sign, a coefficient and an exponent. An
infinity has a sign and nothing more; the coefficient and exponent are
ignored. A (quiet or signalling) nan has a sign, and may carry additional
- information in the coefficient. The exponent is not used. */
+ information (the payload) in the coefficient. The exponent is not used. */
#define DEC_FLAGS_NEG (1<<0)
-#define DEC_FLAGS_NONZERO (1<<1) /* currently unused, but may want this later */
+#define DEC_FLAGS_NONZERO (1<<1) /* currently unused; may want this later */
#define DEC_FLAGS_SPECIAL (1<<2)
#define DEC_FLAGS_INF (1<<3)
#define DEC_FLAGS_NAN (1<<4)
@@ -2505,10 +2508,14 @@
/* Macros to create finite, infinite, qnan, and snan _Decimal instances */
-#define FINITE_DECIMAL(type, sign, coeff, exp) (__Decimal_new(type, sign, coeff, exp))
-#define INF_DECIMAL(type, sign) (__Decimal_new(type, sign | INF_FLAGS, NULL, NULL))
-#define QNAN_DECIMAL(type, sign, payload) (__Decimal_new(type, sign | QNAN_FLAGS, payload, NULL))
-#define SNAN_DECIMAL(type, sign, payload) (__Decimal_new(type, sign | SNAN_FLAGS, payload, NULL))
+#define FINITE_DECIMAL(type, sign, coeff, exp) \
+ (__Decimal_new(type, sign, coeff, exp))
+#define INF_DECIMAL(type, sign) \
+ (__Decimal_new(type, sign | INF_FLAGS, NULL, NULL))
+#define QNAN_DECIMAL(type, sign, payload) \
+ (__Decimal_new(type, sign | QNAN_FLAGS, payload, NULL))
+#define SNAN_DECIMAL(type, sign, payload) \
+ (__Decimal_new(type, sign | SNAN_FLAGS, payload, NULL))
/* create a new finite _Decimal instance */
@@ -2819,7 +2826,8 @@
if (!PyArg_ParseTuple(args, "iO:" DECIMAL_NAME, &sign, &opayload))
return NULL;
if (opayload->ob_type != &deccoeff_DeccoeffType) {
- PyErr_SetString(PyExc_TypeError, "payload should have type " CLASS_NAME);
+ PyErr_SetString(PyExc_TypeError,
+ "payload should have type " CLASS_NAME);
return NULL;
}
payload = (deccoeff *)opayload;
@@ -2841,7 +2849,8 @@
if (!PyArg_ParseTuple(args, "iO:" DECIMAL_NAME, &sign, &opayload))
return NULL;
if (opayload->ob_type != &deccoeff_DeccoeffType) {
- PyErr_SetString(PyExc_TypeError, "payload should have type " CLASS_NAME);
+ PyErr_SetString(PyExc_TypeError,
+ "payload should have type " CLASS_NAME);
return NULL;
}
payload = (deccoeff *)opayload;
@@ -3053,35 +3062,35 @@
static PyTypeObject deccoeff__DecimalType = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
- MODULE_NAME "." DECIMAL_NAME, /* tp_name */
- sizeof(_Decimal), /* tp_basicsize */
- 0, /* tp_itemsize */
- _Decimal_dealloc, /* tp_dealloc */
+ MODULE_NAME "." DECIMAL_NAME, /* tp_name */
+ sizeof(_Decimal), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ _Decimal_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
- 0, /* tp_repr */
- 0, /* tp_as_number */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
0, /* tp_call */
- 0, /* tp_str */
+ 0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- "support for Decimal type", /* tp_doc */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+ "support for Decimal type", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
- 0, /* tp_richcompare */
+ 0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
- _Decimal_methods, /* tp_methods */
+ _Decimal_methods, /* tp_methods */
0, /* tp_members */
- _Decimal_getsetters, /* tp_getset */
+ _Decimal_getsetters, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
@@ -3089,8 +3098,8 @@
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
- _Decimal_new, /* tp_new */
- PyObject_Del, /* tp_free */
+ _Decimal_new, /* tp_new */
+ PyObject_Del, /* tp_free */
};
static PyMethodDef deccoeff_module_methods[] = {
More information about the Python-checkins
mailing list