[Python-checkins] r86318 - in python/branches/py3k-cdecimal/Modules/cdecimal: bits.h cdecimal.c constants.h context.c convolute.c crt.c difradix2.c error.c fnt.c fnt.h fourstep.c fourstep.h io.c memory.c mpdecimal.c mpdecimal32.h mpdecimal64.h mpsignal.c mptest.h mptypes.h numbertheory.h sixstep.c sixstep.h transpose.c typearith.h umodarith.h vccompat.h vcdiv64.asm
stefan.krah
python-checkins at python.org
Mon Nov 8 15:12:50 CET 2010
Author: stefan.krah
Date: Mon Nov 8 15:12:49 2010
New Revision: 86318
Log:
Sync cdecimal with the next version of mpdecimal (2.0):
1) New hash function and float operations.
2) Implement FloatOperation signal to detect accidental float operations.
3) New tests have 100% code coverage for the library and 85% for the module.
Added:
python/branches/py3k-cdecimal/Modules/cdecimal/mpsignal.c (contents, props changed)
Modified:
python/branches/py3k-cdecimal/Modules/cdecimal/bits.h
python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c
python/branches/py3k-cdecimal/Modules/cdecimal/constants.h
python/branches/py3k-cdecimal/Modules/cdecimal/context.c
python/branches/py3k-cdecimal/Modules/cdecimal/convolute.c
python/branches/py3k-cdecimal/Modules/cdecimal/crt.c
python/branches/py3k-cdecimal/Modules/cdecimal/difradix2.c
python/branches/py3k-cdecimal/Modules/cdecimal/error.c
python/branches/py3k-cdecimal/Modules/cdecimal/fnt.c
python/branches/py3k-cdecimal/Modules/cdecimal/fnt.h
python/branches/py3k-cdecimal/Modules/cdecimal/fourstep.c
python/branches/py3k-cdecimal/Modules/cdecimal/fourstep.h
python/branches/py3k-cdecimal/Modules/cdecimal/io.c
python/branches/py3k-cdecimal/Modules/cdecimal/memory.c
python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c
python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal32.h
python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal64.h
python/branches/py3k-cdecimal/Modules/cdecimal/mptest.h
python/branches/py3k-cdecimal/Modules/cdecimal/mptypes.h
python/branches/py3k-cdecimal/Modules/cdecimal/numbertheory.h
python/branches/py3k-cdecimal/Modules/cdecimal/sixstep.c
python/branches/py3k-cdecimal/Modules/cdecimal/sixstep.h
python/branches/py3k-cdecimal/Modules/cdecimal/transpose.c
python/branches/py3k-cdecimal/Modules/cdecimal/typearith.h
python/branches/py3k-cdecimal/Modules/cdecimal/umodarith.h
python/branches/py3k-cdecimal/Modules/cdecimal/vccompat.h
python/branches/py3k-cdecimal/Modules/cdecimal/vcdiv64.asm
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/bits.h
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/bits.h (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/bits.h Mon Nov 8 15:12:49 2010
@@ -19,12 +19,13 @@
return n != 0 && (n & (n-1)) == 0;
}
+#if defined(ANSI)
/*
* Returns the most significant bit position of n from 0 to 32 (64).
* Caller has to make sure that n is not 0.
*/
static inline int
-std_bsr(mpd_size_t n)
+mpd_bsr(mpd_size_t n)
{
int pos = 0;
mpd_size_t tmp;
@@ -47,13 +48,12 @@
return pos + (int)n - 1;
}
-
/*
* Returns the least significant bit position of n from 0 to 32 (64).
* Caller has to make sure that n is not 0.
*/
static inline int
-std_bsf(mpd_size_t n)
+mpd_bsf(mpd_size_t n)
{
int pos;
@@ -75,15 +75,15 @@
#endif
return pos;
}
+/* END ANSI */
-
-#if defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
+#elif defined(ASM)
/*
* Bit scan reverse.
* Caller has to make sure that a is not 0.
*/
static inline int
-x86_bsr(mpd_size_t a)
+mpd_bsr(mpd_size_t a)
{
mpd_size_t retval;
@@ -106,7 +106,7 @@
* Caller has to make sure that a is not 0.
*/
static inline int
-x86_bsf(mpd_size_t a)
+mpd_bsf(mpd_size_t a)
{
mpd_size_t retval;
@@ -123,17 +123,16 @@
return (int)retval;
}
-#endif /* __GNUC__ (amd64|i386) */
+/* END ASM */
-
-#ifdef _MSC_VER
+#elif defined(MASM)
#include <intrin.h>
/*
* Bit scan reverse.
* Caller has to make sure that a is not 0.
*/
static inline int __cdecl
-x86_bsr(mpd_size_t a)
+mpd_bsr(mpd_size_t a)
{
unsigned long retval;
@@ -151,7 +150,7 @@
* Caller has to make sure that a is not 0.
*/
static inline int __cdecl
-x86_bsf(mpd_size_t a)
+mpd_bsf(mpd_size_t a)
{
unsigned long retval;
@@ -163,7 +162,10 @@
return (int)retval;
}
-#endif /* _MSC_VER */
+/* END MASM (_MSC_VER) */
+#else
+ #error "missing preprocessor definitions"
+#endif /* BSR/BSF */
#endif /* BITS_H */
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/cdecimal.c Mon Nov 8 15:12:49 2010
@@ -17,6 +17,10 @@
#include "mptypes.h"
+#if PY_VERSION_HEX < 0x03000000
+ #error "Python versions < 3.0 not supported."
+#endif
+
#if defined(_MSC_VER) && defined (CONFIG_64)
#define _PyLong_AsMpdSsize PyLong_AsLongLong
#define _PyLong_FromMpdSsize PyLong_FromSsize_t
@@ -25,14 +29,13 @@
#define _PyLong_FromMpdSsize PyLong_FromLong
#endif
-
-#if PY_VERSION_HEX < 0x03000000
- #error "Python versions < 3.0 not supported"
-#endif
-
#define Dec_INCREF_TRUE (Py_INCREF(Py_True), Py_True)
#define Dec_INCREF_FALSE (Py_INCREF(Py_False), Py_False)
+#define MPD_Float_operation MPD_Not_implemented
+
+#define BOUNDS_CHECK(x, MIN, MAX) x = (x < MIN || MAX < x) ? MAX : x
+
typedef struct {
PyObject_HEAD
@@ -103,6 +106,7 @@
/* Exceptions that correspond to IEEE signals; inherit from DecimalException */
static DecCondMap signal_map[] = {
{"InvalidOperation", "cdecimal.InvalidOperation", MPD_IEEE_Invalid_operation, NULL},
+ {"FloatOperation", "cdecimal.FloatOperation", MPD_Float_operation, NULL},
{"DivisionByZero", "cdecimal.DivisionByZero", MPD_Division_by_zero, NULL},
{"Overflow", "cdecimal.Overflow", MPD_Overflow, NULL},
{"Underflow", "cdecimal.Underflow", MPD_Underflow, NULL},
@@ -136,16 +140,70 @@
"InvalidOperation",
"InvalidOperation",
"InvalidOperation",
- "NotImplemented",
+ "FloatOperation",
"Overflow",
"Rounded",
"Subnormal",
"Underflow",
};
-static void
-dec_traphandler(mpd_context_t *ctx UNUSED)
+static const char *invalid_rounding_err =
+"valid values for rounding are:\n\
+ [ROUND_CEILING, ROUND_FLOOR, ROUND_UP, ROUND_DOWN,\n\
+ ROUND_HALF_UP, ROUND_HALF_DOWN, ROUND_HALF_EVEN,\n\
+ ROUND_05UP].";
+
+static const char *invalid_signals_err =
+"valid values for signals are:\n\
+ [InvalidOperation, FloatOperation, DivisionByZero,\n\
+ Overflow, Underflow, Subnormal, Inexact, Rounded,\n\
+ Clamped].";
+
+static const char *invalid_flags_err =
+"valid values for _flags or _traps are:\n\
+ signals:\n\
+ [DecIEEEInvalidOperation, DecFloatOperation, DecDivisionByZero,\n\
+ DecOverflow, DecUnderflow, DecSubnormal, DecInexact, DecRounded,\n\
+ DecClamped]\n\
+ conditions which trigger DecIEEEInvalidOperation:\n\
+ [DecInvalidOperation, DecConversionSyntax, DecDivisionImpossible,\n\
+ DecDivisionUndefined, DecFpuError, DecInvalidContext, DecMallocError]";
+
+static int
+value_error_int(const char *mesg)
+{
+ PyErr_SetString(PyExc_ValueError, mesg);
+ return -1;
+}
+
+static PyObject *
+value_error_ptr(const char *mesg)
{
+ PyErr_SetString(PyExc_ValueError, mesg);
+ return NULL;
+}
+
+static int
+runtime_error_int(const char *mesg)
+{ /* GCOV_NOT_REACHED */
+ PyErr_SetString(PyExc_RuntimeError, mesg); /* GCOV_NOT_REACHED */
+ return -1; /* GCOV_NOT_REACHED */
+}
+#define INTERNAL_ERROR_INT(funcname) \
+ return runtime_error_int("internal error in " funcname ".")
+
+static PyObject *
+runtime_error_ptr(const char *mesg)
+{ /* GCOV_NOT_REACHED */
+ PyErr_SetString(PyExc_RuntimeError, mesg); /* GCOV_NOT_REACHED */
+ return NULL; /* GCOV_NOT_REACHED */
+}
+#define INTERNAL_ERROR_PTR(funcname) \
+ return runtime_error_ptr("internal error in " funcname ".")
+
+static void
+dec_traphandler(mpd_context_t *ctx UNUSED) /* GCOV_NOT_REACHED */
+{ /* GCOV_NOT_REACHED */
return;
}
@@ -160,8 +218,7 @@
}
}
- PyErr_SetString(PyExc_ValueError, "invalid flag value");
- return NULL;
+ INTERNAL_ERROR_PTR("flags_as_exception"); /* GCOV_NOT_REACHED */
}
static uint32_t
@@ -175,7 +232,7 @@
}
}
- PyErr_SetString(PyExc_ValueError, "invalid signal value");
+ PyErr_SetString(PyExc_ValueError, invalid_signals_err);
return UINT32_MAX;
}
@@ -186,21 +243,29 @@
DecCondMap *cm;
if ((list = PyList_New(0)) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
for (cm = cond_map; cm->name != NULL; cm++) {
if (flags&cm->mpd_cond) {
- PyList_Append(list, cm->dec_cond);
+ if (PyList_Append(list, cm->dec_cond) < 0) {
+ goto error; /* GCOV_UNLIKELY */
+ }
}
}
for (cm = signal_map+1; cm->name != NULL; cm++) {
if (flags&cm->mpd_cond) {
- PyList_Append(list, cm->dec_cond);
+ if (PyList_Append(list, cm->dec_cond) < 0) {
+ goto error; /* GCOV_UNLIKELY */
+ }
}
}
return list;
+
+error: /* GCOV_UNLIKELY */
+ Py_DECREF(list); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
static uint32_t
@@ -211,7 +276,8 @@
ssize_t n, j;
if (!PyList_Check(list)) {
- PyErr_SetString(PyExc_TypeError, "argument must be a signal list");
+ PyErr_SetString(PyExc_TypeError,
+ "argument must be a list of signals.");
return UINT32_MAX;
}
@@ -238,19 +304,19 @@
if (!PyDict_Check(val)) {
PyErr_SetString(PyExc_TypeError,
- "argument must be a signal dict");
+ "argument must be a signal dict.");
return -1;
}
for (cm = signal_map; cm->name != NULL; cm++) {
if ((b = PyDict_GetItem(val, cm->dec_cond)) == NULL) {
PyErr_SetString(PyExc_ValueError,
- "incomplete signal dict");
+ "incomplete signal dict.");
return UINT32_MAX;
}
if ((x = PyObject_IsTrue(b)) < 0) {
- return UINT32_MAX;
+ return UINT32_MAX; /* GCOV_UNLIKELY */
}
if (x == 1) {
flags |= cm->mpd_cond;
@@ -263,18 +329,14 @@
static uint32_t
PyLong_AsMpdFlags(PyObject *v)
{
- int overflow;
long x;
- if (!PyLong_Check(v)) {
- PyErr_SetString(PyExc_TypeError, "integer argument required");
+ x = PyLong_AsLong(v);
+ if (PyErr_Occurred()) {
return UINT32_MAX;
}
-
- overflow = 0;
- x = PyLong_AsLongAndOverflow(v, &overflow);
- if (overflow != 0 || x < 0 || x > (long)MPD_Max_status) {
- PyErr_SetString(PyExc_ValueError, "invalid flag value");
+ if (x < 0 || x > (long)MPD_Max_status) {
+ PyErr_SetString(PyExc_ValueError, invalid_flags_err);
return UINT32_MAX;
}
@@ -284,14 +346,11 @@
static mpd_ssize_t
PyLong_AsMpdSsize(PyObject *v)
{
-#if MPD_SIZE_MAX == SIZE_MAX
mpd_ssize_t x;
-#else
- int64_t x;
-#endif
if (!PyLong_Check(v)) {
- PyErr_SetString(PyExc_TypeError, "integer argument required");
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument required.");
return MPD_SSIZE_MAX;
}
@@ -299,12 +358,6 @@
if (PyErr_Occurred()) {
return MPD_SSIZE_MAX;
}
-#if MPD_SIZE_MAX < SIZE_MAX
- if (x < MPD_SSIZE_MIN || x > MPD_SSIZE_MAX) {
- PyErr_SetString(PyExc_ValueError, "argument out of range");
- return MPD_SSIZE_MAX;
- }
-#endif
return x;
}
@@ -316,11 +369,13 @@
if (ctx->traps&status) {
PyObject *ex, *siglist;
- if ((ex = flags_as_exception(ctx->traps&status)) == NULL) {
- return 1;
- }
- if ((siglist = flags_as_list(ctx->traps&status)) == NULL) {
- return 1;
+ ex = flags_as_exception(ctx->traps&status);
+ if (ex == NULL) {
+ return 1; /* GCOV_NOT_REACHED */
+ }
+ siglist = flags_as_list(ctx->traps&status);
+ if (siglist == NULL) {
+ return 1; /* GCOV_UNLIKELY */
}
PyErr_SetObject(ex, siglist);
@@ -339,7 +394,7 @@
signaldict_init(PyObject *self, PyObject *args, PyObject *kwds)
{
if (PyDict_Type.tp_init(self, args, kwds) < 0) {
- return -1;
+ return -1; /* GCOV_UNLIKELY */
}
SdFlagAddr(self) = NULL;
@@ -372,7 +427,7 @@
for (cm = signal_map; cm->name != NULL; cm++) {
if (PyDict_SetItem(self, cm->dec_cond, Py_False) < 0) {
- return -1;
+ return -1; /* GCOV_UNLIKELY */
}
}
return 0;
@@ -389,7 +444,7 @@
}
if ((x = PyObject_IsTrue(value)) < 0) {
- return -1;
+ return -1; /* GCOV_UNLIKELY */
}
if (x == 1) {
SdFlags(self) |= flag;
@@ -404,35 +459,10 @@
}
static PyObject *
-signaldict_call_unary(PyObject *self, const char *name)
+signaldict_call_unary(PyObject *self, char *name)
{
- PyObject *result, *s;
-
- if ((s = Py_BuildValue("s", name)) == NULL) {
- return NULL;
- }
-
signaldict_update(self);
- result = PyObject_CallMethodObjArgs(self, s, NULL);
-
- Py_DECREF(s);
- return result;
-}
-
-static PyObject *
-signaldict_call_binary(PyObject *self, const char *name, PyObject *arg)
-{
- PyObject *result, *s;
-
- if ((s = Py_BuildValue("s", name)) == NULL) {
- return NULL;
- }
-
- signaldict_update(self);
- result = PyObject_CallMethodObjArgs(self, s, arg, NULL);
-
- Py_DECREF(s);
- return result;
+ return PyObject_CallMethod((PyObject *)&PyDict_Type, name, "O", self);
}
static PyObject *
@@ -464,13 +494,26 @@
static PyObject *
signaldict_get(PyObject *self, PyObject *args)
{
- return signaldict_call_binary(self, "get", args);
+ PyObject *key = NULL, *failobj = NULL;
+ if (!PyArg_ParseTuple(args, "O|O", &key, &failobj)) {
+ return NULL; /* GCOV_NOT_REACHED (why?) */
+ }
+ signaldict_update(self);
+ if (failobj) {
+ return PyObject_CallMethod((PyObject *)&PyDict_Type, "get",
+ "OOO", self, key, failobj);
+ }
+ return PyObject_CallMethod((PyObject *)&PyDict_Type, "get",
+ "OO", self, key);
}
static PyObject *
signaldict_has_key(PyObject *self, PyObject *key)
{
- return signaldict_call_binary(self, "has_key", key);
+ int ret;
+ signaldict_update(self);
+ ret = PyDict_Contains(self, key);
+ return ret < 0 ? NULL : PyBool_FromLong(ret);
}
static PyObject *
@@ -483,28 +526,11 @@
static PyObject *
signaldict_iter(PyObject *self)
{
+ signaldict_update(self);
return PyDict_Type.tp_iter(self);
}
static PyObject *
-signaldict_iterkeys(PyObject *self)
-{
- return signaldict_call_unary(self, "iterkeys");
-}
-
-static PyObject *
-signaldict_itervalues(PyObject *self)
-{
- return signaldict_call_unary(self, "itervalues");
-}
-
-static PyObject *
-signaldict_iteritems(PyObject *self)
-{
- return signaldict_call_unary(self, "iteritems");
-}
-
-static PyObject *
signaldict_keys(PyObject *self)
{
signaldict_update(self);
@@ -519,10 +545,10 @@
}
static int
-signaldict_print(PyObject *self, FILE *fp, int flags)
-{
- signaldict_update(self);
- return PyDict_Type.tp_print(self, fp, flags);
+signaldict_print(PyObject *self, FILE *fp, int flags) /* GCOV_UNLIKELY */
+{ /* GCOV_UNLIKELY */
+ signaldict_update(self); /* GCOV_UNLIKELY */
+ return PyDict_Type.tp_print(self, fp, flags); /* GCOV_UNLIKELY */
}
static PyObject *
@@ -542,9 +568,7 @@
signaldict_ass_sub(PyObject *self, PyObject *v, PyObject *w)
{
if (w == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "signal keys cannot be deleted");
- return -1;
+ return value_error_int("signal keys cannot be deleted.");
}
else {
return signaldict_setitem(self, v, w);
@@ -595,9 +619,6 @@
{"items", (PyCFunction)signaldict_items, METH_NOARGS, NULL},
{"values", (PyCFunction)signaldict_values, METH_NOARGS, NULL},
{"copy", (PyCFunction)signaldict_copy, METH_NOARGS, NULL},
- {"iterkeys", (PyCFunction)signaldict_iterkeys, METH_NOARGS, NULL},
- {"itervalues", (PyCFunction)signaldict_itervalues, METH_NOARGS, NULL},
- {"iteritems", (PyCFunction)signaldict_iteritems, METH_NOARGS, NULL},
{NULL, NULL}
};
@@ -748,15 +769,15 @@
mpd_context_t *ctx;
mpd_ssize_t x;
- if ((x = PyLong_AsMpdSsize(value)) == MPD_SSIZE_MAX) {
+ x = PyLong_AsMpdSsize(value);
+ if (PyErr_Occurred()) {
return -1;
}
ctx = CtxAddr(self);
if (!mpd_qsetprec(ctx, x)) {
- if (dec_addstatus(ctx, MPD_Invalid_context)) {
- return -1;
- }
+ return value_error_int(
+ "valid range for prec is [0, MAX_PREC].");
}
return 0;
@@ -768,15 +789,15 @@
mpd_context_t *ctx;
mpd_ssize_t x;
- if ((x = PyLong_AsMpdSsize(value)) == MPD_SSIZE_MAX) {
+ x = PyLong_AsMpdSsize(value);
+ if (PyErr_Occurred()) {
return -1;
}
ctx = CtxAddr(self);
if (!mpd_qsetemin(ctx, x)) {
- if (dec_addstatus(ctx, MPD_Invalid_context)) {
- return -1;
- }
+ return value_error_int(
+ "valid range for Emin is [MIN_EMIN, 0].");
}
return 0;
@@ -788,15 +809,15 @@
mpd_context_t *ctx;
mpd_ssize_t x;
- if ((x = PyLong_AsMpdSsize(value)) == MPD_SSIZE_MAX) {
+ x = PyLong_AsMpdSsize(value);
+ if (PyErr_Occurred()) {
return -1;
}
ctx = CtxAddr(self);
if (!mpd_qsetemax(ctx, x)) {
- if (dec_addstatus(ctx, MPD_Invalid_context)) {
- return -1;
- }
+ return value_error_int(
+ "valid range for Emax is [0, MAX_EMAX].");
}
return 0;
@@ -807,7 +828,8 @@
{
mpd_context_t *ctx = CtxAddr(self);
- if ((ctx->prec = PyLong_AsMpdSsize(value)) == MPD_SSIZE_MAX) {
+ ctx->prec = PyLong_AsMpdSsize(value);
+ if (PyErr_Occurred()) {
return NULL;
}
@@ -819,7 +841,8 @@
{
mpd_context_t *ctx = CtxAddr(self);
- if ((ctx->emin = PyLong_AsMpdSsize(value)) == MPD_SSIZE_MAX) {
+ ctx->emin = PyLong_AsMpdSsize(value);
+ if (PyErr_Occurred()) {
return NULL;
}
@@ -831,7 +854,8 @@
{
mpd_context_t *ctx = CtxAddr(self);
- if ((ctx->emax = PyLong_AsMpdSsize(value)) == MPD_SSIZE_MAX) {
+ ctx->emax = PyLong_AsMpdSsize(value);
+ if (PyErr_Occurred()) {
return NULL;
}
@@ -844,20 +868,15 @@
mpd_context_t *ctx;
mpd_ssize_t x;
- if ((x = PyLong_AsMpdSsize(value)) == MPD_SSIZE_MAX) {
- return -1;
- }
- if (x < 0 || x >= MPD_ROUND_GUARD) {
- PyErr_SetString(PyExc_ValueError,
- "invalid value for context.round");
+ x = PyLong_AsMpdSsize(value);
+ if (PyErr_Occurred()) {
return -1;
}
+ BOUNDS_CHECK(x, INT_MIN, INT_MAX);
ctx = CtxAddr(self);
if (!mpd_qsetround(ctx, (int)x)) {
- if (dec_addstatus(ctx, MPD_Invalid_context)) {
- return -1;
- }
+ return value_error_int(invalid_rounding_err);
}
return 0;
@@ -868,15 +887,16 @@
{
mpd_ssize_t x;
- if ((x = PyLong_AsMpdSsize(value)) == MPD_SSIZE_MAX) {
+ x = PyLong_AsMpdSsize(value);
+ if (PyErr_Occurred()) {
return -1;
}
+ BOUNDS_CHECK(x, INT_MIN, INT_MAX);
+
if (x != 0 && x != 1) {
- PyErr_SetString(PyExc_ValueError,
- "invalid value for context.capitals");
- return -1;
+ return value_error_int(
+ "valid values for capitals are 0 or 1.");
}
-
CtxCaps(self) = (int)x;
return 0;
@@ -894,10 +914,8 @@
}
ctx = CtxAddr(self);
- if (!mpd_qsettraps(ctx, (uint32_t)flags)) {
- if (dec_addstatus(ctx, MPD_Invalid_context)) {
- return -1;
- }
+ if (!mpd_qsettraps(ctx, flags)) {
+ INTERNAL_ERROR_INT("context_settraps"); /* GCOV_NOT_REACHED */
}
return 0;
@@ -909,15 +927,14 @@
mpd_context_t *ctx;
uint32_t flags;
- if ((flags = list_as_flags(value)) == UINT32_MAX) {
+ flags = list_as_flags(value);
+ if (flags == UINT32_MAX) {
return -1;
}
ctx = CtxAddr(self);
if (!mpd_qsettraps(ctx, flags)) {
- if (dec_addstatus(ctx, MPD_Invalid_context)) {
- return -1;
- }
+ INTERNAL_ERROR_INT("context_settraps_list"); /* GCOV_NOT_REACHED */
}
return 0;
@@ -929,15 +946,14 @@
mpd_context_t *ctx;
uint32_t flags;
- if ((flags = dict_as_flags(value)) == UINT32_MAX) {
+ flags = dict_as_flags(value);
+ if (flags == UINT32_MAX) {
return -1;
}
ctx = CtxAddr(self);
if (!mpd_qsettraps(ctx, flags)) {
- if (dec_addstatus(ctx, MPD_Invalid_context)) {
- return -1;
- }
+ INTERNAL_ERROR_INT("context_settraps_dict"); /* GCOV_NOT_REACHED */
}
return 0;
@@ -955,10 +971,8 @@
}
ctx = CtxAddr(self);
- if (!mpd_qsetstatus(ctx, (uint32_t)flags)) {
- if (dec_addstatus(ctx, MPD_Invalid_context)) {
- return -1;
- }
+ if (!mpd_qsetstatus(ctx, flags)) {
+ INTERNAL_ERROR_INT("context_setstatus"); /* GCOV_NOT_REACHED */
}
return 0;
@@ -970,15 +984,14 @@
mpd_context_t *ctx;
uint32_t flags;
- if ((flags = list_as_flags(value)) == UINT32_MAX) {
+ flags = list_as_flags(value);
+ if (flags == UINT32_MAX) {
return -1;
}
ctx = CtxAddr(self);
if (!mpd_qsetstatus(ctx, flags)) {
- if (dec_addstatus(ctx, MPD_Invalid_context)) {
- return -1;
- }
+ INTERNAL_ERROR_INT("context_setstatus_list"); /* GCOV_NOT_REACHED */
}
return 0;
@@ -990,15 +1003,14 @@
mpd_context_t *ctx;
uint32_t flags;
- if ((flags = dict_as_flags(value)) == UINT32_MAX) {
+ flags = dict_as_flags(value);
+ if (flags == UINT32_MAX) {
return -1;
}
ctx = CtxAddr(self);
if (!mpd_qsetstatus(ctx, flags)) {
- if (dec_addstatus(ctx, MPD_Invalid_context)) {
- return -1;
- }
+ INTERNAL_ERROR_INT("context_setstatus_dict"); /* GCOV_NOT_REACHED */
}
return 0;
@@ -1010,15 +1022,15 @@
mpd_context_t *ctx;
mpd_ssize_t x;
- if ((x = PyLong_AsMpdSsize(value)) == MPD_SSIZE_MAX) {
+ x = PyLong_AsMpdSsize(value);
+ if (PyErr_Occurred()) {
return -1;
}
+ BOUNDS_CHECK(x, INT_MIN, INT_MAX);
ctx = CtxAddr(self);
if (!mpd_qsetclamp(ctx, (int)x)) {
- if (dec_addstatus(ctx, MPD_Invalid_context)) {
- return -1;
- }
+ return value_error_int("valid values for clamp are 0 or 1.");
}
return 0;
@@ -1030,15 +1042,15 @@
mpd_context_t *ctx;
mpd_ssize_t x;
- if ((x = PyLong_AsMpdSsize(value)) == MPD_SSIZE_MAX) {
+ x = PyLong_AsMpdSsize(value);
+ if (PyErr_Occurred()) {
return -1;
}
+ BOUNDS_CHECK(x, INT_MIN, INT_MAX);
ctx = CtxAddr(self);
if (!mpd_qsetcr(ctx, (int)x)) {
- if (dec_addstatus(ctx, MPD_Invalid_context)) {
- return -1;
- }
+ return value_error_int("valid values for _allcr are 0 or 1.");
}
return 0;
@@ -1050,10 +1062,10 @@
PyObject *retval;
if (!PyUnicode_Check(name)) {
- PyErr_Format(PyExc_TypeError,
+ PyErr_Format(PyExc_TypeError, /* GCOV_NOT_REACHED (why?) */
"attribute name must be string, not '%.200s'",
- name->ob_type->tp_name);
- return NULL;
+ name->ob_type->tp_name); /* GCOV_NOT_REACHED */
+ return NULL; /* GCOV_NOT_REACHED */
}
if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) {
@@ -1075,25 +1087,21 @@
context_setattr(PyObject *self, PyObject *name, PyObject *value)
{
if (!PyUnicode_Check(name)) {
- PyErr_Format(PyExc_TypeError,
+ PyErr_Format(PyExc_TypeError, /* GCOV_NOT_REACHED (why?) */
"attribute name must be string, not '%.200s'",
- name->ob_type->tp_name);
- return -1;
+ name->ob_type->tp_name); /* GCOV_NOT_REACHED */
+ return -1; /* GCOV_NOT_REACHED */
}
if (PyUnicode_CompareWithASCIIString(name, "traps") == 0) {
if (value == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "traps cannot be deleted");
- return -1;
+ return value_error_int("traps cannot be deleted.");
}
return context_settraps_dict(self, value);
}
else if (PyUnicode_CompareWithASCIIString(name, "flags") == 0) {
if (value == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "flags cannot be deleted");
- return -1;
+ return value_error_int("flags cannot be deleted.");
}
return context_setstatus_dict(self, value);
}
@@ -1108,7 +1116,7 @@
PyDecContextObject *decctx = (PyDecContextObject *)self;
if (signaldict_clear_all(decctx->traps) < 0) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
Py_RETURN_NONE;
}
@@ -1119,7 +1127,7 @@
PyDecContextObject *decctx = (PyDecContextObject *)self;
if (signaldict_clear_all(decctx->flags) < 0) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
Py_RETURN_NONE;
}
@@ -1133,18 +1141,18 @@
self = PyObject_New(PyDecContextObject, &PyDecContext_Type);
if (self == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
self->traps = PyObject_CallObject((PyObject *)&PyDecSignalDict_Type, NULL);
if (self->traps == NULL) {
- Py_DECREF(self);
- return NULL;
+ Py_DECREF(self); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
self->flags = PyObject_CallObject((PyObject *)&PyDecSignalDict_Type, NULL);
if (self->flags == NULL) {
- Py_DECREF(self->traps);
- Py_DECREF(self);
- return NULL;
+ Py_DECREF(self->traps); /* GCOV_UNLIKELY */
+ Py_DECREF(self); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
ctx = CtxAddr(self);
@@ -1187,6 +1195,7 @@
PyObject *status = NULL;
mpd_context_t *ctx, t=dflt_ctx;
int capitals = 1;
+ int ret;
assert(PyTuple_Check(args));
ctx = CtxAddr(self);
@@ -1212,43 +1221,47 @@
!mpd_qsetstatus(ctx, t.status) ||
!mpd_qsetclamp(ctx, t.clamp) ||
!mpd_qsetcr(ctx, t.allcr)) {
- PyErr_SetString(PyExc_ValueError, "invalid context");
- return -1;
+ return value_error_int("invalid context.");
}
if (capitals != 0 && capitals != 1) {
- PyErr_SetString(PyExc_ValueError, "invalid context");
- return -1;
+ return value_error_int("invalid context.");
}
CtxCaps(self) = capitals;
if (traps != NULL) {
if (PyLong_Check(traps)) {
- return context_settraps(self, traps, NULL);
+ ret = context_settraps(self, traps, NULL);
}
else if (PyList_Check(traps)) {
- return context_settraps_list(self, traps);
+ ret = context_settraps_list(self, traps);
}
else {
- return context_settraps_dict(self, traps);
+ ret = context_settraps_dict(self, traps);
+ }
+ if (ret < 0) {
+ return ret;
}
}
if (status != NULL) {
if (PyLong_Check(status)) {
- return context_setstatus(self, status, NULL);
+ ret = context_setstatus(self, status, NULL);
}
else if (PyList_Check(status)) {
- return context_setstatus_list(self, status);
+ ret = context_setstatus_list(self, status);
}
else {
- return context_setstatus_dict(self, status);
+ ret = context_setstatus_dict(self, status);
+ }
+ if (ret < 0) {
+ return ret;
}
}
return 0;
}
-#define FD_CTX_LEN 400
+#define FD_CTX_LEN 432
static PyObject *
context_repr(PyDecContextObject *self)
{
@@ -1288,9 +1301,8 @@
return PyUnicode_FromString(s);
-error:
- PyErr_SetString(PyExc_RuntimeError, "internal error in context_repr");
- return NULL;
+error: /* GCOV_NOT_REACHED */
+ INTERNAL_ERROR_PTR("context_repr"); /* GCOV_NOT_REACHED */
}
static void
@@ -1339,7 +1351,7 @@
ctxobj = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
if (ctxobj == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
*CtxAddr(ctxobj) = ctx;
@@ -1347,8 +1359,8 @@
error:
PyErr_Format(PyExc_ValueError,
- "argument must be a multiple of 32, with a maximum of %d",
- MPD_IEEE_CONTEXT_MAX_BITS
+ "argument must be a multiple of 32, with a maximum of %d.",
+ MPD_IEEE_CONTEXT_MAX_BITS
);
return NULL;
}
@@ -1361,7 +1373,7 @@
newob = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
if (newob == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
ctx = CtxAddr(newob);
@@ -1423,15 +1435,15 @@
#define CONTEXT_CHECK(obj) \
if (!PyDecContext_Check(obj)) { \
- PyErr_SetString( PyExc_TypeError, \
- "argument must be a context" ); \
+ PyErr_SetString(PyExc_TypeError, \
+ "argument must be a context."); \
return NULL; \
}
#define CONTEXT_CHECK_VA(obj) \
if (!PyDecContext_Check(obj)) { \
- PyErr_SetString( PyExc_TypeError, \
- "optional argument must be a context" ); \
+ PyErr_SetString(PyExc_TypeError, \
+ "optional argument must be a context."); \
return NULL; \
}
@@ -1520,8 +1532,9 @@
dict = PyThreadState_GetDict();
if (dict == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "cannot get thread state");
- return NULL;
+ PyErr_SetString(PyExc_RuntimeError, /* GCOV_UNLIKELY */
+ "cannot get thread state."); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
tl_context = PyDict_GetItem(dict, tls_context_key);
@@ -1535,11 +1548,11 @@
/* Otherwise, set up a new thread local context. */
tl_context = (PyObject *)context_copy(default_context_template);
if (tl_context == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
if (PyDict_SetItem(dict, tls_context_key, tl_context) < 0) {
- Py_DECREF(tl_context);
- return NULL;
+ Py_DECREF(tl_context); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
Py_DECREF(tl_context);
@@ -1569,7 +1582,7 @@
PyObject *obj;
if ((obj = current_context()) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
Py_INCREF(obj);
@@ -1586,8 +1599,9 @@
dict = PyThreadState_GetDict();
if (dict == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "cannot get thread state");
- return NULL;
+ PyErr_SetString(PyExc_RuntimeError, /* GCOV_UNLIKELY */
+ "cannot get thread state."); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
/* If the new context is one of the templates, make a copy.
@@ -1596,7 +1610,7 @@
v == basic_context_template ||
v == extended_context_template) {
if ((v = context_copy(v)) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
}
else {
@@ -1604,7 +1618,7 @@
}
if (PyDict_SetItem(dict, tls_context_key, v) < 0) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
Py_DECREF(v);
@@ -1625,20 +1639,20 @@
CURRENT_CONTEXT(global);
local = global;
if (!PyArg_ParseTuple(args, "|O", &local)) {
- return NULL;
+ return NULL; /* GCOV_NOT_REACHED */
}
CONTEXT_CHECK_VA(local);
self = PyObject_New(PyDecContextManagerObject,
&PyDecContextManager_Type);
if (self == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
self->local = context_copy(local);
if (self->local == NULL) {
- Py_DECREF(self);
- return NULL;
+ Py_DECREF(self); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
self->global = global;
Py_INCREF(self->global);
@@ -1661,7 +1675,7 @@
ret = PyDec_SetCurrentContext(NULL, self->local);
if (ret == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
Py_DECREF(ret);
@@ -1677,7 +1691,7 @@
ret = PyDec_SetCurrentContext(NULL, self->global);
if (ret == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
Py_DECREF(ret);
@@ -1734,12 +1748,12 @@
PyDecObject * self;
if ((self = PyObject_New(PyDecObject, &PyDec_Type)) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
if ((self->dec = mpd_qnew()) == NULL) {
- PyErr_NoMemory();
- PyObject_Del(self);
- return NULL;
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ PyObject_Del(self); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
return self;
@@ -1766,19 +1780,19 @@
char *cp;
if((newob = dec_alloc()) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
if ((cp = PyMem_Malloc(PyUnicode_GET_SIZE(v)+1)) == NULL) {
- Py_DECREF(newob);
- PyErr_NoMemory();
- return NULL;
+ Py_DECREF(newob); /* GCOV_UNLIKELY */
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
PyUnicode_GET_SIZE(v),
cp, NULL)) {
- Py_DECREF(newob);
- PyMem_Free(cp);
- return NULL;
+ Py_DECREF(newob); /* GCOV_UNLIKELY */
+ PyMem_Free(cp); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
mpd_qset_string(newob->dec, cp, ctx, &status);
@@ -1803,7 +1817,7 @@
uint8_t sign;
if((newob = dec_alloc()) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
ob_size = Py_SIZE(l);
@@ -1831,7 +1845,7 @@
mpd_qimport_u16(newob->dec, l->ob_digit, len, sign, PyLong_BASE,
ctx, &status);
#else
- #error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
+ #error "PYLONG_BITS_IN_DIGIT should be 15 or 30."
#endif
if (dec_addstatus(ctx, status)) {
Py_DECREF(newob);
@@ -1867,7 +1881,7 @@
if (s != x || t != y) {
n = t-s;
if ((y = PyMem_Malloc(n+1)) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
strncpy(y, s, n);
y[n] = '\0';
@@ -1887,27 +1901,27 @@
char *cp, *stripped;
if((newob = dec_alloc()) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
if ((cp = PyMem_Malloc(PyUnicode_GET_SIZE(v)+1)) == NULL) {
- Py_DECREF(newob);
- PyErr_NoMemory();
- return NULL;
+ Py_DECREF(newob); /* GCOV_UNLIKELY */
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
PyUnicode_GET_SIZE(v),
cp, NULL)) {
- Py_DECREF(newob);
- PyMem_Free(cp);
- return NULL;
+ Py_DECREF(newob); /* GCOV_UNLIKELY */
+ PyMem_Free(cp); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
mpd_maxcontext(&maxctx);
if ((stripped = strip_ws(cp)) == NULL) {
- Py_DECREF(newob);
- PyMem_Free(cp);
- PyErr_NoMemory();
- return NULL;
+ Py_DECREF(newob); /* GCOV_UNLIKELY */
+ PyMem_Free(cp); /* GCOV_UNLIKELY */
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
mpd_qset_string(newob->dec, stripped, &maxctx, &status);
@@ -1921,8 +1935,8 @@
}
status &= MPD_Errors;
if (dec_addstatus(ctx, status)) {
- Py_DECREF(newob);
- return NULL;
+ Py_DECREF(newob); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
return (PyObject *)newob;
@@ -1941,7 +1955,7 @@
uint8_t sign;
if((newob = dec_alloc()) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
ob_size = Py_SIZE(l);
@@ -1971,17 +1985,17 @@
mpd_qimport_u16(newob->dec, l->ob_digit, len, sign, PyLong_BASE,
&maxctx, &status);
#else
- #error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
+ #error "PYLONG_BITS_IN_DIGIT should be 15 or 30."
#endif
if (status&(MPD_Inexact|MPD_Rounded)) {
/* we want exact results */
- mpd_seterror(newob->dec, MPD_Invalid_operation, &status);
+ mpd_seterror(newob->dec, MPD_Invalid_operation, &status); /* GCOV_UNLIKELY */
}
status &= MPD_Errors;
if (dec_addstatus(ctx, status)) {
- Py_DECREF(newob);
- return NULL;
+ Py_DECREF(newob); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
return (PyObject *)newob;
@@ -2000,22 +2014,18 @@
int n;
if (PyTuple_Size(v) != 3) {
- PyErr_SetString(PyExc_ValueError,
- "argument must be a tuple of length 3");
- return NULL;
+ return value_error_ptr(
+ "argument must be a tuple of length 3.");
}
tmp = PyTuple_GET_ITEM(v, 0);
if (!PyLong_Check(tmp)) {
- PyErr_SetString(PyExc_TypeError,
- "sign must be 0 or 1");
+ PyErr_SetString(PyExc_TypeError, "sign must be 0 or 1.");
return NULL;
}
sign = PyLong_AsLong(tmp);
if (sign != 0 && sign != 1) {
- PyErr_SetString(PyExc_ValueError,
- "sign must be 0 or 1");
- return NULL;
+ return value_error_ptr("sign must be 0 or 1.");
}
sign_special[0] = sign ? '-' : '+';
sign_special[1] = '\0';
@@ -2032,10 +2042,9 @@
strcat(sign_special, "sNaN");
}
else {
- PyErr_SetString(PyExc_ValueError,
- "string argument in the third position "
- "must be 'F', 'n' or 'N'");
- return NULL;
+ return value_error_ptr(
+ "string argument in the third position "
+ "must be 'F', 'n' or 'N'.");
}
}
else {
@@ -2048,7 +2057,7 @@
dtuple = PyTuple_GET_ITEM(v, 1);
if (!PyTuple_Check(dtuple)) {
PyErr_SetString(PyExc_TypeError,
- "coefficient must be a tuple of digits");
+ "coefficient must be a tuple of digits.");
return NULL;
}
@@ -2057,8 +2066,8 @@
mem = 1 + tsize + 3 + MPD_EXPDIGITS + 2;
cp = decstring = PyMem_Malloc(mem);
if (decstring == NULL) {
- PyErr_NoMemory();
- return NULL;
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
n = snprintf(cp, mem, "%s", sign_special);
@@ -2074,15 +2083,14 @@
if (!PyLong_Check(tmp)) {
PyMem_Free(decstring);
PyErr_SetString(PyExc_TypeError,
- "coefficient must be a tuple of digits");
+ "coefficient must be a tuple of digits.");
return NULL;
}
l = PyLong_AsLong(tmp);
if (l < 0 || l > 9) {
PyMem_Free(decstring);
- PyErr_SetString(PyExc_ValueError,
- "coefficient must be a tuple of digits");
- return NULL;
+ return value_error_ptr(
+ "coefficient must be a tuple of digits.");
}
*cp++ = (char)l + '0';
}
@@ -2131,6 +2139,145 @@
return result;
}
+static PyObject *
+_PyDec_FromFloat_Max(PyObject *self, PyObject *v)
+{
+ PyObject *result, *tmp;
+ PyObject *n, *d, *n_d;
+ mpd_ssize_t k;
+ double x;
+ int sign;
+ mpd_t *d1, *d2;
+ uint32_t status = 0;
+ mpd_context_t *ctx, maxctx;
+
+
+ CURRENT_CONTEXT_ADDR(ctx);
+ if (PyLong_Check(v)) {
+ return _PyDec_FromLong_Max(v, ctx);
+ }
+
+ x = PyFloat_AsDouble(v);
+ if (x == -1.0 && PyErr_Occurred()) {
+ return NULL;
+ }
+ sign = (copysign(1.0, x) == 1.0) ? 0 : 1;
+
+ if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) {
+ result = PyObject_CallObject(self, NULL);
+ if (result == NULL) {
+ return NULL; /* GCOV_UNLIKELY */
+ }
+ if (Py_IS_NAN(x)) {
+ /* decimal.py calls repr(float(+-nan)),
+ * which always gives a positive result. */
+ mpd_setspecial(DecAddr(result), MPD_POS, MPD_NAN);
+ }
+ else {
+ mpd_setspecial(DecAddr(result), sign, MPD_INF);
+ }
+ return result;
+ }
+
+ if ((tmp = PyObject_CallMethod(v, "__abs__", NULL)) == NULL) {
+ return NULL; /* GCOV_UNLIKELY */
+ }
+ n_d = PyObject_CallMethod(tmp, "as_integer_ratio", NULL);
+ Py_DECREF(tmp);
+ if (n_d == NULL) {
+ return NULL; /* GCOV_UNLIKELY */
+ }
+ if ((n = PyTuple_GetItem(n_d, 0)) == NULL) {
+ Py_DECREF(n_d); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
+ }
+ if ((d = PyTuple_GetItem(n_d, 1)) == NULL) {
+ Py_DECREF(n_d); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
+ }
+
+
+ if ((tmp = PyObject_CallMethod(d, "bit_length", NULL)) == NULL) {
+ Py_DECREF(n_d); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
+ }
+ k = PyLong_AsMpdSsize(tmp);
+ Py_DECREF(tmp);
+ if (k == MPD_SSIZE_MAX) {
+ Py_DECREF(n_d); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
+ }
+ k--;
+
+ if ((d1 = mpd_qnew()) == NULL) {
+ Py_DECREF(n_d); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
+ }
+ if ((d2 = mpd_qnew()) == NULL) {
+ mpd_del(d1); /* GCOV_UNLIKELY */
+ Py_DECREF(n_d); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
+ }
+
+ mpd_maxcontext(&maxctx);
+ mpd_qset_uint(d1, 5, &maxctx, &status);
+ mpd_qset_ssize(d2, k, &maxctx, &status);
+ mpd_qpow(d1, d1, d2, &maxctx, &status);
+ if (dec_addstatus(ctx, status)) {
+ mpd_del(d1); /* GCOV_UNLIKELY */
+ mpd_del(d2); /* GCOV_UNLIKELY */
+ Py_DECREF(n_d); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
+ }
+
+ tmp = Py_BuildValue("(O)", n);
+ result = PyObject_CallObject(self, tmp);
+ Py_DECREF(tmp);
+ Py_DECREF(n_d);
+ if (result == NULL) {
+ mpd_del(d1); /* GCOV_UNLIKELY */
+ mpd_del(d2); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
+ }
+
+ /* result = n * 5**k */
+ mpd_qmul(DecAddr(result), DecAddr(result), d1, &maxctx, &status);
+ mpd_del(d1);
+ mpd_del(d2);
+ if (dec_addstatus(ctx, status)) {
+ Py_DECREF(result); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
+ }
+ /* result = +- n * 5**k * 10**-k */
+ mpd_set_sign(DecAddr(result), sign);
+ DecAddr(result)->exp = -k;
+
+ return result;
+}
+
+static PyObject *
+PyDecContext_FromFloat(PyObject *self, PyObject *v)
+{
+ PyObject *result;
+ mpd_context_t *ctx;
+ uint32_t status = 0;
+
+ ctx = CtxAddr(self);
+
+ result = _PyDec_FromFloat_Max((PyObject *)&PyDec_Type, v);
+ if (result == NULL) {
+ return NULL; /* GCOV_UNLIKELY */
+ }
+
+ mpd_qfinalize(DecAddr(result), ctx, &status);
+ if (dec_addstatus(ctx, status)) {
+ Py_DECREF(result);
+ return NULL;
+ }
+
+ return result;
+}
+
/* Caller guarantees types. */
static PyObject *
dec_apply(PyObject *v, mpd_context_t *ctx)
@@ -2139,13 +2286,13 @@
uint32_t status = 0;
if((newob = dec_alloc()) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
mpd_qcopy(newob->dec, ((PyDecObject *)v)->dec, &status);
if (dec_addstatus(ctx, status)) {
- Py_DECREF(newob);
- return NULL;
+ Py_DECREF(newob); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
mpd_qfinalize(newob->dec, ctx, &status);
@@ -2180,7 +2327,8 @@
mpd_context_t *ctx;
if (!PyDec_Check(decobj)) {
- PyErr_SetString(PyExc_TypeError, "argument must be a Decimal");
+ PyErr_SetString(PyExc_TypeError,
+ "argument must be a Decimal.");
return NULL;
}
@@ -2201,19 +2349,19 @@
if (PyDec_Check(v)) {
*a = (PyDecObject *) v;
Py_INCREF(v);
+ return 1;
}
- else if (PyLong_Check(v)) {
- if ((*a = (PyDecObject *) _PyDec_FromLong_Max(v, ctx)) == NULL) {
- return 0;
+ if (PyLong_Check(v)) {
+ *a = (PyDecObject *) _PyDec_FromLong_Max(v, ctx);
+ if (*a == NULL) {
+ return 0; /* GCOV_UNLIKELY */
}
- }
- else {
- Py_INCREF(Py_NotImplemented);
- *a = (PyDecObject *) Py_NotImplemented;
- return 0;
+ return 1;
}
- return 1;
+ Py_INCREF(Py_NotImplemented);
+ *a = (PyDecObject *) Py_NotImplemented;
+ return 0;
}
#define CONVERT_OP(v, a, ctx) \
@@ -2245,6 +2393,54 @@
}
+/* Convert for comparison */
+static int
+convert_op_cmp(PyObject *v, PyDecObject **a, int op, mpd_context_t *ctx)
+{
+ if (PyDec_Check(v)) {
+ *a = (PyDecObject *) v;
+ Py_INCREF(v);
+ return 1;
+ }
+ if (PyLong_Check(v)) {
+ *a = (PyDecObject *) _PyDec_FromLong_Max(v, ctx);
+ if (*a == NULL) {
+ return 0; /* GCOV_UNLIKELY */
+ }
+ return 1;
+ }
+ if (PyFloat_Check(v)) {
+ ctx->status |= MPD_Float_operation;
+ if (op != Py_EQ && op != Py_NE &&
+ dec_addstatus(ctx, MPD_Float_operation)) {
+ *a = NULL;
+ return 0;
+ }
+#if PY_VERSION_HEX >= 0x03020000
+ *a = (PyDecObject *) _PyDec_FromFloat_Max(
+ (PyObject *)&PyDec_Type, v);
+ if (*a == NULL) {
+ return 0; /* GCOV_UNLIKELY */
+ }
+ return 1;
+#endif
+ }
+
+ Py_INCREF(Py_NotImplemented);
+ *a = (PyDecObject *) Py_NotImplemented;
+ return 0;
+}
+
+#define CONVERT_BINOP_CMP(v, w, a, b, op, ctx) \
+ if (!convert_op_cmp(v, a, op, ctx)) { \
+ return (PyObject *) *(a); \
+ } \
+ if (!convert_op_cmp(w, b, op, ctx)) { \
+ Py_DECREF(*(a)); \
+ return (PyObject *) *(b); \
+ }
+
+
/* Same as convert_op(), but set an error instead of returning
* NotImplemented. */
static int
@@ -2254,19 +2450,20 @@
if (PyDec_Check(v)) {
*a = (PyDecObject *) v;
Py_INCREF(v);
+ return 1;
}
- else if (PyLong_Check(v)) {
- if ((*a = (PyDecObject *) _PyDec_FromLong_Max(v, ctx)) == NULL) {
- return 0;
+ if (PyLong_Check(v)) {
+ *a = (PyDecObject *) _PyDec_FromLong_Max(v, ctx);
+ if (*a == NULL) {
+ return 0; /* GCOV_UNLIKELY */
}
- }
- else {
- PyErr_Format(PyExc_TypeError, "conversion from %s to Decimal is"
- " not supported", v->ob_type->tp_name);
- return 0;
+ return 1;
}
- return 1;
+ PyErr_Format(PyExc_TypeError,
+ "conversion from %s to Decimal is not supported.",
+ v->ob_type->tp_name);
+ return 0;
}
#define CONVERT_OP_SET(v, a, ctx) \
@@ -2297,6 +2494,7 @@
return NULL; \
}
+
static PyObject *dec_subtype_new(PyTypeObject *type, PyObject *args,
PyObject *kwds);
@@ -2311,240 +2509,119 @@
return dec_subtype_new(type, args, kwds);
}
- CURRENT_CONTEXT(ctxobj);
- if (!PyArg_ParseTuple(args, "|OO", &v, &ctxobj)) {
- return NULL;
- }
-
- if (v == NULL) {
- v = PyLong_FromLong(0);
- Py_DECREF(v);
- }
-
- CONTEXT_CHECK_VA(ctxobj);
- ctx = CtxAddr(ctxobj);
-
- if (PyDec_Check(v)) {
- Py_INCREF(v);
- return v;
- }
- else if (PyUnicode_Check(v)) {
- return _PyDec_FromUnicode_Max(v, ctx);
- }
- else if (PyLong_Check(v)) {
- return _PyDec_FromLong_Max(v, ctx);
- }
- else if (PyTuple_Check(v)) {
- return _PyDec_FromTuple_Max(v, ctx);
- }
- else {
- PyErr_Format(PyExc_TypeError, "conversion from %s to Decimal is"
- " not supported", v->ob_type->tp_name);
- return NULL;
- }
-}
-
-static PyObject *
-dec_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyObject *tmp, *newobj;
-
- assert(PyType_IsSubtype(type, &PyDec_Type));
- tmp = dec_new(&PyDec_Type, args, kwds);
- if (tmp == NULL) {
- return NULL;
- }
-
- newobj = type->tp_alloc(type, 0);
- if (newobj == NULL) {
- Py_DECREF(tmp);
- return NULL;
- }
-
- DecAddr(newobj) = mpd_qncopy(DecAddr(tmp));
- if (DecAddr(newobj) == NULL) {
- PyErr_NoMemory();
- Py_DECREF(tmp);
- return NULL;
- }
-
- Py_DECREF(tmp);
- return (PyObject *)newobj;
-}
-
-static PyObject *
-PyDecContext_CreateDecimal(PyObject *self, PyObject *args)
-{
- PyObject *v = NULL;
- mpd_context_t *ctx;
-
- if (!PyArg_ParseTuple(args, "|O", &v)) {
- return NULL;
- }
-
- if (v == NULL) {
- v = PyLong_FromLong(0);
- Py_DECREF(v);
- }
-
- ctx = CtxAddr(self);
-
- if (PyDec_Check(v)) {
- return dec_apply(v, ctx);
- }
- else if (PyUnicode_Check(v)) {
- return _PyDec_FromUnicode(v, ctx);
- }
- else if (PyLong_Check(v)) {
- return _PyDec_FromLong(v, ctx);
- }
- else if (PyTuple_Check(v)) {
- return _PyDec_FromTuple(v, ctx);
- }
- else {
- PyErr_Format(PyExc_TypeError, "conversion from %s to Decimal is"
- " not supported", v->ob_type->tp_name);
- return NULL;
- }
-}
-
-static PyObject *
-_PyDec_FromFloat_Max(PyObject *self, PyObject *v)
-{
- PyObject *result, *tmp;
- PyObject *n, *d, *n_d;
- mpd_ssize_t k;
- double x;
- int sign;
- mpd_t *d1, *d2;
- uint32_t status = 0;
- mpd_context_t *ctx, maxctx;
-
-
- CURRENT_CONTEXT_ADDR(ctx);
- if (PyLong_Check(v)) {
- return _PyDec_FromLong_Max(v, ctx);
- }
-
- x = PyFloat_AsDouble(v);
- if (x == -1.0 && PyErr_Occurred()) {
- return NULL;
- }
- sign = (copysign(1.0, x) == 1.0) ? 0 : 1;
-
- if (Py_IS_NAN(x) || Py_IS_INFINITY(x)) {
- result = PyObject_CallObject(self, NULL);
- if (result == NULL) {
- return NULL;
- }
- if (Py_IS_NAN(x)) {
- /* decimal.py calls repr(float(+-nan)),
- * which always gives a positive result */
- mpd_setspecial(DecAddr(result), MPD_POS, MPD_NAN);
- }
- else {
- mpd_setspecial(DecAddr(result), sign, MPD_INF);
- }
- return result;
- }
-
- if ((tmp = PyObject_CallMethod(v, "__abs__", NULL)) == NULL) {
- return NULL;
- }
- n_d = PyObject_CallMethod(tmp, "as_integer_ratio", NULL);
- Py_DECREF(tmp);
- if (n_d == NULL) {
- return NULL;
- }
- if ((n = PyTuple_GetItem(n_d, 0)) == NULL) {
- Py_DECREF(n_d);
+ CURRENT_CONTEXT(ctxobj);
+ if (!PyArg_ParseTuple(args, "|OO", &v, &ctxobj)) {
return NULL;
}
- if ((d = PyTuple_GetItem(n_d, 1)) == NULL) {
- Py_DECREF(n_d);
- return NULL;
+
+ if (v == NULL) {
+ v = PyLong_FromLong(0);
+ Py_DECREF(v);
}
+ CONTEXT_CHECK_VA(ctxobj);
+ ctx = CtxAddr(ctxobj);
- if ((tmp = PyObject_CallMethod(d, "bit_length", NULL)) == NULL) {
- Py_DECREF(n_d);
- return NULL;
+ if (PyDec_Check(v)) {
+ Py_INCREF(v);
+ return v;
}
- k = PyLong_AsMpdSsize(tmp);
- Py_DECREF(tmp);
- if (k == MPD_SSIZE_MAX) {
- Py_DECREF(n_d);
- return NULL;
+ else if (PyUnicode_Check(v)) {
+ return _PyDec_FromUnicode_Max(v, ctx);
}
- k--;
-
- if ((d1 = mpd_qnew()) == NULL) {
- Py_DECREF(n_d);
- return NULL;
+ else if (PyLong_Check(v)) {
+ return _PyDec_FromLong_Max(v, ctx);
}
- if ((d2 = mpd_qnew()) == NULL) {
- mpd_del(d1);
- Py_DECREF(n_d);
+ else if (PyTuple_Check(v)) {
+ return _PyDec_FromTuple_Max(v, ctx);
+ }
+#if PY_VERSION_HEX >= 0x03020000
+ else if (PyFloat_Check(v)) {
+ if (dec_addstatus(ctx, MPD_Float_operation)) {
+ return NULL;
+ }
+ return _PyDec_FromFloat_Max((PyObject *)&PyDec_Type, v);
+ }
+#endif
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "conversion from %s to Decimal is not supported.",
+ v->ob_type->tp_name);
return NULL;
}
+}
- mpd_maxcontext(&maxctx);
- mpd_qset_uint(d1, 5, &maxctx, &status);
- mpd_qset_ssize(d2, k, &maxctx, &status);
- mpd_qpow(d1, d1, d2, &maxctx, &status);
- if (dec_addstatus(ctx, status)) {
- mpd_del(d1);
- mpd_del(d2);
- Py_DECREF(n_d);
- return NULL;
+static PyObject *
+dec_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ PyObject *tmp, *newobj;
+
+ assert(PyType_IsSubtype(type, &PyDec_Type));
+ tmp = dec_new(&PyDec_Type, args, kwds);
+ if (tmp == NULL) {
+ return NULL; /* GCOV_UNLIKELY */
}
- tmp = Py_BuildValue("(O)", n);
- result = PyObject_CallObject(self, tmp);
- Py_DECREF(tmp);
- Py_DECREF(n_d);
- if (result == NULL) {
- mpd_del(d1);
- mpd_del(d2);
- return NULL;
+ newobj = type->tp_alloc(type, 0);
+ if (newobj == NULL) {
+ Py_DECREF(tmp); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
- /* result = n * 5**k */
- mpd_qmul(DecAddr(result), DecAddr(result), d1, &maxctx, &status);
- mpd_del(d1);
- mpd_del(d2);
- if (dec_addstatus(ctx, status)) {
- Py_DECREF(result);
- return NULL;
+ DecAddr(newobj) = mpd_qncopy(DecAddr(tmp));
+ if (DecAddr(newobj) == NULL) {
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ Py_DECREF(tmp); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
- /* result = +- n * 5**k * 10**-k */
- mpd_set_sign(DecAddr(result), sign);
- DecAddr(result)->exp = -k;
- return result;
+ Py_DECREF(tmp);
+ return (PyObject *)newobj;
}
static PyObject *
-PyDecContext_FromFloat(PyObject *self, PyObject *v)
+PyDecContext_CreateDecimal(PyObject *self, PyObject *args)
{
- PyObject *result;
+ PyObject *v = NULL;
mpd_context_t *ctx;
- uint32_t status = 0;
-
- ctx = CtxAddr(self);
- result = _PyDec_FromFloat_Max((PyObject *)&PyDec_Type, v);
- if (result == NULL) {
+ if (!PyArg_ParseTuple(args, "|O", &v)) {
return NULL;
}
- mpd_qfinalize(DecAddr(result), ctx, &status);
- if (dec_addstatus(ctx, status)) {
- Py_DECREF(result);
- return NULL;
+ if (v == NULL) {
+ v = PyLong_FromLong(0);
+ Py_DECREF(v);
}
- return result;
+ ctx = CtxAddr(self);
+
+ if (PyDec_Check(v)) {
+ return dec_apply(v, ctx);
+ }
+ else if (PyUnicode_Check(v)) {
+ return _PyDec_FromUnicode(v, ctx);
+ }
+ else if (PyLong_Check(v)) {
+ return _PyDec_FromLong(v, ctx);
+ }
+ else if (PyTuple_Check(v)) {
+ return _PyDec_FromTuple(v, ctx);
+ }
+#if PY_VERSION_HEX >= 0x03020000
+ else if (PyFloat_Check(v)) {
+ if (dec_addstatus(ctx, MPD_Float_operation)) {
+ return NULL;
+ }
+ return PyDecContext_FromFloat(self, v);
+ }
+#endif
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "conversion from %s to Decimal is not supported.",
+ v->ob_type->tp_name);
+ return NULL;
+ }
}
@@ -2566,50 +2643,52 @@
if (mpd_isspecial(self->dec)) {
if (mpd_isnan(self->dec)) {
PyErr_SetString(PyExc_ValueError,
- "cannot convert NaN to integer");
+ "cannot convert NaN to integer.");
}
else {
PyErr_SetString(PyExc_OverflowError,
- "cannot convert Infinity to integer");
+ "cannot convert Infinity to integer.");
}
return NULL;
}
if ((intdec = mpd_qnew()) == NULL) {
- PyErr_NoMemory();
- return NULL;
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
workctx = *ctx;
workctx.round = round;
mpd_qround_to_int(intdec, self->dec, &workctx, &status);
if (dec_addstatus(ctx, status)) {
- mpd_del(intdec);
- return NULL;
+ mpd_del(intdec); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
maxsize = mpd_sizeinbase(intdec, PyLong_BASE);
if (maxsize > PY_SSIZE_T_MAX) {
- PyErr_NoMemory();
- mpd_del(intdec);
- return NULL;
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ mpd_del(intdec); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
if ((newob = _PyLong_New(maxsize)) == NULL) {
- mpd_del(intdec);
- return NULL;
+ mpd_del(intdec); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
status = 0;
#if PYLONG_BITS_IN_DIGIT == 30
- n = mpd_qexport_u32(newob->ob_digit, maxsize, PyLong_BASE, intdec, &status);
+ n = mpd_qexport_u32(newob->ob_digit, maxsize, PyLong_BASE,
+ intdec, &status);
#elif PYLONG_BITS_IN_DIGIT == 15
- n = mpd_qexport_u16(newob->ob_digit, maxsize, PyLong_BASE, intdec, &status);
+ n = mpd_qexport_u16(newob->ob_digit, maxsize, PyLong_BASE,
+ intdec, &status);
#else
- #error "PYLONG_BITS_IN_DIGIT should be 15 or 30"
+ #error "PYLONG_BITS_IN_DIGIT should be 15 or 30."
#endif
if (dec_addstatus(ctx, status)) {
- Py_DECREF((PyObject *) newob);
- mpd_del(intdec);
- return NULL;
+ Py_DECREF((PyObject *) newob); /* GCOV_UNLIKELY */
+ mpd_del(intdec); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
i = n;
@@ -2635,12 +2714,14 @@
return _PyInt_FromDec(self, ctx, MPD_ROUND_DOWN);
}
+#if PY_VERSION_HEX < 0x03020000
/* Caller guarantees type */
static PyObject *
PyLong_FromDecCtx(PyDecObject *self, mpd_context_t *ctx)
{
return _PyInt_FromDec(self, ctx, MPD_ROUND_DOWN);
}
+#endif
/* Caller guarantees type. Uses default module context. */
static PyObject *
@@ -2671,11 +2752,11 @@
}
if (!PyDecContext_Check(ctxobj)) {
PyErr_SetString(PyExc_TypeError,
- "optional second arg must be a context");
+ "optional second arg must be a context.");
return NULL;
}
if ((result = dec_alloc()) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
ctx = CtxAddr(ctxobj);
@@ -2686,8 +2767,8 @@
mpd_qround_to_int(result->dec, DecAddr(self), &workctx, &status);
if (dec_addstatus(ctx, status)) {
- Py_DECREF(result);
- return NULL;
+ Py_DECREF(result); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
return (PyObject *)result;
@@ -2712,11 +2793,11 @@
}
if (!PyDecContext_Check(ctxobj)) {
PyErr_SetString(PyExc_TypeError,
- "optional second arg must be a context");
+ "optional second arg must be a context.");
return NULL;
}
if ((result = dec_alloc()) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
ctx = CtxAddr(ctxobj);
@@ -2749,8 +2830,8 @@
if ((selfcpy = mpd_qncopy(DecAddr(self))) == NULL) {
- PyErr_NoMemory();
- goto error;
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ goto error; /* GCOV_UNLIKELY */
}
o_sign = Py_BuildValue("i", mpd_sign(DecAddr(self)));
@@ -2758,10 +2839,10 @@
if (mpd_isinfinite(selfcpy)) {
if ((o_exp = Py_BuildValue("s", "F")) == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
if ((o_coeff = PyTuple_New(0)) == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
}
else {
@@ -2784,13 +2865,13 @@
mpd_clear_flags(selfcpy);
intstring = mpd_to_sci(selfcpy, 1);
if (intstring == NULL) {
- PyErr_NoMemory();
- goto error;
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ goto error; /* GCOV_UNLIKELY */
}
intlen = strlen(intstring);
if ((o_coeff = PyTuple_New(intlen)) == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
for (i = 0; i < intlen; i++) {
@@ -2801,13 +2882,13 @@
}
else {
if ((o_coeff = PyTuple_New(0)) == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
}
}
if ((o_tuple = PyTuple_New(3)) == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
PyTuple_SET_ITEM(o_tuple, 0, o_sign);
PyTuple_SET_ITEM(o_tuple, 1, o_coeff);
@@ -2819,11 +2900,11 @@
if (intstring) mpd_free(intstring);
return o_tuple;
-error:
- if (o_sign) { Py_DECREF(o_sign); }
- if (o_coeff) { Py_DECREF(o_coeff); }
- if (o_exp) { Py_DECREF(o_exp); }
- goto out;
+error: /* GCOV_UNLIKELY */
+ if (o_sign) { Py_DECREF(o_sign); } /* GCOV_UNLIKELY */
+ if (o_coeff) { Py_DECREF(o_coeff); } /* GCOV_UNLIKELY */
+ if (o_exp) { Py_DECREF(o_exp); } /* GCOV_UNLIKELY */
+ goto out; /* GCOV_UNLIKELY */
}
/* Caller guarantees type. Uses default module context. */
@@ -2836,8 +2917,8 @@
CURRENT_CONTEXT(c);
res = mpd_to_sci(self->dec, CtxCaps(c));
if (res == NULL) {
- PyErr_NoMemory();
- return NULL;
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
s = PyUnicode_FromString(res);
@@ -2861,17 +2942,17 @@
CURRENT_CONTEXT(c);
cp = mpd_to_sci(self->dec, CtxCaps(c));
if (cp == NULL) {
- PyErr_NoMemory();
- return NULL;
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
declen = strlen(cp);
err = 0;
cp = mpd_realloc(cp, (mpd_size_t)(declen+dtaglen+3), sizeof *cp, &err);
if (err) {
- mpd_free(cp);
- PyErr_NoMemory();
- return NULL;
+ mpd_free(cp); /* GCOV_UNLIKELY */
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
memmove(cp+dtaglen, cp, declen);
@@ -2893,7 +2974,7 @@
PyObject *f, *s;
if ((s = dec_str(self)) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
f = PyFloat_FromString(s);
@@ -2924,19 +3005,19 @@
if (!PyLong_Check(x)) {
PyErr_SetString(PyExc_TypeError,
- "optional arg must be an integer");
+ "optional arg must be an integer.");
return NULL;
}
y = PyLong_AsMpdSsize(x);
- if (y == MPD_SSIZE_MAX || y == MPD_SSIZE_MIN) {
+ if (PyErr_Occurred()) {
return NULL;
}
if ((result = dec_alloc()) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
- q.exp = -y;
+ q.exp = (y == MPD_SSIZE_MIN) ? MPD_SSIZE_MAX : -y;
mpd_qquantize(result->dec, a->dec, &q, ctx, &status);
if (dec_addstatus(ctx, status)) {
Py_DECREF(result);
@@ -2974,45 +3055,46 @@
}
if (PyBytes_Check(fmtarg)) {
- fmt = fmtarg;
+ fmt = fmtarg; /* GCOV_NOT_REACHED */
}
else if (PyUnicode_Check(fmtarg)) {
if ((fmt = PyUnicode_AsUTF8String(fmtarg)) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
}
else {
- PyErr_SetString(PyExc_TypeError, "format requires bytes or "
- "unicode arg");
+ PyErr_SetString(PyExc_TypeError,
+ "format requires bytes or unicode arg.");
return NULL;
}
if (!mpd_parse_fmt_str(&spec, PyBytes_AS_STRING(fmt),
CtxCaps(ctxobj))) {
- PyErr_SetString(PyExc_ValueError, "invalid format string");
+ PyErr_SetString(PyExc_ValueError,
+ "invalid format string.");
goto finish;
}
if (override) {
if (!PyDict_Check(override)) {
- PyErr_SetString(PyExc_TypeError, "optional argument "
- "must be a dict");
+ PyErr_SetString(PyExc_TypeError,
+ "optional argument must be a dict.");
goto finish;
}
if ((dot = PyDict_GetItemString(override, "decimal_point"))) {
if ((dot = PyUnicode_AsUTF8String(dot)) == NULL) {
- goto finish;
+ goto finish; /* GCOV_UNLIKELY */
}
spec.dot = PyBytes_AS_STRING(dot);
}
if ((sep = PyDict_GetItemString(override, "thousands_sep"))) {
if ((sep = PyUnicode_AsUTF8String(sep)) == NULL) {
- goto finish;
+ goto finish; /* GCOV_UNLIKELY */
}
spec.sep = PyBytes_AS_STRING(sep);
}
if ((grouping = PyDict_GetItemString(override, "grouping"))) {
if ((grouping = PyUnicode_AsUTF8String(grouping)) == NULL) {
- goto finish;
+ goto finish; /* GCOV_UNLIKELY */
}
spec.grouping = PyBytes_AS_STRING(grouping);
}
@@ -3020,38 +3102,38 @@
else {
n = strlen(spec.dot);
if (n > 1 || (n == 1 && !isascii((uchar)spec.dot[0]))) {
- n = mbstowcs(buf, spec.dot, 2);
- if (n != 1) {
- PyErr_SetString(PyExc_ValueError,
- "invalid decimal point or unsupported "
- "combination of LC_CTYPE and LC_NUMERIC");
- goto finish;
+ n = mbstowcs(buf, spec.dot, 2); /* GCOV_UNLIKELY */
+ if (n != 1) { /* GCOV_UNLIKELY */
+ PyErr_SetString(PyExc_ValueError, /* GCOV_UNLIKELY */
+ "invalid decimal point or unsupported "
+ "combination of LC_CTYPE and LC_NUMERIC.");
+ goto finish; /* GCOV_UNLIKELY */
}
- if ((tmp = PyUnicode_FromWideChar(buf, n)) == NULL) {
- goto finish;
+ if ((tmp = PyUnicode_FromWideChar(buf, n)) == NULL) { /* GCOV_UNLIKELY */
+ goto finish; /* GCOV_UNLIKELY */
}
- if ((dot = PyUnicode_AsUTF8String(tmp)) == NULL) {
- Py_DECREF(tmp);
- goto finish;
+ if ((dot = PyUnicode_AsUTF8String(tmp)) == NULL) { /* GCOV_UNLIKELY */
+ Py_DECREF(tmp); /* GCOV_UNLIKELY */
+ goto finish; /* GCOV_UNLIKELY */
}
- spec.dot = PyBytes_AS_STRING(dot);
- Py_DECREF(tmp);
+ spec.dot = PyBytes_AS_STRING(dot); /* GCOV_UNLIKELY */
+ Py_DECREF(tmp); /* GCOV_UNLIKELY */
}
n = strlen(spec.sep);
if (n > 1 || (n == 1 && !isascii((uchar)spec.sep[0]))) {
n = mbstowcs(buf, spec.sep, 2);
if (n != 1) {
- PyErr_SetString(PyExc_ValueError,
- "invalid thousands separator or unsupported "
- "combination of LC_CTYPE and LC_NUMERIC");
- goto finish;
+ PyErr_SetString(PyExc_ValueError, /* GCOV_UNLIKELY */
+ "invalid thousands separator or unsupported "
+ "combination of LC_CTYPE and LC_NUMERIC.");
+ goto finish; /* GCOV_UNLIKELY */
}
if ((tmp = PyUnicode_FromWideChar(buf, n)) == NULL) {
- goto finish;
+ goto finish; /* GCOV_UNLIKELY */
}
if ((sep = PyUnicode_AsUTF8String(tmp)) == NULL) {
- Py_DECREF(tmp);
- goto finish;
+ Py_DECREF(tmp); /* GCOV_UNLIKELY */
+ goto finish; /* GCOV_UNLIKELY */
}
spec.sep = PyBytes_AS_STRING(sep);
Py_DECREF(tmp);
@@ -3399,15 +3481,15 @@
CONVERT_BINOP(v, w, &a, &b, ctx);
if ((q = dec_alloc()) == NULL) {
- Py_DECREF(a);
- Py_DECREF(b);
- return NULL;
+ Py_DECREF(a); /* GCOV_UNLIKELY */
+ Py_DECREF(b); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
if ((r = dec_alloc()) == NULL) {
- Py_DECREF(a);
- Py_DECREF(b);
- Py_DECREF(q);
- return NULL;
+ Py_DECREF(a); /* GCOV_UNLIKELY */
+ Py_DECREF(b); /* GCOV_UNLIKELY */
+ Py_DECREF(q); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
mpd_qdivmod(q->dec, r->dec, a->dec, b->dec, ctx, &status);
@@ -3442,7 +3524,7 @@
}
if ((result = dec_alloc()) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
if (c == NULL) {
@@ -3526,13 +3608,13 @@
CURRENT_CONTEXT_ADDR(ctx);
if ((result = dec_alloc()) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
mpd_qcopy_abs(result->dec, a->dec, &status);
if (dec_addstatus(ctx, status)) {
- Py_DECREF(result);
- return NULL;
+ Py_DECREF(result); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
return (PyObject *) result;
@@ -3548,13 +3630,13 @@
CURRENT_CONTEXT_ADDR(ctx);
if ((result = dec_alloc()) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
mpd_qcopy_negate(result->dec, a->dec, &status);
if (dec_addstatus(ctx, status)) {
- Py_DECREF(result);
- return NULL;
+ Py_DECREF(result); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
return (PyObject *) result;
@@ -3578,17 +3660,17 @@
CONVERT_BINOP_SET(v, w, &a, &b, ctx);
if ((result = dec_alloc()) == NULL) {
- Py_DECREF(a);
- Py_DECREF(b);
- return NULL;
+ Py_DECREF(a); /* GCOV_UNLIKELY */
+ Py_DECREF(b); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
mpd_qcopy_sign(result->dec, a->dec, b->dec, &status);
Py_DECREF(a);
Py_DECREF(b);
if (dec_addstatus(ctx, status)) {
- Py_DECREF(result);
- return NULL;
+ Py_DECREF(result); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
return (PyObject *) result;
@@ -3656,15 +3738,15 @@
CONVERT_BINOP_SET(v, w, &a, &b, ctx);
if ((q = dec_alloc()) == NULL) {
- Py_DECREF(a);
- Py_DECREF(b);
- return NULL;
+ Py_DECREF(a); /* GCOV_UNLIKELY */
+ Py_DECREF(b); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
if ((r = dec_alloc()) == NULL) {
- Py_DECREF(a);
- Py_DECREF(b);
- Py_DECREF(q);
- return NULL;
+ Py_DECREF(a); /* GCOV_UNLIKELY */
+ Py_DECREF(b); /* GCOV_UNLIKELY */
+ Py_DECREF(q); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
mpd_qdivmod(q->dec, r->dec, a->dec, b->dec, ctx, &status);
@@ -3733,8 +3815,8 @@
s = mpd_to_sci(a->dec, CtxCaps(c));
if (s == NULL) {
- PyErr_NoMemory();
- return NULL;
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
result = PyUnicode_FromString(s);
@@ -3758,8 +3840,8 @@
s = mpd_to_eng(a->dec, CtxCaps(c));
if (s == NULL) {
- PyErr_NoMemory();
- return NULL;
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
result = PyUnicode_FromString(s);
@@ -3779,7 +3861,7 @@
int r;
CURRENT_CONTEXT_ADDR(ctx);
- CONVERT_BINOP(v, w, &a, &b, ctx);
+ CONVERT_BINOP_CMP(v, w, &a, &b, op, ctx);
a_issnan = mpd_issnan(a->dec);
b_issnan = mpd_issnan(b->dec);
@@ -3823,6 +3905,7 @@
return PyBool_FromLong(r);
}
+#if PY_VERSION_HEX < 0x03020000
/* Always uses the module context */
static long
dec_hash(PyObject *v)
@@ -3850,25 +3933,25 @@
long result;
if ((a = dec_alloc()) == NULL) {
- PyErr_NoMemory();
- return -1;
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ return -1; /* GCOV_UNLIKELY */
}
- if (!mpd_qcopy(a->dec, ((PyDecObject *) v)->dec, &status)) {
- PyErr_NoMemory();
- result = -1;
- goto finish;
+ if (!mpd_qcopy(a->dec, DecAddr(v), &status)) {
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ result = -1; /* GCOV_UNLIKELY */
+ goto finish; /* GCOV_UNLIKELY */
}
if (mpd_isspecial(a->dec)) {
if (mpd_isnan(a->dec)) {
PyErr_SetString(PyExc_ValueError,
- "cannot hash a NaN value");
+ "cannot hash a NaN value");
result = -1;
}
else {
if ((obj = dec_str(a)) == NULL) {
- result = -1;
- goto finish;
+ result = -1; /* GCOV_UNLIKELY */
+ goto finish; /* GCOV_UNLIKELY */
}
result = PyObject_Hash(obj);
}
@@ -3880,16 +3963,16 @@
PyObject *ctxobj = current_context();
mpd_context_t *ctx;
if (ctxobj == NULL) {
- result = -1;
- goto finish;
+ result = -1; /* GCOV_UNLIKELY */
+ goto finish; /* GCOV_UNLIKELY */
}
ctx = CtxAddr(ctxobj);
mpd_maxcontext(&maxcontext);
if ((tmp = mpd_qnew()) == NULL) {
- PyErr_NoMemory();
- result = -1;
- goto finish;
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ result = -1; /* GCOV_UNLIKELY */
+ goto finish; /* GCOV_UNLIKELY */
}
/* clobbering a function scope object */
@@ -3900,15 +3983,15 @@
mpd_qmul(a->dec, a->dec, tmp, &maxcontext, &status);
if (status&MPD_Errors) {
- if (dec_addstatus(ctx, status)) {
- result = -1;
- goto finish;
+ if (dec_addstatus(ctx, status)) { /* GCOV_UNLIKELY */
+ result = -1; /* GCOV_UNLIKELY */
+ goto finish; /* GCOV_UNLIKELY */
}
}
if ((obj = PyLong_FromDecCtx(a, &maxcontext)) == NULL) {
- result = -1;
- goto finish;
+ result = -1; /* GCOV_UNLIKELY */
+ goto finish; /* GCOV_UNLIKELY */
}
result = PyObject_Hash(obj);
}
@@ -3924,13 +4007,13 @@
mpd_qshiftr_inplace(a->dec, tz);
a->dec->exp = 0;
- a->dec->flags = MPD_POS;
+ mpd_set_flags(a->dec, MPD_POS);
cp = mpd_to_sci(a->dec, 1);
obj = Py_BuildValue("(i"CONV_mpd_ssize_t"s)", sign, exp, cp);
if (obj == NULL) {
- result = -1;
- goto finish;
+ result = -1; /* GCOV_UNLIKELY */
+ goto finish; /* GCOV_UNLIKELY */
}
result = PyObject_Hash(obj);
}
@@ -3943,6 +4026,120 @@
if (cp) mpd_free(cp);
return result;
}
+#else
+/* Always uses the module context */
+static Py_hash_t
+dec_hash(PyObject *v)
+{
+#if defined(CONFIG_64) && _PyHASH_BITS == 61
+ /* 2**61 - 1 */
+ mpd_uint_t p_data[1] = {2305843009213693951ULL};
+ mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 19, 1, 1, p_data};
+ /* Inverse of 10 modulo p */
+ mpd_uint_t inv10_p_data[2] = {2075258708292324556ULL};
+ mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
+ 0, 19, 1, 1, inv10_p_data};
+#elif defined(CONFIG_32) && _PyHASH_BITS == 31
+ /* 2**31 - 1 */
+ mpd_uint_t p_data[2] = {147483647UL, 2};
+ mpd_t p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA, 0, 10, 2, 2, p_data};
+ /* Inverse of 10 modulo p */
+ mpd_uint_t inv10_p_data[2] = {503238553UL, 1};
+ mpd_t inv10_p = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
+ 0, 10, 2, 2, inv10_p_data};
+#else
+ #error "No valid combination of CONFIG_64, CONFIG_32 and _PyHASH_BITS."
+#endif
+ const Py_hash_t py_hash_inf = 314159;
+ const Py_hash_t py_hash_nan = 0;
+ mpd_uint_t ten_data[1] = {10};
+ mpd_t ten = {MPD_POS|MPD_STATIC|MPD_CONST_DATA,
+ 0, 2, 1, 1, ten_data};
+ Py_hash_t result;
+ mpd_t *exp_hash = NULL;
+ mpd_t *tmp = NULL;
+ mpd_ssize_t exp;
+ uint32_t status = 0;
+ mpd_context_t *ctx, maxcontext;
+ PyObject *ctxobj;
+
+
+ ctxobj = current_context();
+ if (ctxobj == NULL) {
+ return -1; /* GCOV_UNLIKELY */
+ }
+ ctx = CtxAddr(ctxobj);
+
+ if (mpd_isspecial(DecAddr(v))) {
+ if (mpd_issnan(DecAddr(v))) {
+ return value_error_int(
+ "Cannot hash a signaling NaN value.");
+ }
+ else if (mpd_isnan(DecAddr(v))) {
+ return py_hash_nan;
+ }
+ else {
+ return py_hash_inf * mpd_arith_sign(DecAddr(v));
+ }
+ }
+
+ mpd_maxcontext(&maxcontext);
+ if ((exp_hash = mpd_qnew()) == NULL) {
+ goto malloc_error; /* GCOV_UNLIKELY */
+ }
+ if ((tmp = mpd_qnew()) == NULL) {
+ goto malloc_error; /* GCOV_UNLIKELY */
+ }
+
+ /*
+ * exp(v): exponent of v
+ * int(v): coefficient of v
+ */
+ exp = DecAddr(v)->exp;
+ if (exp >= 0) {
+ /* 10**exp(v) % p */
+ mpd_qsset_ssize(tmp, exp, &maxcontext, &status);
+ mpd_qpowmod(exp_hash, &ten, tmp, &p, &maxcontext, &status);
+ }
+ else {
+ /* inv10_p**(-exp(v)) % p */
+ mpd_qsset_ssize(tmp, -exp, &maxcontext, &status);
+ mpd_qpowmod(exp_hash, &inv10_p, tmp, &p, &maxcontext, &status);
+ }
+
+ /* hash = (int(v) * exp_hash) % p */
+ if (!mpd_qcopy(tmp, DecAddr(v), &status)) {
+ goto malloc_error; /* GCOV_UNLIKELY */
+ }
+ tmp->exp = 0;
+ mpd_set_positive(tmp);
+ mpd_qmul(tmp, tmp, exp_hash, &maxcontext, &status);
+ mpd_qrem(tmp, tmp, &p, &maxcontext, &status);
+
+ result = mpd_qget_ssize(tmp, &status);
+ result = mpd_ispositive(DecAddr(v)) ? result : -result;
+ result = (result == -1) ? -2 : result;
+
+ if (status != 0) {
+ status |= MPD_Invalid_operation; /* GCOV_UNLIKELY */
+ if (dec_addstatus(ctx, status)) { /* GCOV_UNLIKELY */
+ result = -1; /* GCOV_UNLIKELY */
+ goto finish; /* GCOV_UNLIKELY */
+ }
+ }
+
+
+finish:
+ if (exp_hash) mpd_del(exp_hash);
+ if (tmp) mpd_del(tmp);
+ return result;
+
+malloc_error: /* GCOV_UNLIKELY */
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ result = -1; /* GCOV_UNLIKELY */
+ goto finish; /* GCOV_UNLIKELY */
+}
+#endif
static PyObject *
dec_reduce(PyObject *self, PyObject *dummy UNUSED)
@@ -3950,7 +4147,7 @@
PyObject *newob, *mpd_str;
if ((mpd_str = dec_str((PyDecObject *)self)) == NULL) {
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
newob = Py_BuildValue("O(N)", Py_TYPE(self), mpd_str);
@@ -3997,111 +4194,111 @@
static PyMethodDef dec_methods [] =
{
- /* Unary arithmetic functions */
- { "abs", _DecOpt_mpd_qabs, METH_VARARGS, doc_abs },
- { "exp", _DecOpt_mpd_qexp, METH_VARARGS, doc_exp },
- { "invroot", _DecOpt_mpd_qinvroot, METH_VARARGS, doc_invroot },
- { "ln", _DecOpt_mpd_qln, METH_VARARGS, doc_ln },
- { "log10", _DecOpt_mpd_qlog10, METH_VARARGS, doc_log10 },
- { "minus", _DecOpt_mpd_qminus, METH_VARARGS, doc_minus },
- { "next_minus", _DecOpt_mpd_qnext_minus, METH_VARARGS, doc_next_minus },
- { "next_plus", _DecOpt_mpd_qnext_plus, METH_VARARGS, doc_next_plus },
- { "normalize", _DecOpt_mpd_qreduce, METH_VARARGS, doc_normalize }, /* alias for reduce */
- { "plus", _DecOpt_mpd_qplus, METH_VARARGS, doc_plus },
- { "reduce", _DecOpt_mpd_qreduce, METH_VARARGS, doc_reduce },
- { "to_integral", (PyCFunction)PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral },
- { "to_integral_exact", (PyCFunction)PyDec_ToIntegralExact, METH_VARARGS|METH_KEYWORDS, doc_to_integral_exact },
- { "to_integral_value", (PyCFunction)PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral_value },
- { "sqrt", _DecOpt_mpd_qsqrt, METH_VARARGS, doc_sqrt },
-
- /* Binary arithmetic functions */
- { "add", _DecOpt_mpd_qadd, METH_VARARGS, doc_add },
- { "compare", _DecOpt_mpd_qcompare, METH_VARARGS, doc_compare },
- { "compare_signal", _DecOpt_mpd_qcompare_signal, METH_VARARGS, doc_compare_signal },
- { "div", _DecOpt_mpd_qdiv, METH_VARARGS, doc_div }, /* alias for divide */
- { "divide", _DecOpt_mpd_qdiv, METH_VARARGS, doc_divide },
- { "divide_int", _DecOpt_mpd_qdivint, METH_VARARGS, doc_divide_int },
- { "divint", _DecOpt_mpd_qdivint, METH_VARARGS, doc_divint }, /* alias for divide_int */
- { "divmod", _DecOpt_mpd_qdivmod, METH_VARARGS, doc_divmod },
- { "max", _DecOpt_mpd_qmax, METH_VARARGS, doc_max },
- { "max_mag", _DecOpt_mpd_qmax_mag, METH_VARARGS, doc_max_mag },
- { "min", _DecOpt_mpd_qmin, METH_VARARGS, doc_min },
- { "min_mag", _DecOpt_mpd_qmin_mag, METH_VARARGS, doc_min_mag },
- { "mul", _DecOpt_mpd_qmul, METH_VARARGS, doc_mul }, /* alias for multiply */
- { "multiply", _DecOpt_mpd_qmul, METH_VARARGS, doc_multiply },
- { "next_toward", _DecOpt_mpd_qnext_toward, METH_VARARGS, doc_next_toward },
- { "pow", _DecOpt_mpd_qpow, METH_VARARGS, doc_pow }, /* alias for power */
- { "power", _DecOpt_mpd_qpow, METH_VARARGS, doc_power },
- { "quantize", _DecOpt_mpd_qquantize, METH_VARARGS, doc_quantize },
- { "rem", _DecOpt_mpd_qrem, METH_VARARGS, doc_rem }, /* alias for remainder */
- { "remainder", _DecOpt_mpd_qrem, METH_VARARGS, doc_remainder },
- { "remainder_near", _DecOpt_mpd_qrem_near, METH_VARARGS, doc_remainder_near },
- { "sub", _DecOpt_mpd_qsub, METH_VARARGS, doc_sub }, /* alias for subtract */
- { "subtract", _DecOpt_mpd_qsub, METH_VARARGS, doc_subtract },
-
- /* Ternary arithmetic functions */
- { "fma", _DecOpt_mpd_qfma, METH_VARARGS, doc_fma },
- { "powmod", _DecOpt_mpd_qpowmod, METH_VARARGS, doc_powmod },
-
- /* Boolean functions, no context arg */
- { "is_canonical", _Dec_CFunc_mpd_iscanonical, METH_NOARGS, doc_is_canonical },
- { "is_finite", _Dec_CFunc_mpd_isfinite, METH_NOARGS, doc_is_finite },
- { "is_infinite", _Dec_CFunc_mpd_isinfinite, METH_NOARGS, doc_is_infinite },
- { "is_integer", _Dec_CFunc_mpd_isinteger, METH_NOARGS, doc_is_integer },
- { "is_nan", _Dec_CFunc_mpd_isnan, METH_NOARGS, doc_is_nan },
- { "is_qnan", _Dec_CFunc_mpd_isqnan, METH_NOARGS, doc_is_qnan },
- { "is_snan", _Dec_CFunc_mpd_issnan, METH_NOARGS, doc_is_snan },
- { "is_signed", _Dec_CFunc_mpd_issigned, METH_NOARGS, doc_is_signed },
- { "is_special", _Dec_CFunc_mpd_isspecial, METH_NOARGS, doc_is_special },
- { "is_zero", _Dec_CFunc_mpd_iszero, METH_NOARGS, doc_is_zero },
-
- /* Boolean functions, optional context arg */
- { "is_normal", _DecOpt_mpd_isnormal, METH_VARARGS, doc_is_normal },
- { "is_subnormal", _DecOpt_mpd_issubnormal, METH_VARARGS, doc_is_subnormal },
-
- /* Unary functions, no context arg */
- { "adjusted", _Dec_mpd_adjexp, METH_NOARGS, doc_adjusted },
- { "canonical", _Dec_canonical, METH_NOARGS, doc_canonical },
- { "copy_abs", _Dec_mpd_qcopy_abs, METH_NOARGS, doc_copy_abs },
- { "copy_negate", _Dec_mpd_qcopy_negate, METH_NOARGS, doc_copy_negate },
- { "radix", _Dec_mpd_radix, METH_NOARGS, doc_radix },
- { "sign", _Dec_mpd_sign, METH_NOARGS, doc_sign },
-
- /* Unary functions, optional context arg */
- { "apply", PyDec_Apply, METH_VARARGS, doc_apply },
- { "logb", _DecOpt_mpd_qlogb, METH_VARARGS, doc_logb },
- { "logical_invert", _DecOpt_mpd_qinvert, METH_VARARGS, doc_logical_invert },
- { "number_class", _DecOpt_mpd_class, METH_VARARGS, doc_number_class },
- { "to_sci", _Dec_mpd_to_sci, METH_VARARGS, doc_to_sci }, /* alias for to_sci_string */
- { "to_sci_string", _Dec_mpd_to_sci, METH_VARARGS, doc_to_sci_string },
- { "to_eng", _Dec_mpd_to_eng, METH_VARARGS, doc_to_eng }, /* alias for to_eng_string */
- { "to_eng_string", _Dec_mpd_to_eng, METH_VARARGS, doc_to_eng_string },
-
- /* Binary functions, optional context arg */
- { "compare_total", _DecOpt_mpd_compare_total, METH_VARARGS, doc_compare_total },
- { "compare_total_mag", _DecOpt_mpd_compare_total_mag, METH_VARARGS, doc_compare_total_mag },
- { "copy_sign", _Dec_mpd_qcopy_sign, METH_O, doc_copy_sign },
- { "logical_and", _DecOpt_mpd_qand, METH_VARARGS, doc_logical_and },
- { "logical_or", _DecOpt_mpd_qor, METH_VARARGS, doc_logical_or },
- { "logical_xor", _DecOpt_mpd_qxor, METH_VARARGS, doc_logical_xor },
- { "rotate", _DecOpt_mpd_qrotate, METH_VARARGS, doc_rotate },
- { "same_quantum", _Dec_mpd_same_quantum, METH_VARARGS, doc_same_quantum },
- { "scaleb", _DecOpt_mpd_qscaleb, METH_VARARGS, doc_scaleb },
- { "shift", _DecOpt_mpd_qshift, METH_VARARGS, doc_shift },
-
- /* Miscellaneous */
- { "from_float", _PyDec_FromFloat_Max, METH_O|METH_CLASS, doc_from_float },
- { "as_tuple", PyDec_AsTuple, METH_NOARGS, doc_as_tuple },
-
- /* Generic stuff */
- { "__copy__", dec_copy, METH_NOARGS, NULL },
- { "__deepcopy__", dec_copy, METH_VARARGS, NULL },
- { "__format__", dec_format, METH_VARARGS, NULL },
- { "__reduce__", dec_reduce, METH_NOARGS, NULL },
- { "__round__", PyDec_Round, METH_VARARGS, NULL },
- { "__trunc__", PyDec_Trunc, METH_NOARGS, NULL },
+ /* Unary arithmetic functions */
+ { "abs", _DecOpt_mpd_qabs, METH_VARARGS, doc_abs },
+ { "exp", _DecOpt_mpd_qexp, METH_VARARGS, doc_exp },
+ { "invroot", _DecOpt_mpd_qinvroot, METH_VARARGS, doc_invroot },
+ { "ln", _DecOpt_mpd_qln, METH_VARARGS, doc_ln },
+ { "log10", _DecOpt_mpd_qlog10, METH_VARARGS, doc_log10 },
+ { "minus", _DecOpt_mpd_qminus, METH_VARARGS, doc_minus },
+ { "next_minus", _DecOpt_mpd_qnext_minus, METH_VARARGS, doc_next_minus },
+ { "next_plus", _DecOpt_mpd_qnext_plus, METH_VARARGS, doc_next_plus },
+ { "normalize", _DecOpt_mpd_qreduce, METH_VARARGS, doc_normalize }, /* alias for reduce */
+ { "plus", _DecOpt_mpd_qplus, METH_VARARGS, doc_plus },
+ { "reduce", _DecOpt_mpd_qreduce, METH_VARARGS, doc_reduce },
+ { "to_integral", (PyCFunction)PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral },
+ { "to_integral_exact", (PyCFunction)PyDec_ToIntegralExact, METH_VARARGS|METH_KEYWORDS, doc_to_integral_exact },
+ { "to_integral_value", (PyCFunction)PyDec_ToIntegralValue, METH_VARARGS|METH_KEYWORDS, doc_to_integral_value },
+ { "sqrt", _DecOpt_mpd_qsqrt, METH_VARARGS, doc_sqrt },
+
+ /* Binary arithmetic functions */
+ { "add", _DecOpt_mpd_qadd, METH_VARARGS, doc_add },
+ { "compare", _DecOpt_mpd_qcompare, METH_VARARGS, doc_compare },
+ { "compare_signal", _DecOpt_mpd_qcompare_signal, METH_VARARGS, doc_compare_signal },
+ { "div", _DecOpt_mpd_qdiv, METH_VARARGS, doc_div }, /* alias for divide */
+ { "divide", _DecOpt_mpd_qdiv, METH_VARARGS, doc_divide },
+ { "divide_int", _DecOpt_mpd_qdivint, METH_VARARGS, doc_divide_int },
+ { "divint", _DecOpt_mpd_qdivint, METH_VARARGS, doc_divint }, /* alias for divide_int */
+ { "divmod", _DecOpt_mpd_qdivmod, METH_VARARGS, doc_divmod },
+ { "max", _DecOpt_mpd_qmax, METH_VARARGS, doc_max },
+ { "max_mag", _DecOpt_mpd_qmax_mag, METH_VARARGS, doc_max_mag },
+ { "min", _DecOpt_mpd_qmin, METH_VARARGS, doc_min },
+ { "min_mag", _DecOpt_mpd_qmin_mag, METH_VARARGS, doc_min_mag },
+ { "mul", _DecOpt_mpd_qmul, METH_VARARGS, doc_mul }, /* alias for multiply */
+ { "multiply", _DecOpt_mpd_qmul, METH_VARARGS, doc_multiply },
+ { "next_toward", _DecOpt_mpd_qnext_toward, METH_VARARGS, doc_next_toward },
+ { "pow", _DecOpt_mpd_qpow, METH_VARARGS, doc_pow }, /* alias for power */
+ { "power", _DecOpt_mpd_qpow, METH_VARARGS, doc_power },
+ { "quantize", _DecOpt_mpd_qquantize, METH_VARARGS, doc_quantize },
+ { "rem", _DecOpt_mpd_qrem, METH_VARARGS, doc_rem }, /* alias for remainder */
+ { "remainder", _DecOpt_mpd_qrem, METH_VARARGS, doc_remainder },
+ { "remainder_near", _DecOpt_mpd_qrem_near, METH_VARARGS, doc_remainder_near },
+ { "sub", _DecOpt_mpd_qsub, METH_VARARGS, doc_sub }, /* alias for subtract */
+ { "subtract", _DecOpt_mpd_qsub, METH_VARARGS, doc_subtract },
+
+ /* Ternary arithmetic functions */
+ { "fma", _DecOpt_mpd_qfma, METH_VARARGS, doc_fma },
+ { "powmod", _DecOpt_mpd_qpowmod, METH_VARARGS, doc_powmod },
+
+ /* Boolean functions, no context arg */
+ { "is_canonical", _Dec_CFunc_mpd_iscanonical, METH_NOARGS, doc_is_canonical },
+ { "is_finite", _Dec_CFunc_mpd_isfinite, METH_NOARGS, doc_is_finite },
+ { "is_infinite", _Dec_CFunc_mpd_isinfinite, METH_NOARGS, doc_is_infinite },
+ { "is_integer", _Dec_CFunc_mpd_isinteger, METH_NOARGS, doc_is_integer },
+ { "is_nan", _Dec_CFunc_mpd_isnan, METH_NOARGS, doc_is_nan },
+ { "is_qnan", _Dec_CFunc_mpd_isqnan, METH_NOARGS, doc_is_qnan },
+ { "is_snan", _Dec_CFunc_mpd_issnan, METH_NOARGS, doc_is_snan },
+ { "is_signed", _Dec_CFunc_mpd_issigned, METH_NOARGS, doc_is_signed },
+ { "is_special", _Dec_CFunc_mpd_isspecial, METH_NOARGS, doc_is_special },
+ { "is_zero", _Dec_CFunc_mpd_iszero, METH_NOARGS, doc_is_zero },
+
+ /* Boolean functions, optional context arg */
+ { "is_normal", _DecOpt_mpd_isnormal, METH_VARARGS, doc_is_normal },
+ { "is_subnormal", _DecOpt_mpd_issubnormal, METH_VARARGS, doc_is_subnormal },
+
+ /* Unary functions, no context arg */
+ { "adjusted", _Dec_mpd_adjexp, METH_NOARGS, doc_adjusted },
+ { "canonical", _Dec_canonical, METH_NOARGS, doc_canonical },
+ { "copy_abs", _Dec_mpd_qcopy_abs, METH_NOARGS, doc_copy_abs },
+ { "copy_negate", _Dec_mpd_qcopy_negate, METH_NOARGS, doc_copy_negate },
+ { "radix", _Dec_mpd_radix, METH_NOARGS, doc_radix },
+ { "sign", _Dec_mpd_sign, METH_NOARGS, doc_sign },
+
+ /* Unary functions, optional context arg */
+ { "apply", PyDec_Apply, METH_VARARGS, doc_apply },
+ { "logb", _DecOpt_mpd_qlogb, METH_VARARGS, doc_logb },
+ { "logical_invert", _DecOpt_mpd_qinvert, METH_VARARGS, doc_logical_invert },
+ { "number_class", _DecOpt_mpd_class, METH_VARARGS, doc_number_class },
+ { "to_sci", _Dec_mpd_to_sci, METH_VARARGS, doc_to_sci }, /* alias for to_sci_string */
+ { "to_sci_string", _Dec_mpd_to_sci, METH_VARARGS, doc_to_sci_string },
+ { "to_eng", _Dec_mpd_to_eng, METH_VARARGS, doc_to_eng }, /* alias for to_eng_string */
+ { "to_eng_string", _Dec_mpd_to_eng, METH_VARARGS, doc_to_eng_string },
+
+ /* Binary functions, optional context arg */
+ { "compare_total", _DecOpt_mpd_compare_total, METH_VARARGS, doc_compare_total },
+ { "compare_total_mag", _DecOpt_mpd_compare_total_mag, METH_VARARGS, doc_compare_total_mag },
+ { "copy_sign", _Dec_mpd_qcopy_sign, METH_O, doc_copy_sign },
+ { "logical_and", _DecOpt_mpd_qand, METH_VARARGS, doc_logical_and },
+ { "logical_or", _DecOpt_mpd_qor, METH_VARARGS, doc_logical_or },
+ { "logical_xor", _DecOpt_mpd_qxor, METH_VARARGS, doc_logical_xor },
+ { "rotate", _DecOpt_mpd_qrotate, METH_VARARGS, doc_rotate },
+ { "same_quantum", _Dec_mpd_same_quantum, METH_VARARGS, doc_same_quantum },
+ { "scaleb", _DecOpt_mpd_qscaleb, METH_VARARGS, doc_scaleb },
+ { "shift", _DecOpt_mpd_qshift, METH_VARARGS, doc_shift },
+
+ /* Miscellaneous */
+ { "from_float", _PyDec_FromFloat_Max, METH_O|METH_CLASS, doc_from_float },
+ { "as_tuple", PyDec_AsTuple, METH_NOARGS, doc_as_tuple },
+
+ /* Generic stuff */
+ { "__copy__", dec_copy, METH_NOARGS, NULL },
+ { "__deepcopy__", dec_copy, METH_VARARGS, NULL },
+ { "__format__", dec_format, METH_VARARGS, NULL },
+ { "__reduce__", dec_reduce, METH_NOARGS, NULL },
+ { "__round__", PyDec_Round, METH_VARARGS, NULL },
+ { "__trunc__", PyDec_Trunc, METH_NOARGS, NULL },
- { NULL, NULL, 1 }
+ { NULL, NULL, 1 }
};
static PyTypeObject PyDec_Type =
@@ -4405,15 +4602,15 @@
CONVERT_OP_SET(v, &a, ctx);
if ((result = dec_alloc()) == NULL) {
- Py_DECREF(a);
- return NULL;
+ Py_DECREF(a); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
mpd_qcopy_abs(result->dec, a->dec, &status);
Py_DECREF(a);
if (dec_addstatus(ctx, status)) {
- Py_DECREF(result);
- return NULL;
+ Py_DECREF(result); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
return (PyObject *) result;
@@ -4430,15 +4627,15 @@
CONVERT_OP_SET(v, &a, ctx);
if ((result = dec_alloc()) == NULL) {
- Py_DECREF(a);
- return NULL;
+ Py_DECREF(a); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
mpd_qcopy_negate(result->dec, a->dec, &status);
Py_DECREF(a);
if (dec_addstatus(ctx, status)) {
- Py_DECREF(result);
- return NULL;
+ Py_DECREF(result); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
return (PyObject *) result;
@@ -4467,17 +4664,17 @@
CONVERT_BINOP_SET(v, w, &a, &b, ctx);
if ((result = dec_alloc()) == NULL) {
- Py_DECREF(a);
- Py_DECREF(b);
- return NULL;
+ Py_DECREF(a); /* GCOV_UNLIKELY */
+ Py_DECREF(b); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
mpd_qcopy_sign(result->dec, a->dec, b->dec, &status);
Py_DECREF(a);
Py_DECREF(b);
if (dec_addstatus(ctx, status)) {
- Py_DECREF(result);
- return NULL;
+ Py_DECREF(result); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
return (PyObject *) result;
@@ -4495,7 +4692,8 @@
_DecCtx_iscanonical(PyObject *self UNUSED, PyObject *v)
{
if (!PyDec_Check(v)) {
- PyErr_SetString(PyExc_TypeError, "argument must be a Decimal");
+ PyErr_SetString(PyExc_TypeError,
+ "argument must be a Decimal.");
return NULL;
}
@@ -4506,7 +4704,8 @@
_DecCtx_canonical(PyObject *self UNUSED, PyObject *v)
{
if (!PyDec_Check(v)) {
- PyErr_SetString(PyExc_TypeError, "argument must be a Decimal");
+ PyErr_SetString(PyExc_TypeError,
+ "argument must be a Decimal.");
return NULL;
}
@@ -4547,15 +4746,15 @@
CONVERT_BINOP_SET(v, w, &a, &b, ctx);
if ((q = dec_alloc()) == NULL) {
- Py_DECREF(a);
- Py_DECREF(b);
- return NULL;
+ Py_DECREF(a); /* GCOV_UNLIKELY */
+ Py_DECREF(b); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
if ((r = dec_alloc()) == NULL) {
- Py_DECREF(a);
- Py_DECREF(b);
- Py_DECREF(q);
- return NULL;
+ Py_DECREF(a); /* GCOV_UNLIKELY */
+ Py_DECREF(b); /* GCOV_UNLIKELY */
+ Py_DECREF(q); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
mpd_qdivmod(q->dec, r->dec, a->dec, b->dec, ctx, &status);
@@ -4584,8 +4783,8 @@
s = mpd_to_sci(a->dec, CtxCaps(self));
Py_DECREF(a);
if (s == NULL) {
- PyErr_NoMemory();
- return NULL;
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
result = PyUnicode_FromString(s);
@@ -4608,8 +4807,8 @@
s = mpd_to_eng(a->dec, CtxCaps(self));
Py_DECREF(a);
if (s == NULL) {
- PyErr_NoMemory();
- return NULL;
+ PyErr_NoMemory(); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
result = PyUnicode_FromString(s);
@@ -4650,115 +4849,115 @@
static PyMethodDef context_methods [] =
{
- /* Unary arithmetic functions */
- { "abs", _DecCtx_mpd_qabs, METH_O, doc_ctx_abs },
- { "exp", _DecCtx_mpd_qexp, METH_O, doc_ctx_exp },
- { "invroot", _DecCtx_mpd_qinvroot, METH_O, doc_ctx_invroot },
- { "ln", _DecCtx_mpd_qln, METH_O, doc_ctx_ln },
- { "log10", _DecCtx_mpd_qlog10, METH_O, doc_ctx_log10 },
- { "minus", _DecCtx_mpd_qminus, METH_O, doc_ctx_minus },
- { "next_minus", _DecCtx_mpd_qnext_minus, METH_O, doc_ctx_next_minus },
- { "next_plus", _DecCtx_mpd_qnext_plus, METH_O, doc_ctx_next_plus },
- { "normalize", _DecCtx_mpd_qreduce, METH_O, doc_ctx_normalize }, /* alias for reduce */
- { "plus", _DecCtx_mpd_qplus, METH_O, doc_ctx_plus },
- { "reduce", _DecCtx_mpd_qreduce, METH_O, doc_ctx_reduce },
- { "to_integral", _DecCtx_mpd_qround_to_int, METH_O, doc_ctx_to_integral },
- { "to_integral_exact", _DecCtx_mpd_qround_to_intx, METH_O, doc_ctx_to_integral_exact },
- { "to_integral_value", _DecCtx_mpd_qround_to_int, METH_O, doc_ctx_to_integral_value },
- { "sqrt", _DecCtx_mpd_qsqrt, METH_O, doc_ctx_sqrt },
-
- /* Binary arithmetic functions */
- { "add", _DecCtx_mpd_qadd, METH_VARARGS, doc_ctx_add },
- { "compare", _DecCtx_mpd_qcompare, METH_VARARGS, doc_ctx_compare },
- { "compare_signal", _DecCtx_mpd_qcompare_signal, METH_VARARGS, doc_ctx_compare_signal },
- { "div", _DecCtx_mpd_qdiv, METH_VARARGS, doc_ctx_div }, /* alias for divide */
- { "divide", _DecCtx_mpd_qdiv, METH_VARARGS, doc_ctx_divide },
- { "divide_int", _DecCtx_mpd_qdivint, METH_VARARGS, doc_ctx_divide_int },
- { "divint", _DecCtx_mpd_qdivint, METH_VARARGS, doc_ctx_divint }, /* alias for divide_int */
- { "divmod", _DecCtx_mpd_qdivmod, METH_VARARGS, doc_ctx_divmod },
- { "max", _DecCtx_mpd_qmax, METH_VARARGS, doc_ctx_max },
- { "max_mag", _DecCtx_mpd_qmax_mag, METH_VARARGS, doc_ctx_max_mag },
- { "min", _DecCtx_mpd_qmin, METH_VARARGS, doc_ctx_min },
- { "min_mag", _DecCtx_mpd_qmin_mag, METH_VARARGS, doc_ctx_min_mag },
- { "mul", _DecCtx_mpd_qmul, METH_VARARGS, doc_ctx_mul }, /* alias for multiply */
- { "multiply", _DecCtx_mpd_qmul, METH_VARARGS, doc_ctx_multiply },
- { "next_toward", _DecCtx_mpd_qnext_toward, METH_VARARGS, doc_ctx_next_toward },
- { "pow", _DecCtx_mpd_qpow, METH_VARARGS, doc_ctx_pow }, /* alias for power */
- { "power", _DecCtx_mpd_qpow, METH_VARARGS, doc_ctx_power },
- { "quantize", _DecCtx_mpd_qquantize, METH_VARARGS, doc_ctx_quantize },
- { "rem", _DecCtx_mpd_qrem, METH_VARARGS, doc_ctx_rem }, /* alias for remainder */
- { "remainder", _DecCtx_mpd_qrem, METH_VARARGS, doc_ctx_remainder },
- { "remainder_near", _DecCtx_mpd_qrem_near, METH_VARARGS, doc_ctx_remainder_near },
- { "sub", _DecCtx_mpd_qsub, METH_VARARGS, doc_ctx_sub }, /* alias for subtract */
- { "subtract", _DecCtx_mpd_qsub, METH_VARARGS, doc_ctx_subtract },
-
- /* Ternary arithmetic functions */
- { "fma", _DecCtx_mpd_qfma, METH_VARARGS, doc_ctx_fma },
- { "powmod", _DecCtx_mpd_qpowmod, METH_VARARGS, doc_ctx_powmod },
-
- /* No argument */
- { "Etiny", context_getetiny, METH_NOARGS, doc_ctx_Etiny },
- { "Etop", context_getetop, METH_NOARGS, doc_ctx_Etop },
- { "radix", _DecCtx_mpd_radix, METH_NOARGS, doc_ctx_radix },
-
- /* Boolean functions */
- { "is_canonical", _DecCtx_iscanonical, METH_O, doc_ctx_is_canonical },
- { "is_finite", _DecCtx_mpd_isfinite, METH_O, doc_ctx_is_finite },
- { "is_infinite", _DecCtx_mpd_isinfinite, METH_O, doc_ctx_is_infinite },
- { "is_nan", _DecCtx_mpd_isnan, METH_O, doc_ctx_is_nan },
- { "is_normal", _DecCtx_mpd_isnormal, METH_O, doc_ctx_is_normal },
- { "is_qnan", _DecCtx_mpd_isqnan, METH_O, doc_ctx_is_qnan },
- { "is_signed", _DecCtx_mpd_issigned, METH_O, doc_ctx_is_signed },
- { "is_snan", _DecCtx_mpd_issnan, METH_O, doc_ctx_is_snan },
- { "is_subnormal", _DecCtx_mpd_issubnormal, METH_O, doc_ctx_is_subnormal },
- { "is_zero", _DecCtx_mpd_iszero, METH_O, doc_ctx_is_zero },
-
- /* Functions with a single decimal argument */
- { "_apply", PyDecContext_Apply, METH_O, NULL }, /* alias for apply */
- { "apply", PyDecContext_Apply, METH_O, doc_ctx_apply },
- { "canonical", _DecCtx_canonical, METH_O, doc_ctx_canonical },
- { "copy_abs", _DecCtx_mpd_qcopy_abs, METH_O, doc_ctx_copy_abs },
- { "copy_decimal", _DecCtx_copy_decimal, METH_O, doc_ctx_copy_decimal },
- { "copy_negate", _DecCtx_mpd_qcopy_negate, METH_O, doc_ctx_copy_negate },
- { "logb", _DecCtx_mpd_qlogb, METH_O, doc_ctx_logb },
- { "logical_invert", _DecCtx_mpd_qinvert, METH_O, doc_ctx_logical_invert },
- { "number_class", _DecCtx_mpd_class, METH_O, doc_ctx_number_class },
- { "to_sci", _DecCtx_mpd_to_sci, METH_O, doc_ctx_to_sci }, /* alias for to_sci_string */
- { "to_sci_string", _DecCtx_mpd_to_sci, METH_O, doc_ctx_to_sci_string },
- { "to_eng", _DecCtx_mpd_to_eng, METH_O, doc_ctx_to_eng }, /* alias for to_eng_string */
- { "to_eng_string", _DecCtx_mpd_to_eng, METH_O, doc_ctx_to_eng_string },
-
- /* Functions with two decimal arguments */
- { "compare_total", _DecCtx_mpd_compare_total, METH_VARARGS, doc_ctx_compare_total },
- { "compare_total_mag", _DecCtx_mpd_compare_total_mag, METH_VARARGS, doc_ctx_compare_total_mag },
- { "copy_sign", _DecCtx_mpd_qcopy_sign, METH_VARARGS, doc_ctx_copy_sign },
- { "logical_and", _DecCtx_mpd_qand, METH_VARARGS, doc_ctx_logical_and },
- { "logical_or", _DecCtx_mpd_qor, METH_VARARGS, doc_ctx_logical_or },
- { "logical_xor", _DecCtx_mpd_qxor, METH_VARARGS, doc_ctx_logical_xor },
- { "rotate", _DecCtx_mpd_qrotate, METH_VARARGS, doc_ctx_rotate },
- { "same_quantum", _DecCtx_mpd_same_quantum, METH_VARARGS, doc_ctx_same_quantum },
- { "scaleb", _DecCtx_mpd_qscaleb, METH_VARARGS, doc_ctx_scaleb },
- { "shift", _DecCtx_mpd_qshift, METH_VARARGS, doc_ctx_shift },
-
- /* Set context values */
- { "setflags", PyDec_SetStatusFromList, METH_O, doc_ctx_setflags },
- { "settraps", PyDec_SetTrapsFromList, METH_O, doc_ctx_settraps },
- { "clear_flags", context_clear_flags, METH_NOARGS, doc_ctx_clear_flags },
- { "clear_traps", context_clear_traps, METH_NOARGS, doc_ctx_clear_traps },
-
- /* Unsafe set functions with no range checks */
- { "unsafe_setprec", context_unsafe_setprec, METH_O, NULL },
- { "unsafe_setemin", context_unsafe_setemin, METH_O, NULL },
- { "unsafe_setemax", context_unsafe_setemax, METH_O, NULL },
-
- /* Miscellaneous */
- { "__copy__", (PyCFunction)context_copy, METH_NOARGS, NULL },
- { "__reduce__", context_reduce, METH_NOARGS, NULL },
- { "copy", (PyCFunction)context_copy, METH_NOARGS, doc_ctx_copy },
- { "create_decimal", PyDecContext_CreateDecimal, METH_VARARGS, doc_ctx_create_decimal },
- { "create_decimal_from_float", PyDecContext_FromFloat, METH_O, doc_ctx_create_decimal_from_float },
+ /* Unary arithmetic functions */
+ { "abs", _DecCtx_mpd_qabs, METH_O, doc_ctx_abs },
+ { "exp", _DecCtx_mpd_qexp, METH_O, doc_ctx_exp },
+ { "invroot", _DecCtx_mpd_qinvroot, METH_O, doc_ctx_invroot },
+ { "ln", _DecCtx_mpd_qln, METH_O, doc_ctx_ln },
+ { "log10", _DecCtx_mpd_qlog10, METH_O, doc_ctx_log10 },
+ { "minus", _DecCtx_mpd_qminus, METH_O, doc_ctx_minus },
+ { "next_minus", _DecCtx_mpd_qnext_minus, METH_O, doc_ctx_next_minus },
+ { "next_plus", _DecCtx_mpd_qnext_plus, METH_O, doc_ctx_next_plus },
+ { "normalize", _DecCtx_mpd_qreduce, METH_O, doc_ctx_normalize }, /* alias for reduce */
+ { "plus", _DecCtx_mpd_qplus, METH_O, doc_ctx_plus },
+ { "reduce", _DecCtx_mpd_qreduce, METH_O, doc_ctx_reduce },
+ { "to_integral", _DecCtx_mpd_qround_to_int, METH_O, doc_ctx_to_integral },
+ { "to_integral_exact", _DecCtx_mpd_qround_to_intx, METH_O, doc_ctx_to_integral_exact },
+ { "to_integral_value", _DecCtx_mpd_qround_to_int, METH_O, doc_ctx_to_integral_value },
+ { "sqrt", _DecCtx_mpd_qsqrt, METH_O, doc_ctx_sqrt },
+
+ /* Binary arithmetic functions */
+ { "add", _DecCtx_mpd_qadd, METH_VARARGS, doc_ctx_add },
+ { "compare", _DecCtx_mpd_qcompare, METH_VARARGS, doc_ctx_compare },
+ { "compare_signal", _DecCtx_mpd_qcompare_signal, METH_VARARGS, doc_ctx_compare_signal },
+ { "div", _DecCtx_mpd_qdiv, METH_VARARGS, doc_ctx_div }, /* alias for divide */
+ { "divide", _DecCtx_mpd_qdiv, METH_VARARGS, doc_ctx_divide },
+ { "divide_int", _DecCtx_mpd_qdivint, METH_VARARGS, doc_ctx_divide_int },
+ { "divint", _DecCtx_mpd_qdivint, METH_VARARGS, doc_ctx_divint }, /* alias for divide_int */
+ { "divmod", _DecCtx_mpd_qdivmod, METH_VARARGS, doc_ctx_divmod },
+ { "max", _DecCtx_mpd_qmax, METH_VARARGS, doc_ctx_max },
+ { "max_mag", _DecCtx_mpd_qmax_mag, METH_VARARGS, doc_ctx_max_mag },
+ { "min", _DecCtx_mpd_qmin, METH_VARARGS, doc_ctx_min },
+ { "min_mag", _DecCtx_mpd_qmin_mag, METH_VARARGS, doc_ctx_min_mag },
+ { "mul", _DecCtx_mpd_qmul, METH_VARARGS, doc_ctx_mul }, /* alias for multiply */
+ { "multiply", _DecCtx_mpd_qmul, METH_VARARGS, doc_ctx_multiply },
+ { "next_toward", _DecCtx_mpd_qnext_toward, METH_VARARGS, doc_ctx_next_toward },
+ { "pow", _DecCtx_mpd_qpow, METH_VARARGS, doc_ctx_pow }, /* alias for power */
+ { "power", _DecCtx_mpd_qpow, METH_VARARGS, doc_ctx_power },
+ { "quantize", _DecCtx_mpd_qquantize, METH_VARARGS, doc_ctx_quantize },
+ { "rem", _DecCtx_mpd_qrem, METH_VARARGS, doc_ctx_rem }, /* alias for remainder */
+ { "remainder", _DecCtx_mpd_qrem, METH_VARARGS, doc_ctx_remainder },
+ { "remainder_near", _DecCtx_mpd_qrem_near, METH_VARARGS, doc_ctx_remainder_near },
+ { "sub", _DecCtx_mpd_qsub, METH_VARARGS, doc_ctx_sub }, /* alias for subtract */
+ { "subtract", _DecCtx_mpd_qsub, METH_VARARGS, doc_ctx_subtract },
+
+ /* Ternary arithmetic functions */
+ { "fma", _DecCtx_mpd_qfma, METH_VARARGS, doc_ctx_fma },
+ { "powmod", _DecCtx_mpd_qpowmod, METH_VARARGS, doc_ctx_powmod },
+
+ /* No argument */
+ { "Etiny", context_getetiny, METH_NOARGS, doc_ctx_Etiny },
+ { "Etop", context_getetop, METH_NOARGS, doc_ctx_Etop },
+ { "radix", _DecCtx_mpd_radix, METH_NOARGS, doc_ctx_radix },
+
+ /* Boolean functions */
+ { "is_canonical", _DecCtx_iscanonical, METH_O, doc_ctx_is_canonical },
+ { "is_finite", _DecCtx_mpd_isfinite, METH_O, doc_ctx_is_finite },
+ { "is_infinite", _DecCtx_mpd_isinfinite, METH_O, doc_ctx_is_infinite },
+ { "is_nan", _DecCtx_mpd_isnan, METH_O, doc_ctx_is_nan },
+ { "is_normal", _DecCtx_mpd_isnormal, METH_O, doc_ctx_is_normal },
+ { "is_qnan", _DecCtx_mpd_isqnan, METH_O, doc_ctx_is_qnan },
+ { "is_signed", _DecCtx_mpd_issigned, METH_O, doc_ctx_is_signed },
+ { "is_snan", _DecCtx_mpd_issnan, METH_O, doc_ctx_is_snan },
+ { "is_subnormal", _DecCtx_mpd_issubnormal, METH_O, doc_ctx_is_subnormal },
+ { "is_zero", _DecCtx_mpd_iszero, METH_O, doc_ctx_is_zero },
+
+ /* Functions with a single decimal argument */
+ { "_apply", PyDecContext_Apply, METH_O, NULL }, /* alias for apply */
+ { "apply", PyDecContext_Apply, METH_O, doc_ctx_apply },
+ { "canonical", _DecCtx_canonical, METH_O, doc_ctx_canonical },
+ { "copy_abs", _DecCtx_mpd_qcopy_abs, METH_O, doc_ctx_copy_abs },
+ { "copy_decimal", _DecCtx_copy_decimal, METH_O, doc_ctx_copy_decimal },
+ { "copy_negate", _DecCtx_mpd_qcopy_negate, METH_O, doc_ctx_copy_negate },
+ { "logb", _DecCtx_mpd_qlogb, METH_O, doc_ctx_logb },
+ { "logical_invert", _DecCtx_mpd_qinvert, METH_O, doc_ctx_logical_invert },
+ { "number_class", _DecCtx_mpd_class, METH_O, doc_ctx_number_class },
+ { "to_sci", _DecCtx_mpd_to_sci, METH_O, doc_ctx_to_sci }, /* alias for to_sci_string */
+ { "to_sci_string", _DecCtx_mpd_to_sci, METH_O, doc_ctx_to_sci_string },
+ { "to_eng", _DecCtx_mpd_to_eng, METH_O, doc_ctx_to_eng }, /* alias for to_eng_string */
+ { "to_eng_string", _DecCtx_mpd_to_eng, METH_O, doc_ctx_to_eng_string },
+
+ /* Functions with two decimal arguments */
+ { "compare_total", _DecCtx_mpd_compare_total, METH_VARARGS, doc_ctx_compare_total },
+ { "compare_total_mag", _DecCtx_mpd_compare_total_mag, METH_VARARGS, doc_ctx_compare_total_mag },
+ { "copy_sign", _DecCtx_mpd_qcopy_sign, METH_VARARGS, doc_ctx_copy_sign },
+ { "logical_and", _DecCtx_mpd_qand, METH_VARARGS, doc_ctx_logical_and },
+ { "logical_or", _DecCtx_mpd_qor, METH_VARARGS, doc_ctx_logical_or },
+ { "logical_xor", _DecCtx_mpd_qxor, METH_VARARGS, doc_ctx_logical_xor },
+ { "rotate", _DecCtx_mpd_qrotate, METH_VARARGS, doc_ctx_rotate },
+ { "same_quantum", _DecCtx_mpd_same_quantum, METH_VARARGS, doc_ctx_same_quantum },
+ { "scaleb", _DecCtx_mpd_qscaleb, METH_VARARGS, doc_ctx_scaleb },
+ { "shift", _DecCtx_mpd_qshift, METH_VARARGS, doc_ctx_shift },
+
+ /* Set context values */
+ { "setflags", PyDec_SetStatusFromList, METH_O, doc_ctx_setflags },
+ { "settraps", PyDec_SetTrapsFromList, METH_O, doc_ctx_settraps },
+ { "clear_flags", context_clear_flags, METH_NOARGS, doc_ctx_clear_flags },
+ { "clear_traps", context_clear_traps, METH_NOARGS, doc_ctx_clear_traps },
+
+ /* Unsafe set functions with no range checks */
+ { "unsafe_setprec", context_unsafe_setprec, METH_O, NULL },
+ { "unsafe_setemin", context_unsafe_setemin, METH_O, NULL },
+ { "unsafe_setemax", context_unsafe_setemax, METH_O, NULL },
+
+ /* Miscellaneous */
+ { "__copy__", (PyCFunction)context_copy, METH_NOARGS, NULL },
+ { "__reduce__", context_reduce, METH_NOARGS, NULL },
+ { "copy", (PyCFunction)context_copy, METH_NOARGS, doc_ctx_copy },
+ { "create_decimal", PyDecContext_CreateDecimal, METH_VARARGS, doc_ctx_create_decimal },
+ { "create_decimal_from_float", PyDecContext_FromFloat, METH_O, doc_ctx_create_decimal_from_float },
- { NULL, NULL, 1 }
+ { NULL, NULL, 1 }
};
static PyTypeObject PyDecContext_Type =
@@ -4807,11 +5006,11 @@
static PyMethodDef cdecimal_methods [] =
{
- { "getcontext", (PyCFunction)PyDec_GetCurrentContext, METH_NOARGS, doc_getcontext},
- { "setcontext", (PyCFunction)PyDec_SetCurrentContext, METH_O, doc_setcontext},
- { "localcontext", (PyCFunction)ctxmanager_new, METH_VARARGS, doc_localcontext},
- { "IEEEContext", (PyCFunction)ieee_context, METH_O, doc_ieee_context},
- { NULL, NULL, 1, NULL }
+ { "getcontext", (PyCFunction)PyDec_GetCurrentContext, METH_NOARGS, doc_getcontext},
+ { "setcontext", (PyCFunction)PyDec_SetCurrentContext, METH_O, doc_setcontext},
+ { "localcontext", (PyCFunction)ctxmanager_new, METH_VARARGS, doc_localcontext},
+ { "IEEEContext", (PyCFunction)ieee_context, METH_O, doc_ieee_context},
+ { NULL, NULL, 1, NULL }
};
static struct PyModuleDef cdecimal_module = {
@@ -4845,56 +5044,56 @@
if (PyType_Ready(&PyDec_Type) < 0) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
if (PyType_Ready(&PyDecContext_Type) < 0) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
if (PyType_Ready(&PyDecSignalDict_Type) < 0) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
if (PyType_Ready(&PyDecContextManager_Type) < 0) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
if ((obj = PyUnicode_FromString("cdecimal")) == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
if (PyDict_SetItemString(PyDec_Type.tp_dict, "__module__", obj) < 0) {
- Py_DECREF(obj);
- goto error;
+ Py_DECREF(obj); /* GCOV_UNLIKELY */
+ goto error; /* GCOV_UNLIKELY */
}
if (PyDict_SetItemString(PyDecContext_Type.tp_dict, "__module__", obj) < 0) {
- Py_DECREF(obj);
- goto error;
+ Py_DECREF(obj); /* GCOV_UNLIKELY */
+ goto error; /* GCOV_UNLIKELY */
}
Py_DECREF(obj);
if ((_numbers = PyImport_ImportModule("numbers")) == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
if ((_Number = PyObject_GetAttrString(_numbers, "Number")) == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
if ((obj = Py_BuildValue("O", &PyDec_Type)) == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
if ((s = Py_BuildValue("s", "register")) == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
if ((ret = PyObject_CallMethodObjArgs(_Number, s, obj, NULL)) == NULL) {
- Py_DECREF(s);
- Py_DECREF(obj);
- goto error;
+ Py_DECREF(s); /* GCOV_UNLIKELY */
+ Py_DECREF(obj); /* GCOV_UNLIKELY */
+ goto error; /* GCOV_UNLIKELY */
}
Py_DECREF(s);
Py_DECREF(obj);
Py_DECREF(ret);
if ((m = PyModule_Create(&cdecimal_module)) == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
mpd_traphandler = dec_traphandler;
@@ -4946,7 +5145,7 @@
/* Default context template */
ctxobj = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
if (ctxobj == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
default_context_template = ctxobj;
Py_INCREF(ctxobj);
@@ -4956,14 +5155,14 @@
/* Module context */
ctxobj = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
if (ctxobj == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
module_context = ctxobj;
PyModule_AddIntConstant(m, "HAVE_THREADS", 0);
#else
tls_context_key = Py_BuildValue("s", "__CDECIMAL_CTX__");
if (tls_context_key == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
PyModule_AddIntConstant(m, "HAVE_THREADS", 1);
#endif
@@ -4971,7 +5170,7 @@
/* Basic context template */
ctxobj = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
if (ctxobj == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
init_basic_context(ctxobj);
basic_context_template = ctxobj;
@@ -4981,7 +5180,7 @@
/* Extended context template */
ctxobj = PyObject_CallObject((PyObject *)&PyDecContext_Type, NULL);
if (ctxobj == NULL) {
- goto error;
+ goto error; /* GCOV_UNLIKELY */
}
init_extended_context(ctxobj);
extended_context_template = ctxobj;
@@ -5022,7 +5221,7 @@
PyModule_AddIntConstant(m, "DecInvalidOperation", MPD_Invalid_operation);
PyModule_AddIntConstant(m, "DecIEEEInvalidOperation", MPD_IEEE_Invalid_operation);
PyModule_AddIntConstant(m, "DecMallocError", MPD_Malloc_error);
- PyModule_AddIntConstant(m, "DecNotImplemented", MPD_Not_implemented);
+ PyModule_AddIntConstant(m, "DecFloatOperation", MPD_Float_operation);
PyModule_AddIntConstant(m, "DecOverflow", MPD_Overflow);
PyModule_AddIntConstant(m, "DecRounded", MPD_Rounded);
PyModule_AddIntConstant(m, "DecSubnormal", MPD_Subnormal);
@@ -5033,20 +5232,20 @@
return m;
-error:
- if (_numbers) Py_DECREF(_numbers);
- if (_Number) Py_DECREF(_Number);
+error: /* GCOV_UNLIKELY */
+ if (_numbers) Py_DECREF(_numbers); /* GCOV_UNLIKELY */
+ if (_Number) Py_DECREF(_Number); /* GCOV_UNLIKELY */
#ifdef WITHOUT_THREADS
- if (module_context) Py_DECREF(module_context);
+ if (module_context) Py_DECREF(module_context); /* GCOV_UNLIKELY */
#else
- if (default_context_template) Py_DECREF(default_context_template);
- if (tls_context_key) Py_DECREF(tls_context_key);
+ if (default_context_template) Py_DECREF(default_context_template); /* GCOV_UNLIKELY */
+ if (tls_context_key) Py_DECREF(tls_context_key); /* GCOV_UNLIKELY */
#endif
- if (basic_context_template) Py_DECREF(basic_context_template);
- if (extended_context_template) Py_DECREF(extended_context_template);
- if (m) Py_DECREF(m);
+ if (basic_context_template) Py_DECREF(basic_context_template); /* GCOV_UNLIKELY */
+ if (extended_context_template) Py_DECREF(extended_context_template); /* GCOV_UNLIKELY */
+ if (m) Py_DECREF(m); /* GCOV_UNLIKELY */
- return NULL;
+ return NULL; /* GCOV_UNLIKELY */
}
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/constants.h
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/constants.h (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/constants.h Mon Nov 8 15:12:49 2010
@@ -20,14 +20,6 @@
#define POWMOD(base, exp) x64_powmod(base, exp, umod)
#define SETMODULUS(modnum) std_setmodulus(modnum, &umod)
#define SIZE3_NTT(x0, x1, x2, w3table) std_size3_ntt(x0, x1, x2, w3table, umod)
-
- #if defined(__x86_64__)
- #define BSR(a) x86_bsr(a)
- #define BSF(a) x86_bsf(a)
- #else
- #define BSR(a) std_bsr(a)
- #define BSF(a) std_bsf(a)
- #endif
#elif defined(PPRO)
/* PentiumPro (or later) gcc inline asm */
#define MULMOD(a, b) ppro_mulmod(a, b, &dmod, dinvmod)
@@ -36,9 +28,6 @@
#define POWMOD(base, exp) ppro_powmod(base, exp, &dmod, dinvmod)
#define SETMODULUS(modnum) ppro_setmodulus(modnum, &umod, &dmod, dinvmod)
#define SIZE3_NTT(x0, x1, x2, w3table) ppro_size3_ntt(x0, x1, x2, w3table, umod, &dmod, dinvmod)
-
- #define BSR(a) x86_bsr(a)
- #define BSF(a) x86_bsf(a)
#else
/* ANSI C99 */
#define MULMOD(a, b) std_mulmod(a, b, umod)
@@ -47,9 +36,6 @@
#define POWMOD(base, exp) std_powmod(base, exp, umod)
#define SETMODULUS(modnum) std_setmodulus(modnum, &umod)
#define SIZE3_NTT(x0, x1, x2, w3table) std_size3_ntt(x0, x1, x2, w3table, umod)
-
- #define BSR(a) std_bsr(a)
- #define BSF(a) std_bsf(a)
#endif
/* PentiumPro (or later) gcc inline asm */
@@ -57,7 +43,6 @@
extern const uint32_t mpd_invmoduli[3][3];
enum {P1, P2, P3};
-enum {UNORDERED, ORDERED};
extern const mpd_uint_t mpd_moduli[];
extern const mpd_uint_t mpd_roots[];
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/context.c
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/context.c (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/context.c Mon Nov 8 15:12:49 2010
@@ -10,7 +10,7 @@
#include <signal.h>
-static void
+void
mpd_dflt_traphandler(mpd_context_t *ctx UNUSED)
{
raise(SIGFPE);
@@ -30,7 +30,7 @@
return;
}
if (n < MPD_MINALLOC_MIN || n > MPD_MINALLOC_MAX) {
- mpd_err_fatal("illegal value for MPD_MINALLOC");
+ mpd_err_fatal("illegal value for MPD_MINALLOC"); /* GCOV_NOT_REACHED */
}
MPD_MINALLOC = n;
minalloc_is_set = 1;
@@ -70,6 +70,20 @@
}
void
+mpd_maxcontext_plus(mpd_context_t *workctx, const mpd_context_t *ctx)
+{
+ workctx->prec = ctx->prec > MPD_MAX_PREC ? ctx->prec : MPD_MAX_PREC;
+ workctx->emax = ctx->emax > MPD_MAX_EMAX ? ctx->emax : MPD_MAX_EMAX;
+ workctx->emin = ctx->emin < MPD_MIN_EMIN ? ctx->emin : MPD_MIN_EMIN;
+ workctx->round=MPD_ROUND_HALF_EVEN;
+ workctx->traps=MPD_Traps;
+ workctx->status=0;
+ workctx->newtrap=0;
+ workctx->clamp=0;
+ workctx->allcr=1;
+}
+
+void
mpd_defaultcontext(mpd_context_t *ctx)
{
ctx->prec=2*MPD_RDIGITS;
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/convolute.c
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/convolute.c (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/convolute.c Mon Nov 8 15:12:49 2010
@@ -20,8 +20,8 @@
int
fnt_convolute(mpd_uint_t *c1, mpd_uint_t *c2, mpd_size_t n, int modnum)
{
- int (*fnt)(mpd_uint_t *, mpd_size_t, int, int);
- int (*inv_fnt)(mpd_uint_t *, mpd_size_t, int, int);
+ int (*fnt)(mpd_uint_t *, mpd_size_t, int);
+ int (*inv_fnt)(mpd_uint_t *, mpd_size_t, int);
#ifdef PPRO
double dmod;
uint32_t dinvmod[3];
@@ -48,10 +48,10 @@
inv_fnt = inv_four_step_fnt;
}
- if (!fnt(c1, n, modnum, UNORDERED)) {
+ if (!fnt(c1, n, modnum)) {
return 0;
}
- if (!fnt(c2, n, modnum, UNORDERED)) {
+ if (!fnt(c2, n, modnum)) {
return 0;
}
for (i = 0; i < n-1; i += 2) {
@@ -64,7 +64,7 @@
c1[i+1] = x1;
}
- if (!inv_fnt(c1, n, modnum, UNORDERED)) {
+ if (!inv_fnt(c1, n, modnum)) {
return 0;
}
for (i = 0; i < n-3; i += 4) {
@@ -87,8 +87,8 @@
int
fnt_autoconvolute(mpd_uint_t *c1, mpd_size_t n, int modnum)
{
- int (*fnt)(mpd_uint_t *, mpd_size_t, int, int);
- int (*inv_fnt)(mpd_uint_t *, mpd_size_t, int, int);
+ int (*fnt)(mpd_uint_t *, mpd_size_t, int);
+ int (*inv_fnt)(mpd_uint_t *, mpd_size_t, int);
#ifdef PPRO
double dmod;
uint32_t dinvmod[3];
@@ -115,7 +115,7 @@
inv_fnt = inv_four_step_fnt;
}
- if (!fnt(c1, n, modnum, UNORDERED)) {
+ if (!fnt(c1, n, modnum)) {
return 0;
}
for (i = 0; i < n-1; i += 2) {
@@ -126,7 +126,7 @@
c1[i+1] = x1;
}
- if (!inv_fnt(c1, n, modnum, UNORDERED)) {
+ if (!inv_fnt(c1, n, modnum)) {
return 0;
}
for (i = 0; i < n-3; i += 4) {
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/crt.c
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/crt.c (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/crt.c Mon Nov 8 15:12:49 2010
@@ -63,7 +63,7 @@
w[2] = 0;
}
else {
- _mpd_div_word(&w[2], &r1, u[2], v);
+ _mpd_div_word(&w[2], &r1, u[2], v); /* GCOV_NOT_REACHED */
}
_mpd_div_words(&w[1], &r2, r1, u[1], v);
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/difradix2.c
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/difradix2.c (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/difradix2.c Mon Nov 8 15:12:49 2010
@@ -32,7 +32,7 @@
a[r] = t;
}
x += 1;
- r ^= (n - (n >> (BSF(x)+1)));
+ r ^= (n - (n >> (mpd_bsf(x)+1)));
} while (x < n);
}
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/error.c
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/error.c (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/error.c Mon Nov 8 15:12:49 2010
@@ -19,7 +19,7 @@
va_end(ap);
if (action == MPD_ERR_EXIT) {
- exit(EXIT_FAILURE);
+ exit(EXIT_FAILURE); /* GCOV_NOT_REACHED */
}
}
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/fnt.c
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/fnt.c (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/fnt.c Mon Nov 8 15:12:49 2010
@@ -16,7 +16,7 @@
/* forward transform, sign = -1 */
int
-std_fnt(mpd_uint_t *a, mpd_size_t n, int modnum, int ordered UNUSED)
+std_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
{
struct fnt_params *tparams;
@@ -35,7 +35,7 @@
/* reverse transform, sign = 1 */
int
-std_inv_fnt(mpd_uint_t *a, mpd_size_t n, int modnum, int ordered UNUSED)
+std_inv_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
{
struct fnt_params *tparams;
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/fnt.h
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/fnt.h (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/fnt.h Mon Nov 8 15:12:49 2010
@@ -12,8 +12,8 @@
#include <stdio.h>
-int std_fnt(mpd_uint_t a[], mpd_size_t n, int modnum, int ordered UNUSED);
-int std_inv_fnt(mpd_uint_t a[], mpd_size_t n, int modnum, int ordered UNUSED);
+int std_fnt(mpd_uint_t a[], mpd_size_t n, int modnum);
+int std_inv_fnt(mpd_uint_t a[], mpd_size_t n, int modnum);
#endif
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/fourstep.c
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/fourstep.c (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/fourstep.c Mon Nov 8 15:12:49 2010
@@ -118,7 +118,7 @@
/* forward transform, sign = -1; transform length = 3 * 2^n */
int
-four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum, int ordered)
+four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
{
mpd_size_t R = 3; /* number of rows */
mpd_size_t C = n / 3; /* number of columns */
@@ -163,21 +163,24 @@
/* transform rows */
for (s = a; s < a+n; s += C) {
- if (!six_step_fnt(s, C, modnum, ordered)) {
+ if (!six_step_fnt(s, C, modnum)) {
return 0;
}
}
+#if 0
+ /* An unordered transform is sufficient for convolution. */
if (ordered) {
transpose_3xpow2(a, R, C);
}
+#endif
return 1;
}
/* backward transform, sign = 1; transform length = 3 * 2^n */
int
-inv_four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum, int ordered)
+inv_four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
{
mpd_size_t R = 3; /* number of rows */
mpd_size_t C = n / 3; /* number of columns */
@@ -196,13 +199,16 @@
assert(n <= 3*MPD_MAXTRANSFORM_2N);
+#if 0
+ /* An unordered transform is sufficient for convolution. */
if (ordered) {
transpose_3xpow2(a, C, R);
}
+#endif
/* transform rows */
for (s = a; s < a+n; s += C) {
- if (!inv_six_step_fnt(s, C, modnum, ordered)) {
+ if (!inv_six_step_fnt(s, C, modnum)) {
return 0;
}
}
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/fourstep.h
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/fourstep.h (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/fourstep.h Mon Nov 8 15:12:49 2010
@@ -12,8 +12,8 @@
#include <stdio.h>
-int four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum, int ordered);
-int inv_four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum, int ordered);
+int four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum);
+int inv_four_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum);
#endif
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/io.c
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/io.c (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/io.c Mon Nov 8 15:12:49 2010
@@ -161,13 +161,13 @@
mpd_qset_string(mpd_t *dec, const char *s, const mpd_context_t *ctx,
uint32_t *status)
{
- mpd_ssize_t q, r, declen;
+ mpd_ssize_t q, r, len;
const char *coeff, *end;
const char *dpoint = NULL, *exp = NULL;
- size_t len;
+ size_t digits;
uint8_t sign = MPD_POS;
- dec->flags = 0;
+ mpd_set_flags(dec, 0);
dec->len = 0;
dec->exp = 0;
@@ -192,9 +192,9 @@
/* payload consists entirely of zeros */
if (*coeff == '\0')
return;
- len = end - coeff;
+ digits = end - coeff;
/* prec >= 1, clamp is 0 or 1 */
- if (len > (size_t)(ctx->prec-ctx->clamp))
+ if (digits > (size_t)(ctx->prec-ctx->clamp))
goto conversion_error;
} /* sNaN */
else if (_mpd_strneq(s, "snan", "SNAN", 4)) {
@@ -208,8 +208,8 @@
/* payload consists entirely of zeros */
if (*coeff == '\0')
return;
- len = end - coeff;
- if (len > (size_t)(ctx->prec-ctx->clamp))
+ digits = end - coeff;
+ if (digits > (size_t)(ctx->prec-ctx->clamp))
goto conversion_error;
}
else if (_mpd_strneq(s, "inf", "INF", 3)) {
@@ -231,39 +231,50 @@
/* exponent-part */
end = exp; exp++;
dec->exp = strtoexp(exp);
- if (errno == EINVAL)
- goto conversion_error;
- if ((errno == ERANGE && dec->exp == MPD_SSIZE_MAX)
- || dec->exp > MPD_EXP_INF)
- dec->exp = MPD_EXP_INF;
- else if ((errno == ERANGE && dec->exp == MPD_SSIZE_MIN)
- || dec->exp < MPD_EXP_CLAMP)
- dec->exp = MPD_EXP_CLAMP;
+ if (errno) {
+ if (!(errno == ERANGE &&
+ (dec->exp == MPD_SSIZE_MAX ||
+ dec->exp == MPD_SSIZE_MIN)))
+ goto conversion_error;
+ }
}
- len = end - coeff;
+ digits = end - coeff;
if (dpoint) {
- dec->exp -= (end-dpoint-1);
- if (dpoint > coeff) len--;
+ size_t fracdigits = end-dpoint-1;
+ if (dpoint > coeff) digits--;
+
+ if (fracdigits > MPD_MAX_PREC) {
+ goto conversion_error;
+ }
+ if (dec->exp < (MPD_SSIZE_MIN+1)+(mpd_ssize_t)fracdigits) {
+ dec->exp = MPD_SSIZE_MIN+1;
+ }
+ else {
+ dec->exp -= (mpd_ssize_t)fracdigits;
+ }
}
- if (len > MPD_MAX_PREC) {
+ if (digits > MPD_MAX_PREC) {
goto conversion_error;
}
+ if (dec->exp > MPD_EXP_INF) {
+ dec->exp = MPD_EXP_INF;
+ }
}
- _mpd_idiv_word(&q, &r, (mpd_ssize_t)len, MPD_RDIGITS);
+ _mpd_idiv_word(&q, &r, (mpd_ssize_t)digits, MPD_RDIGITS);
- declen = (r == 0) ? q : q+1;
- if (declen == 0) {
- goto conversion_error;
+ len = (r == 0) ? q : q+1;
+ if (len == 0) {
+ goto conversion_error; /* GCOV_NOT_REACHED */
}
- if (!mpd_qresize(dec, declen, status)) {
+ if (!mpd_qresize(dec, len, status)) {
mpd_seterror(dec, MPD_Malloc_error, status);
return;
}
- dec->len = declen;
+ dec->len = len;
- string_to_coeff(dec->data, coeff, dpoint, (int)r, declen);
+ string_to_coeff(dec->data, coeff, dpoint, (int)r, len);
mpd_setdigits(dec);
mpd_qfinalize(dec, ctx, status);
@@ -440,7 +451,7 @@
cp += 8;
}
else { /* debug */
- abort();
+ abort(); /* GCOV_NOT_REACHED */
}
}
else {
@@ -859,15 +870,16 @@
int pad = 0;
n_sign = sign ? 1 : 0;
- n_sep = strlen(spec->sep);
+ n_sep = (mpd_ssize_t)strlen(spec->sep);
g = spec->grouping;
dest->cur = dest->nbytes;
dest->nbytes = dest->nchars = 0;
- _mbstr_copy_ascii(dest, rest, strlen(rest));
+ /* rest <= MPD_MAX_PREC */
+ _mbstr_copy_ascii(dest, rest, (mpd_ssize_t)strlen(rest));
if (dot) {
- _mbstr_copy_char(dest, dot, strlen(dot));
+ _mbstr_copy_char(dest, dot, (mpd_ssize_t)strlen(dot));
}
consume = *g;
@@ -920,7 +932,7 @@
const char *sign = NULL, *intpart = NULL;
const char *dot = NULL, *rest = NULL;
const char *dp;
- size_t n_int;
+ mpd_ssize_t n_int;
assert(result->data == NULL);
@@ -935,14 +947,14 @@
while (isdigit((uchar)*dp)) {
dp++;
}
- n_int = dp-intpart;
+ n_int = (mpd_ssize_t)(dp-intpart);
}
if (*dp == '.') {
if (*spec->dot == '\0') {
/* decimal point must be present */
- *status |= MPD_Invalid_operation;
- mpd_free(decstring);
- return;
+ *status |= MPD_Invalid_operation; /* GCOV_NOT_REACHED */
+ mpd_free(decstring); /* GCOV_NOT_REACHED */
+ return; /* GCOV_NOT_REACHED */
}
dp++; dot = spec->dot;
}
@@ -951,7 +963,7 @@
if (!dot && !(intpart && *spec->sep && *spec->grouping)) {
result->data = decstring;
- result->nbytes = result->nchars = strlen(decstring);
+ result->nbytes = result->nchars = (mpd_ssize_t)strlen(decstring);
return;
}
@@ -976,16 +988,16 @@
_mpd_add_pad(mpd_mbstr_t *result, mpd_spec_t *spec, uint32_t *status)
{
if (result->nchars < spec->min_width) {
+ mpd_ssize_t add_chars, add_bytes;
size_t lpad = 0, rpad = 0;
- size_t add_chars, add_bytes, n_fill;
- size_t len, i, j;
+ size_t n_fill, len, i, j;
uint8_t err = 0;
char *cp;
n_fill = strlen(spec->fill);
add_chars = (spec->min_width - result->nchars);
/* max value: MPD_MAX_PREC * 4 */
- add_bytes = add_chars * n_fill;
+ add_bytes = add_chars * (mpd_ssize_t)n_fill;
cp = result->data = mpd_realloc(result->data,
result->nbytes+add_bytes+1,
@@ -993,6 +1005,7 @@
if (err) {
*status |= MPD_Malloc_error;
mpd_free(result->data);
+ result->data = NULL;
return;
}
@@ -1057,6 +1070,7 @@
if (spec->min_width > MPD_MAX_PREC) {
+ *status |= MPD_Invalid_operation;
return NULL;
}
@@ -1081,7 +1095,7 @@
flags |= MPD_FMT_SIGN_PLUS;
}
- mpd_maxcontext(&workctx);
+ mpd_maxcontext_plus(&workctx, ctx);
workctx.round = ctx->round;
if (mpd_isspecial(&tmp)) {
/* no percent formatting */
@@ -1148,7 +1162,8 @@
if (spec->min_width) {
if (result.nbytes == 0) {
- result.nbytes = result.nchars = strlen(result.data);
+ result.nbytes = result.nchars =
+ (mpd_ssize_t)strlen(result.data);
}
_mpd_add_pad(&result, spec, status);
}
@@ -1328,6 +1343,7 @@
return (int)(cp-dest); /* strlen, without NUL terminator */
}
+/* The following two functions are mainly intended for debugging. */
void
mpd_fprint(FILE *file, const mpd_t *dec)
{
@@ -1339,7 +1355,7 @@
mpd_free(decstring);
}
else {
- fputs("mpd_fprint: output error\n", file);
+ fputs("mpd_fprint: output error\n", file); /* GCOV_NOT_REACHED */
}
}
@@ -1354,7 +1370,7 @@
mpd_free(decstring);
}
else {
- fputs("mpd_fprint: output error", stderr);
+ fputs("mpd_fprint: output error\n", stderr); /* GCOV_NOT_REACHED */
}
}
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/memory.c
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/memory.c (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/memory.c Mon Nov 8 15:12:49 2010
@@ -19,6 +19,7 @@
void (* mpd_free)(void *ptr) = free;
+
/* emulate calloc if it is not available */
void *
mpd_callocfunc_em(size_t nmemb, size_t size)
@@ -27,11 +28,11 @@
size_t req;
#if MPD_SIZE_MAX < SIZE_MAX
- if (size > MPD_SIZE_MAX) {
+ if (nmemb > MPD_SIZE_MAX || size > MPD_SIZE_MAX) {
return NULL;
}
#endif
- req = mul_size_t(nmemb, size);
+ req = mul_size_t((mpd_size_t)nmemb, (mpd_size_t)size);
if ((ptr = mpd_mallocfunc(req)) == NULL) {
return NULL;
}
@@ -102,40 +103,6 @@
return ptr;
}
-/* mpd_callocfunc must have overflow checking */
-void *
-mpd_sh_calloc(mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size)
-{
- void *ptr;
- mpd_size_t req;
-
- req = mul_size_t(nmemb, size);
- req = add_size_t(req, struct_size);
- if ((ptr = mpd_callocfunc(req, 1)) == NULL) {
- return NULL;
- }
-
- return ptr;
-}
-
-/* struct hack realloc with overflow checking */
-void *
-mpd_sh_realloc(void *ptr, mpd_size_t struct_size, mpd_size_t nmemb,
- mpd_size_t size, uint8_t *err)
-{
- void *new;
- mpd_size_t req;
-
- req = mul_size_t(nmemb, size);
- req = add_size_t(req, struct_size);
- if ((new = mpd_reallocfunc(ptr, req)) == NULL) {
- *err = 1;
- return ptr;
- }
-
- return new;
-}
-
/* Allocate a new decimal with data-size 'size'.
* In case of an error the return value is NULL.
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal.c Mon Nov 8 15:12:49 2010
@@ -32,16 +32,21 @@
#endif
#endif
-#if defined(__GLIBC__) && !defined(__INTEL_COMPILER)
- #define HAVE_80BIT_LONG_DOUBLE
+#if defined(__x86_64__) && defined(__GLIBC__) && !defined(__INTEL_COMPILER)
+ #define USE_80BIT_LONG_DOUBLE
#endif
#if defined(_MSC_VER)
#define ALWAYS_INLINE __forceinline
#else
- #define ALWAYS_INLINE inline __attribute__ ((always_inline))
+ #ifdef TEST_COVERAGE
+ #define ALWAYS_INLINE
+ #else
+ #define ALWAYS_INLINE inline __attribute__ ((always_inline))
+ #endif
#endif
+
#define MPD_NEWTONDIV_CUTOFF 1024L
#define MPD_NEW_STATIC(name, flags, exp, digits, len) \
@@ -81,7 +86,7 @@
static inline void _mpd_qpow_uint(mpd_t *result, mpd_t *base, mpd_uint_t exp,
uint8_t resultsign, const mpd_context_t *ctx, uint32_t *status);
-static mpd_uint_t mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n);
+mpd_uint_t mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n);
/******************************************************************************/
@@ -152,7 +157,7 @@
ALWAYS_INLINE mpd_ssize_t
mpd_adjexp(const mpd_t *dec)
{
- return dec->exp + dec->digits - 1;
+ return (dec->exp + dec->digits) - 1;
}
/* Etiny */
@@ -692,7 +697,7 @@
result->data[0] = 0;
}
-/* Set the coefficient to all nines. Does not raise. */
+/* Set the coefficient to all nines. */
void
mpd_qmaxcoeff(mpd_t *result, const mpd_context_t *ctx, uint32_t *status)
{
@@ -1108,7 +1113,7 @@
#ifdef CONFIG_32
/* set a decimal from a uint64_t */
static void
-_c32setu64(mpd_t *result, uint64_t u, uint32_t *status)
+_c32setu64(mpd_t *result, uint64_t u, uint8_t sign, uint32_t *status)
{
mpd_uint_t w[3];
uint64_t q;
@@ -1128,6 +1133,7 @@
result->data[i] = w[i];
}
+ mpd_set_sign(result, sign);
result->exp = 0;
result->len = len;
mpd_setdigits(result);
@@ -1137,7 +1143,7 @@
_c32_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx,
uint32_t *status)
{
- _c32setu64(result, a, status);
+ _c32setu64(result, a, MPD_POS, status);
mpd_qfinalize(result, ctx, status);
}
@@ -1161,8 +1167,7 @@
else {
u = a;
}
- _c32setu64(result, u, status);
- mpd_set_sign(result, sign);
+ _c32setu64(result, u, sign, status);
mpd_qfinalize(result, ctx, status);
}
#endif /* CONFIG_32 */
@@ -1199,8 +1204,8 @@
*
* If the operation is impossible, MPD_Invalid_operation is set.
*/
-mpd_uint_t
-mpd_qget_uint(const mpd_t *a, uint32_t *status)
+static mpd_uint_t
+_mpd_qget_uint(int use_sign, const mpd_t *a, uint32_t *status)
{
mpd_t tmp;
mpd_uint_t tmp_data[2];
@@ -1210,12 +1215,14 @@
*status |= MPD_Invalid_operation;
return MPD_UINT_MAX;
}
-
- assert(a->len > 0);
-
if (mpd_iszero(a)) {
return 0;
}
+ if (use_sign && mpd_isnegative(a)) {
+ *status |= MPD_Invalid_operation;
+ return MPD_UINT_MAX;
+ }
+
if (a->digits+a->exp > MPD_RDIGITS+1) {
*status |= MPD_Invalid_operation;
return MPD_UINT_MAX;
@@ -1252,6 +1259,26 @@
return lo;
}
+/*
+ * Sets Invalid_operation for:
+ * - specials
+ * - negative numbers (except negative zero)
+ * - non-integers
+ * - overflow
+ */
+mpd_uint_t
+mpd_qget_uint(const mpd_t *a, uint32_t *status)
+{
+ return _mpd_qget_uint(1, a, status);
+}
+
+/* Same as above, but gets the absolute value, i.e. the sign is ignored. */
+mpd_uint_t
+mpd_qabs_uint(const mpd_t *a, uint32_t *status)
+{
+ return _mpd_qget_uint(0, a, status);
+}
+
/* quietly get an mpd_ssize_t from a decimal */
mpd_ssize_t
mpd_qget_ssize(const mpd_t *a, uint32_t *status)
@@ -1259,7 +1286,7 @@
mpd_uint_t u;
int isneg;
- u = mpd_qget_uint(a, status);
+ u = mpd_qabs_uint(a, status);
if (*status&MPD_Invalid_operation) {
return MPD_SSIZE_MAX;
}
@@ -1421,7 +1448,7 @@
return (!(rnd == 0) && (ld == 0 || ld == 5));
default:
/* Without a valid context, further results will be undefined. */
- return 0;
+ return 0; /* GCOV_NOT_REACHED */
}
}
@@ -1558,7 +1585,7 @@
}
break;
default: /* debug */
- abort();
+ abort(); /* GCOV_NOT_REACHED */
}
*status |= MPD_Overflow|MPD_Inexact|MPD_Rounded;
@@ -1570,6 +1597,9 @@
(void)mpd_qshiftl(dec, dec, shift, status);
dec->exp -= shift;
*status |= MPD_Clamped;
+ if (adjexp < ctx->emin) {
+ *status |= MPD_Subnormal;
+ }
}
else if (adjexp < ctx->emin) {
@@ -1588,7 +1618,7 @@
if (dec->exp < etiny) {
/* At this point adjexp=exp+digits-1 < emin and exp < etiny=emin-prec+1,
* so shift=emin-prec+1-exp > digits-prec, so digits-shift < prec.
- * [acl2 proof: checkexp-1] */
+ * [ACL2 proof: checkexp-1] */
shift = etiny - dec->exp;
rnd = (int)mpd_qshiftr_inplace(dec, shift);
dec->exp = etiny;
@@ -1680,7 +1710,6 @@
/*
* Copy a decimal. In case of an error, status is set to MPD_Malloc_error.
- * Does not raise.
*/
int
mpd_qcopy(mpd_t *result, const mpd_t *a, uint32_t *status)
@@ -1720,7 +1749,6 @@
/*
* Return a newly allocated copy of the operand. In case of an error,
* status is set to MPD_Malloc_error and the return value is NULL.
- * Does not raise.
*/
mpd_t *
mpd_qncopy(const mpd_t *a)
@@ -2174,8 +2202,7 @@
assert(n >= 0);
if (mpd_iszerocoeff(a) || n == 0) {
- mpd_qcopy(result, a, status);
- return 1;
+ return mpd_qcopy(result, a, status);
}
size = mpd_digits_to_size(a->digits+n);
@@ -2220,7 +2247,7 @@
* caller's responsibility to make sure that the array is big enough.
* The function cannot fail.
*/
-static mpd_uint_t
+mpd_uint_t
mpd_qsshiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n)
{
mpd_uint_t rnd;
@@ -2678,7 +2705,8 @@
if (a->digits > ctx->prec) {
if (!mpd_qcopy(&tmp, a, status)) {
- return;
+ mpd_seterror(result, MPD_Malloc_error, status);
+ goto finish;
}
_mpd_cap(&tmp, ctx);
a = &tmp;
@@ -2726,7 +2754,7 @@
return;
}
- n = mpd_qget_uint(b, &workstatus);
+ n = mpd_qabs_uint(b, &workstatus);
/* the spec demands this */
maxjump = 2 * (ctx->emax + ctx->prec);
@@ -3103,7 +3131,7 @@
_mpd_qsub(mpd_t *result, const mpd_t *a, const mpd_t *b,
const mpd_context_t *ctx, uint32_t *status)
{
- _mpd_qaddsub(result, a, b, !mpd_sign(b), ctx, status);
+ _mpd_qaddsub(result, a, b, !mpd_sign(b), ctx, status);
}
/* Add a and b. */
@@ -3234,6 +3262,40 @@
}
#endif
+/* Subtract int32_t from decimal. */
+void
+mpd_qsub_i32(mpd_t *result, const mpd_t *a, int32_t b,
+ const mpd_context_t *ctx, uint32_t *status)
+{
+ mpd_qsub_ssize(result, a, b, ctx, status);
+}
+
+/* Subtract uint32_t from decimal. */
+void
+mpd_qsub_u32(mpd_t *result, const mpd_t *a, uint32_t b,
+ const mpd_context_t *ctx, uint32_t *status)
+{
+ mpd_qsub_uint(result, a, b, ctx, status);
+}
+
+#ifdef CONFIG_64
+/* Subtract int64_t from decimal. */
+void
+mpd_qsub_i64(mpd_t *result, const mpd_t *a, int64_t b,
+ const mpd_context_t *ctx, uint32_t *status)
+{
+ mpd_qsub_ssize(result, a, b, ctx, status);
+}
+
+/* Subtract uint64_t from decimal. */
+void
+mpd_qsub_u64(mpd_t *result, const mpd_t *a, uint64_t b,
+ const mpd_context_t *ctx, uint32_t *status)
+{
+ mpd_qsub_uint(result, a, b, ctx, status);
+}
+#endif
+
/* Divide infinities. */
static void
@@ -3260,7 +3322,7 @@
const mpd_context_t *ctx, uint32_t *status)
{
MPD_NEW_STATIC(aligned,0,0,0,0);
- mpd_uint_t ld, carry = 0;
+ mpd_uint_t ld;
mpd_ssize_t shift, exp, tz;
mpd_ssize_t newsize;
mpd_ssize_t ideal_exp;
@@ -3338,6 +3400,10 @@
else {
MPD_NEW_STATIC(r,0,0,0,0);
_mpd_qbarrett_divmod(q, &r, a, b, status);
+ if (mpd_isspecial(q) || mpd_isspecial(&r)) {
+ mpd_del(&r);
+ goto finish;
+ }
rem = !mpd_iszerocoeff(&r);
mpd_del(&r);
newsize = q->len;
@@ -3353,14 +3419,7 @@
if (rem) {
ld = mpd_lsd(q->data[0]);
if (ld == 0 || ld == 5) {
- carry = _mpd_baseincr(q->data, q->len);
- if (carry) {
- if (!mpd_qresize(q, q->len+1, status)) {
- mpd_seterror(q, MPD_Malloc_error, status);
- goto finish;
- }
- q->data[q->len] = 1;
- }
+ q->data[0] += 1;
}
}
else if (action == SET_IDEAL_EXP && shift > 0) {
@@ -3402,7 +3461,7 @@
ideal_exp = (a->exp > b->exp) ? b->exp : a->exp;
if (mpd_iszerocoeff(a)) {
if (!mpd_qcopy(r, a, status)) {
- goto nanresult;
+ goto nanresult; /* GCOV_NOT_REACHED */
}
r->exp = ideal_exp;
_settriple(q, sign_ab, 0, 0);
@@ -3493,6 +3552,9 @@
}
else {
_mpd_qbarrett_divmod(q, r, a, b, status);
+ if (mpd_isspecial(q) || mpd_isspecial(r)) {
+ goto nanresult;
+ }
if (mpd_isinfinite(q) || q->digits > ctx->prec) {
*status |= MPD_Division_impossible;
goto nanresult;
@@ -3564,7 +3626,7 @@
return;
}
/* debug */
- abort();
+ abort(); /* GCOV_NOT_REACHED */
}
if (mpd_iszerocoeff(b)) {
if (mpd_iszerocoeff(a)) {
@@ -3609,7 +3671,7 @@
return;
}
/* debug */
- abort();
+ abort(); /* GCOV_NOT_REACHED */
}
if (mpd_iszerocoeff(b)) {
if (mpd_iszerocoeff(a)) {
@@ -3711,7 +3773,7 @@
f = ((double)msdigits + 1) / mpd_pow10[mpd_word_digits(msdigits)];
#ifdef CONFIG_64
- #if defined(__x86_64__) && defined(HAVE_80BIT_LONG_DOUBLE)
+ #ifdef USE_80BIT_LONG_DOUBLE
return ceill((1.435*(long double)prec - 1.182)
/ log10l((long double)prec/f));
#else
@@ -3753,6 +3815,8 @@
MPD_NEW_CONST(word,0,0,0,1,1,1);
mpd_ssize_t j, n, t;
+ assert(!mpd_isspecial(a));
+
/*
* We are calculating e^x = e^(r*10^t) = (e^r)^(10^t), where r < 1 and t >= 0.
*
@@ -3766,10 +3830,10 @@
* will occur when (e^-1)^(10^t) < 10^(etiny-1). If we consider MIN_ETINY,
* this will also happen for t > 10 (32 bit) or (t > 19) (64 bit).
*/
-#ifdef CONFIG_32
+#if defined(CONFIG_64)
+ #define MPD_EXP_MAX_T 19
+#elif defined(CONFIG_32)
#define MPD_EXP_MAX_T 10
-#elif defined(CONFIG_64)
- #define MPD_EXP_MAX_T 19
#endif
t = a->digits + a->exp;
t = (t > 0) ? t : 0;
@@ -3792,8 +3856,8 @@
workctx.round = MPD_ROUND_HALF_EVEN;
if ((n = _mpd_get_exp_iterations(a, workctx.prec)) == MPD_SSIZE_MAX) {
- mpd_seterror(result, MPD_Invalid_operation, status);
- goto finish;
+ mpd_seterror(result, MPD_Invalid_operation, status); /* GCOV_UNLIKELY */
+ goto finish; /* GCOV_UNLIKELY */
}
if (!mpd_qcopy(result, a, status)) {
@@ -3811,6 +3875,9 @@
mpd_qadd(&sum, &sum, &one, &workctx, &workctx.status);
}
+#ifdef CONFIG_64
+ _mpd_qpow_uint(result, &sum, mpd_pow10[t], MPD_POS, &workctx, status);
+#else
if (t <= MPD_MAX_POW10) {
_mpd_qpow_uint(result, &sum, mpd_pow10[t], MPD_POS, &workctx, status);
}
@@ -3820,6 +3887,7 @@
&workctx, status);
_mpd_qpow_uint(result, &tmp, mpd_pow10[t], MPD_POS, &workctx, status);
}
+#endif
finish:
@@ -3864,7 +3932,10 @@
mpd_ssize_t prec;
if (result == a) {
- mpd_qcopy(&aa, a, status);
+ if (!mpd_qcopy(&aa, a, status)) {
+ mpd_seterror(result, MPD_Malloc_error, status);
+ return;
+ }
a = &aa;
}
@@ -3948,18 +4019,38 @@
#if MPD_RDIGITS != 19
#error "mpdecimal.c: MPD_RDIGITS must be 19."
#endif
-static mpd_uint_t mpd_ln10data[MPD_MINALLOC_MAX] = {
+static mpd_uint_t mpd_ln10_data[MPD_MINALLOC_MAX] = {
+ 179914546843642076, 2302585092994045684
+};
+static mpd_uint_t mpd_ln10_init[2] = {
179914546843642076, 2302585092994045684
};
#else
#if MPD_RDIGITS != 9
#error "mpdecimal.c: MPD_RDIGITS must be 9."
#endif
-static mpd_uint_t mpd_ln10data[MPD_MINALLOC_MAX] = {299404568, 230258509};
+static mpd_uint_t mpd_ln10_data[MPD_MINALLOC_MAX] = {299404568, 230258509};
+static mpd_uint_t mpd_ln10_init[2] = {299404568, 230258509};
#endif
/* mpd_ln10 is cached in order to speed up computations */
mpd_t mpd_ln10 = {MPD_STATIC|MPD_STATIC_DATA, -(2*MPD_RDIGITS-1),
- 2*MPD_RDIGITS, 2, MPD_MINALLOC_MAX, mpd_ln10data};
+ 2*MPD_RDIGITS, 2, MPD_MINALLOC_MAX, mpd_ln10_data};
+
+static void
+mpd_reset_ln10(void)
+{
+ if (mpd_isdynamic_data(&mpd_ln10)) {
+ mpd_free(mpd_ln10.data);
+ }
+ mpd_ln10.data = mpd_ln10_data;
+ mpd_ln10_data[0] = mpd_ln10_init[0];
+ mpd_ln10_data[1] = mpd_ln10_init[1];
+ mpd_ln10.flags = MPD_STATIC|MPD_STATIC_DATA;
+ mpd_ln10.exp = -(2*MPD_RDIGITS-1);
+ mpd_ln10.digits = 2*MPD_RDIGITS;
+ mpd_ln10.len = 2;
+ mpd_ln10.alloc = MPD_MINALLOC_MAX;
+}
/*
* Initializes or updates mpd_ln10. If mpd_ln10 is cached and has exactly the
@@ -3977,13 +4068,17 @@
mpd_ssize_t klist[MPD_MAX_PREC_LOG2];
int i;
- if (mpd_ln10.digits > maxprec+2*MPD_RDIGITS) {
+ if (mpd_isspecial(&mpd_ln10)) {
+ mpd_reset_ln10();
+ }
+
+ if (mpd_ln10.digits > maxprec) {
/* shift to smaller cannot fail */
mpd_qshiftr_inplace(&mpd_ln10, mpd_ln10.digits-maxprec);
mpd_ln10.exp = -(mpd_ln10.digits-1);
return;
}
- else if (mpd_ln10.digits >= maxprec) {
+ else if (mpd_ln10.digits == maxprec) {
return;
}
@@ -4000,6 +4095,9 @@
mpd_qmul(&tmp, &static10, &tmp, &varcontext, status);
mpd_qsub(&tmp, &tmp, &one, &maxcontext, status);
mpd_qadd(&mpd_ln10, &mpd_ln10, &tmp, &maxcontext, status);
+ if (mpd_isspecial(&mpd_ln10)) {
+ break;
+ }
}
mpd_del(&tmp);
@@ -4091,6 +4189,8 @@
mpd_uint_t dummy, x;
int i;
+ assert(!mpd_isspecial(a) && !mpd_iszerocoeff(a));
+
/*
* We are calculating ln(a) = ln(v * 10^t) = ln(v) + t*ln(10),
* where 0.5 < v <= 5.
@@ -4184,6 +4284,9 @@
mpd_qsub(&tmp, &tmp, &one, &maxcontext, status);
mpd_qadd(z, z, &tmp, &maxcontext, status);
+ if (mpd_isspecial(z)) {
+ break;
+ }
}
postloop:
@@ -4259,7 +4362,10 @@
mpd_ssize_t prec;
if (result == a) {
- mpd_qcopy(&aa, a, status);
+ if (!mpd_qcopy(&aa, a, status)) {
+ mpd_seterror(result, MPD_Malloc_error, status);
+ return;
+ }
a = &aa;
}
@@ -4344,7 +4450,7 @@
}
if (mpd_coeff_ispow10(a)) {
uint8_t sign = 0;
- mpd_ssize_t adjexp = mpd_adjexp(a);
+ adjexp = mpd_adjexp(a);
if (adjexp < 0) {
sign = 1;
adjexp = -adjexp;
@@ -4376,7 +4482,10 @@
mpd_ssize_t prec;
if (result == a) {
- mpd_qcopy(&aa, a, status);
+ if (!mpd_qcopy(&aa, a, status)) {
+ mpd_seterror(result, MPD_Malloc_error, status);
+ return;
+ }
a = &aa;
}
@@ -4709,7 +4818,7 @@
mpd_size_t x, step;
assert(rsize >= 4);
- log2rsize = BSR(rsize);
+ log2rsize = mpd_bsr(rsize);
if (rsize <= 1024) {
x = ONE_UM<<log2rsize;
@@ -4813,10 +4922,11 @@
memcpy(c3, u, ulen * (sizeof *c3));
if (u == v) {
-
- fnt_autoconvolute(c1, n, P1);
- fnt_autoconvolute(c2, n, P2);
- fnt_autoconvolute(c3, n, P3);
+ if (!fnt_autoconvolute(c1, n, P1) ||
+ !fnt_autoconvolute(c2, n, P2) ||
+ !fnt_autoconvolute(c3, n, P3)) {
+ goto malloc_error;
+ }
}
else {
if ((vtmp = mpd_calloc(sizeof *vtmp, n)) == NULL) {
@@ -4824,15 +4934,24 @@
}
memcpy(vtmp, v, vlen * (sizeof *vtmp));
- fnt_convolute(c1, vtmp, n, P1);
+ if (!fnt_convolute(c1, vtmp, n, P1)) {
+ mpd_free(vtmp);
+ goto malloc_error;
+ }
memcpy(vtmp, v, vlen * (sizeof *vtmp));
mpd_uint_zero(vtmp+vlen, n-vlen);
- fnt_convolute(c2, vtmp, n, P2);
+ if (!fnt_convolute(c2, vtmp, n, P2)) {
+ mpd_free(vtmp);
+ goto malloc_error;
+ }
memcpy(vtmp, v, vlen * (sizeof *vtmp));
mpd_uint_zero(vtmp+vlen, n-vlen);
- fnt_convolute(c3, vtmp, n, P3);
+ if (!fnt_convolute(c3, vtmp, n, P3)) {
+ mpd_free(vtmp);
+ goto malloc_error;
+ }
mpd_free(vtmp);
}
@@ -4893,14 +5012,14 @@
lt = lb + lb + 1; // space needed for result array
mpd_uint_zero(w, lt); // clear result array
if (!_karatsuba_rec_fnt(w, b, a+m, w+lt, lb, la-m)) { // b*ah
- return 0;
+ return 0; /* GCOV_UNLIKELY */
}
}
else {
lt = (la-m) + (la-m) + 1; // space needed for result array
mpd_uint_zero(w, lt); // clear result array
if (!_karatsuba_rec_fnt(w, a+m, b, w+lt, la-m, lb)) { // ah*b
- return 0;
+ return 0; /* GCOV_UNLIKELY */
}
}
_mpd_baseaddto(c+m, w, (la-m)+lb); // add ah*b*B**m
@@ -4908,7 +5027,7 @@
lt = m + m + 1; // space needed for the result array
mpd_uint_zero(w, lt); // clear result array
if (!_karatsuba_rec_fnt(w, a, b, w+lt, m, lb)) { // al*b
- return 0;
+ return 0; /* GCOV_UNLIKELY */
}
_mpd_baseaddto(c, w, m+lb); // add al*b
@@ -4925,14 +5044,14 @@
_mpd_baseaddto(w+(m+1), b+m, lb-m);
if (!_karatsuba_rec_fnt(c+m, w, w+(m+1), w+2*(m+1), m+1, m+1)) {
- return 0;
+ return 0; /* GCOV_UNLIKELY */
}
lt = (la-m) + (la-m) + 1;
mpd_uint_zero(w, lt);
if (!_karatsuba_rec_fnt(w, a+m, b+m, w+lt, la-m, lb-m)) {
- return 0;
+ return 0; /* GCOV_UNLIKELY */
}
_mpd_baseaddto(c+2*m, w, (la-m) + (lb-m));
@@ -4942,7 +5061,7 @@
mpd_uint_zero(w, lt);
if (!_karatsuba_rec_fnt(w, a, b, w+lt, m, m)) {
- return 0;
+ return 0; /* GCOV_UNLIKELY */
}
_mpd_baseaddto(c, w, m+m);
_mpd_basesubfrom(c+m, w, m+m);
@@ -4973,8 +5092,8 @@
m = _kmul_worksize(ulen, 3*(MPD_MAXTRANSFORM_2N/2));
if (m && ((w = mpd_calloc(m, sizeof *w)) == NULL)) {
- mpd_free(result);
- return NULL;
+ mpd_free(result); /* GCOV_UNLIKELY */
+ return NULL; /* GCOV_UNLIKELY */
}
if (!_karatsuba_rec_fnt(result, u, v, w, ulen, vlen)) {
@@ -5065,28 +5184,14 @@
}
- if (big->len == 2) {
- if ((rdata = mpd_calloc(rsize, sizeof *rdata)) == NULL) {
- mpd_seterror(result, MPD_Malloc_error, status);
- return;
- }
- _mpd_mul_2_le2(rdata, big->data, small->data, small->len);
- }
- else if (small->len == 1) {
+ if (small->len == 1) {
if ((rdata = mpd_calloc(rsize, sizeof *rdata)) == NULL) {
mpd_seterror(result, MPD_Malloc_error, status);
return;
}
_mpd_shortmul(rdata, big->data, big->len, small->data[0]);
}
- else if (small->len <= 16 && rsize <= 64) {
- if ((rdata = mpd_calloc(rsize, sizeof *rdata)) == NULL) {
- mpd_seterror(result, MPD_Malloc_error, status);
- return;
- }
- _mpd_basemul(rdata, small->data, big->data, small->len, big->len);
- }
- else if (small->len <= 256 && rsize <= 1024) {
+ else if (rsize <= 1024) {
rdata = _mpd_kmul(big->data, small->data, big->len, small->len, &rsize);
if (rdata == NULL) {
mpd_seterror(result, MPD_Malloc_error, status);
@@ -5103,8 +5208,8 @@
else {
rdata = _mpd_kmul_fnt(big->data, small->data, big->len, small->len, &rsize);
if (rdata == NULL) {
- mpd_seterror(result, MPD_Malloc_error, status);
- return;
+ mpd_seterror(result, MPD_Malloc_error, status); /* GCOV_UNLIKELY */
+ return; /* GCOV_UNLIKELY */
}
}
@@ -5254,17 +5359,17 @@
return;
}
else {
+ mpd_clear_flags(result);
mpd_qmaxcoeff(result, ctx, status);
if (mpd_isnan(result)) {
return;
}
- mpd_clear_flags(result);
result->exp = ctx->emax - ctx->prec + 1;
return;
}
}
- /* should not be reached */
- abort();
+ /* debug */
+ abort(); /* GCOV_NOT_REACHED */
}
mpd_workcontext(&workctx, ctx);
@@ -5276,6 +5381,7 @@
mpd_qfinalize(result, &workctx, &workctx.status);
if (workctx.status&(MPD_Inexact|MPD_Errors)) {
+ *status |= (workctx.status&MPD_Errors);
return;
}
@@ -5301,6 +5407,7 @@
mpd_qcopy(result, a, status);
}
else {
+ mpd_clear_flags(result);
mpd_qmaxcoeff(result, ctx, status);
if (mpd_isnan(result)) {
return;
@@ -5315,12 +5422,13 @@
mpd_workcontext(&workctx, ctx);
workctx.round = MPD_ROUND_CEILING;
- if (!mpd_qcopy(result, a, &workctx.status)) {
+ if (!mpd_qcopy(result, a, status)) {
return;
}
mpd_qfinalize(result, &workctx, &workctx.status);
if (workctx.status & (MPD_Inexact|MPD_Errors)) {
+ *status |= (workctx.status&MPD_Errors);
return;
}
@@ -5380,15 +5488,15 @@
mpd_uint_t n;
if (exp == 0) {
- _settriple(result, resultsign, 1, 0);
- return;
+ _settriple(result, resultsign, 1, 0); /* GCOV_NOT_REACHED */
+ return; /* GCOV_NOT_REACHED */
}
if (!mpd_qcopy(result, base, status)) {
return;
}
- n = mpd_bits[BSR(exp)];
+ n = mpd_bits[mpd_bsr(exp)];
while (n >>= 1) {
mpd_qmul(result, result, result, ctx, &workstatus);
if (exp & n) {
@@ -5418,9 +5526,8 @@
mpd_maxcontext(&maxctx);
- if (!mpd_qcopy(result, &one, status)) {
- return;
- }
+ /* resize to smaller cannot fail */
+ mpd_qcopy(result, &one, status);
while (!mpd_iszero(texp)) {
if (mpd_isodd(texp)) {
@@ -5432,8 +5539,8 @@
}
mpd_qmul(tbase, tbase, tbase, ctx, &workstatus);
mpd_qdivint(texp, texp, &two, &maxctx, &workstatus);
- if (mpd_isnan(texp)) {
- mpd_seterror(result, MPD_Division_undefined, status);
+ if (mpd_isnan(tbase) || mpd_isnan(texp)) {
+ mpd_seterror(result, workstatus&MPD_Errors, status);
return;
}
}
@@ -5472,11 +5579,11 @@
}
}
- n = mpd_qget_uint(exp, &workctx.status);
+ n = mpd_qabs_uint(exp, &workctx.status);
if (workctx.status&MPD_Invalid_operation) {
if (!mpd_qcopy(&texp, exp, status)) {
- mpd_setspecial(result, MPD_POS, MPD_NAN);
- goto finish;
+ mpd_setspecial(result, MPD_POS, MPD_NAN); /* GCOV_UNLIKELY */
+ goto finish; /* GCOV_UNLIKELY */
}
_mpd_qpow_mpd(result, &tbase, &texp, resultsign, &workctx, status);
}
@@ -5540,9 +5647,13 @@
}
/* 1.000**3 = 1.000000000 */
mpd_qmul_ssize(result, exp, -base->exp, ctx, &workstatus);
+ if (workstatus&MPD_Errors) {
+ *status |= (workstatus&MPD_Errors);
+ return 0;
+ }
/* digits-1 after exponentiation */
shift = mpd_qget_ssize(result, &workstatus);
- /* MPD_SSIZE_MAX on failure */
+ /* shift is MPD_SSIZE_MAX if result is too large */
if (shift > ctx->prec-1) {
shift = ctx->prec-1;
*status |= MPD_Rounded;
@@ -5553,9 +5664,11 @@
*status |= (MPD_Inexact|MPD_Rounded);
}
else {
- return -2;
+ return -2; /* GCOV_NOT_REACHED */
+ }
+ if (!mpd_qshiftl(result, &one, shift, status)) {
+ return 0;
}
- mpd_qshiftl(result, &one, shift, status);
result->exp = -shift;
mpd_set_flags(result, resultsign);
}
@@ -5563,131 +5676,140 @@
return cmp;
}
+/*
+ * Detect certain over/underflow of x**y.
+ * ACL2 proof: pow_bounds.lisp.
+ *
+ * Symbols:
+ *
+ * e: EXP_INF or EXP_CLAMP
+ * x: base
+ * y: exponent
+ *
+ * omega(e) = log10(abs(e))
+ * zeta(x) = log10(abs(log10(x)))
+ * theta(y) = log10(abs(y))
+ *
+ * Upper and lower bounds:
+ *
+ * ub_omega(e) = ceil(log10(abs(e)))
+ * lb_theta(y) = floor(log10(abs(y)))
+ *
+ * | floor(log10(floor(abs(log10(x))))) if x < 1/10 or x >= 10
+ * lb_zeta(x) = | floor(log10(abs(x-1)/10)) if 1/10 <= x < 1
+ * | floor(log10(abs((x-1)/100))) if 1 < x < 10
+ *
+ * ub_omega(e) and lb_theta(y) are obviously upper and lower bounds
+ * for omega(e) and theta(y).
+ *
+ * lb_zeta is a lower bound for zeta(x):
+ *
+ * x < 1/10 or x >= 10:
+ *
+ * abs(log10(x)) >= 1, so the outer log10 is well defined. Since log10
+ * is strictly increasing, the end result is a lower bound.
+ *
+ * 1/10 <= x < 1:
+ *
+ * We use: log10(x) <= (x-1)/log(10)
+ * abs(log10(x)) >= abs(x-1)/log(10)
+ * abs(log10(x)) >= abs(x-1)/10
+ *
+ * 1 < x < 10:
+ *
+ * We use: (x-1)/(x*log(10)) < log10(x)
+ * abs((x-1)/100) < abs(log10(x))
+ *
+ * XXX: abs((x-1)/10) would work, need ACL2 proof.
+ *
+ *
+ * Let (0 < x < 1 and y < 0) or (x > 1 and y > 0). (H1)
+ * Let ub_omega(exp_inf) < lb_zeta(x) + lb_theta(y) (H2)
+ *
+ * Then:
+ * log10(abs(exp_inf)) < log10(abs(log10(x))) + log10(abs(y)). (1)
+ * exp_inf < log10(x) * y (2)
+ * 10**exp_inf < x**y (3)
+ *
+ * Let (0 < x < 1 and y > 0) or (x > 1 and y < 0). (H3)
+ * Let ub_omega(exp_clamp) < lb_zeta(x) + lb_theta(y) (H4)
+ *
+ * Then:
+ * log10(abs(exp_clamp)) < log10(abs(log10(x))) + log10(abs(y)). (4)
+ * log10(x) * y < exp_clamp (5)
+ * x**y < 10**exp_clamp (6)
+ *
+ */
static mpd_ssize_t
-_qlog10_exp_bound(const mpd_t *x, uint32_t *status)
+_lower_bound_zeta(const mpd_t *x, uint32_t *status)
{
mpd_context_t maxctx;
MPD_NEW_STATIC(scratch,0,0,0,0);
- MPD_NEW_CONST(tmp,0,0,1,1,1,1);
- mpd_ssize_t t, numdigits, dendigits;
+ mpd_ssize_t t, u;
- /*
- * This function is designed to weed out cases where x**y will clearly
- * over/underflow. The chain of implications is written as a stack, i.e.
- * each line implies the line above it.
- *
- * (1) x**y > 10**(emax+1) /\ x**y < 10**(etiny-1)
- *
- * (2) log10(x) * y > emax+1 /\ log10(x) * y < etiny-1
- *
- * The lhs of the conjunction can only be true if the factors have the
- * same sign, the rhs only if the factors differ. These two hypotheses
- * are implied from now on.
- *
- * (3) |log10(x)| * |y| > emax+1 /\ |log10(x)| * |y| > |etiny-1|
- *
- * (4) log10(|log10(x)|) + log10(|y|) > log10(emax+1)
- * /\ log10(|log10(x)|) + log10(|y|) > log10(|etiny-1|)
- *
- * Now, (4) clearly must be true if it is true for the following estimates
- * for the terms:
- *
- * est(log10(emax+1)| >= log10(emax+1)
- * est(log10(|etiny-1|)| >= log10(|etiny-1|)
- *
- * est(log10(|y|)) <= log10(|y|)
- *
- * 0 < est(log10(x)) <= log10(x), if x > 1
- * log10(x) <= est(log10(x)) < 0, if x < 1
- *
- *
- * Estimate for log10(x):
- *
- * log10(x) = log10(v * 10**t) = log10(v) + t, where 1 <= v < 10.
- * Thus, t is adjexp(x).
- *
- * If t > 0, 0 < t <= log10(x), so we are done.
- *
- * If t < -1, log10(x) <= t+1 < 0, so we are done.
- *
- * If t == -1 or t == 0, then 0.1 <= base < 10. We assume x != 1 and
- * use:
- *
- * 1-1/x < ln(x) < x-1 (Abramowitz&Stegun, 4.1.33)
- *
- * Then, if 1 < x < 10:
- *
- * 0 < (1-1/x) / 2.31 < log10(x)
- * 0 < (1-1/x) / 10 < log10(x)
- * 0 < (x-1) / (10*x) < log10(x)
- * Multiply by (10**-x->exp), c is the coefficient:
- * 0 < (c - 10**(-x->exp)) / (10*c) < log10(x)
- *
- * Then, if 0.1 <= x < 1:
- *
- * log10(x) <= (1-x) / 2.31 < 0
- * log10(x) <= (1-x) / 10 < 0
- * Multiply by (10**-x->exp), c is the coefficient:
- * log10(x) < (10**(-x->exp) - c) / 10**(-x->exp+1) < 0
- *
- */
t = mpd_adjexp(x);
if (t > 0) {
+ /* x >= 10 -> floor(log10(floor(abs(log10(x))))) */
return mpd_exp_digits(t) - 1;
}
else if (t < -1) {
+ /* x < 1/10 -> floor(log10(floor(abs(log10(x))))) */
return mpd_exp_digits(t+1) - 1;
}
else {
mpd_maxcontext(&maxctx);
- tmp.exp = -x->exp;
- if (!mpd_qcopy_abs(&scratch, x, status)) {
- *status |= MPD_Malloc_error;
+ mpd_qsub(&scratch, x, &one, &maxctx, status);
+ if (mpd_isspecial(&scratch)) {
+ mpd_del(&scratch);
return MPD_SSIZE_MAX;
}
- scratch.exp = 0;
- if (t == 0) {
- mpd_qsub(&scratch, &scratch, &tmp, &maxctx, status);
- numdigits = scratch.digits;
- dendigits = x->digits + 1;
- }
- else {
- mpd_qsub(&scratch, &tmp, &scratch, &maxctx, status);
- numdigits = scratch.digits;
- if (-x->exp+1 < 0) {
- numdigits += (-x->exp+1);
- dendigits = 1;
- }
- else {
- dendigits = -x->exp+1;
- }
- }
+ u = mpd_adjexp(&scratch);
mpd_del(&scratch);
- return numdigits-dendigits-(numdigits<dendigits) - 1;
+
+ /* t == -1, 1/10 <= x < 1 -> floor(log10(abs(x-1)/10))
+ * t == 0, 1 < x < 10 -> floor(log10(abs(x-1)/100)) */
+ return (t == 0) ? u-2 : u-1;
}
}
-/* Detect cases of certain overflow/underflow in the power function. */
+/*
+ * Detect cases of certain overflow/underflow in the power function.
+ * Assumptions: x != 1, y != 0. The proof above is for positive x.
+ * If x is negative and y is an odd integer, x**y == -(abs(x)**y),
+ * so the analysis does not change.
+ */
static int
-_qcheck_pow_bounds(mpd_t *result, const mpd_t *base, const mpd_t *exp,
+_qcheck_pow_bounds(mpd_t *result, const mpd_t *x, const mpd_t *y,
uint8_t resultsign,
const mpd_context_t *ctx, uint32_t *status)
{
- mpd_ssize_t bound;
+ MPD_NEW_SHARED(abs_x, x);
+ mpd_ssize_t ub_omega, lb_zeta, lb_theta;
uint8_t sign;
- bound = _qlog10_exp_bound(base, status) + mpd_adjexp(exp);
+ mpd_set_positive(&abs_x);
- sign = (mpd_adjexp(base) < 0) ^ mpd_sign(exp);
+ lb_theta = mpd_adjexp(y);
+ lb_zeta = _lower_bound_zeta(&abs_x, status);
+ if (lb_zeta == MPD_SSIZE_MAX) {
+ mpd_seterror(result, MPD_Malloc_error, status);
+ return 1;
+ }
+
+ sign = (mpd_adjexp(&abs_x) < 0) ^ mpd_sign(y);
if (sign == 0) {
- if (bound >= mpd_exp_digits(ctx->emax)) {
+ /* (0 < |x| < 1 and y < 0) or (|x| > 1 and y > 0) */
+ ub_omega = mpd_exp_digits(ctx->emax);
+ if (ub_omega < lb_zeta + lb_theta) {
_settriple(result, resultsign, 1, MPD_EXP_INF);
mpd_qfinalize(result, ctx, status);
return 1;
}
}
else {
- if (bound >= mpd_exp_digits(mpd_etiny(ctx))) {
+ /* (0 < |x| < 1 and y > 0) or (|x| > 1 and y < 0). */
+ ub_omega = mpd_exp_digits(mpd_etiny(ctx));
+ if (ub_omega < lb_zeta + lb_theta) {
_settriple(result, resultsign, 1, mpd_etiny(ctx)-1);
mpd_qfinalize(result, ctx, status);
return 1;
@@ -5821,7 +5943,7 @@
}
else {
_mpd_qpow_real(result, base, exp, ctx, status);
- if (_mpd_cmp(result, &one) == 0) {
+ if (!mpd_isspecial(result) && _mpd_cmp(result, &one) == 0) {
mpd_ssize_t shift = ctx->prec-1;
mpd_qshiftl(result, &one, shift, status);
result->exp = -shift;
@@ -5846,9 +5968,8 @@
mpd_maxcontext(&maxcontext);
- if (!mpd_qcopy(result, &one, status)) {
- return;
- }
+ /* resize to smaller cannot fail */
+ mpd_qcopy(result, &one, status);
while (exp > 0) {
if (exp & 1) {
@@ -5921,8 +6042,7 @@
}
if (!mpd_qcopy(&tmod, mod, status)) {
- mpd_seterror(result, MPD_Malloc_error, status);
- goto finish;
+ goto mpd_errors;
}
mpd_set_positive(&tmod);
@@ -5943,6 +6063,11 @@
mpd_qrem(result, result, &tmod, &maxcontext, status);
mpd_qmul(&tbase, &tbase, result, &maxcontext, status);
mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status);
+ if (mpd_isspecial(&tbase) ||
+ mpd_isspecial(&texp) ||
+ mpd_isspecial(&tmod)) {
+ goto mpd_errors;
+ }
for (i = 0; i < texp_exp; i++) {
_mpd_qpowmod_uint(&tmp, &tbase, 10, &tmod, status);
@@ -5950,10 +6075,13 @@
tmp = tbase;
tbase = t;
}
+ if (mpd_isspecial(&tbase)) {
+ goto mpd_errors; /* GCOV_UNLIKELY */
+ }
- /* possible resize will be to smaller */
+ /* resize to smaller cannot fail */
mpd_qcopy(result, &one, status);
- while (!mpd_iszero(&texp)) {
+ while (mpd_isfinite(&texp) && !mpd_iszero(&texp)) {
if (mpd_isodd(&texp)) {
mpd_qmul(result, result, &tbase, &maxcontext, status);
mpd_qrem(result, result, &tmod, &maxcontext, status);
@@ -5961,20 +6089,27 @@
mpd_qmul(&tbase, &tbase, &tbase, &maxcontext, status);
mpd_qrem(&tbase, &tbase, &tmod, &maxcontext, status);
mpd_qdivint(&texp, &texp, &two, &maxcontext, status);
- if (mpd_isnan(&texp)) {
- mpd_setspecial(result, MPD_POS, MPD_NAN);
- goto finish;
- }
+ }
+ if (mpd_isspecial(&texp) || mpd_isspecial(&tbase) ||
+ mpd_isspecial(&tmod) || mpd_isspecial(result)) {
+ /* MPD_Malloc_error */
+ goto mpd_errors;
+ }
+ else {
+ mpd_set_sign(result, sign);
}
-
-finish:
+out:
mpd_del(&tbase);
mpd_del(&texp);
mpd_del(&tmod);
mpd_del(&tmp);
- mpd_set_flags(result, sign);
mpd_qfinalize(result, ctx, status);
+ return;
+
+mpd_errors:
+ mpd_setspecial(result, MPD_POS, MPD_NAN);
+ goto out;
}
void
@@ -6028,6 +6163,9 @@
* so the shift before an increment will fit in prec. */
shift = -expdiff;
rnd = mpd_qshiftr(result, a, shift, status);
+ if (rnd == MPD_UINT_MAX) {
+ return;
+ }
result->exp = b_exp;
if (!_mpd_apply_round_fit(result, rnd, ctx, status)) {
return;
@@ -6105,7 +6243,7 @@
return;
}
/* debug */
- abort();
+ abort(); /* GCOV_NOT_REACHED */
}
if (mpd_iszerocoeff(b)) {
if (mpd_iszerocoeff(a)) {
@@ -6146,7 +6284,7 @@
return;
}
/* debug */
- abort();
+ abort(); /* GCOV_NOT_REACHED */
}
if (mpd_iszerocoeff(b)) {
if (mpd_iszerocoeff(a)) {
@@ -6184,7 +6322,7 @@
expdiff = mpd_adjexp(b) - mpd_adjexp(r);
if (-1 <= expdiff && expdiff <= 1) {
- mpd_qfloor(&q, &q, &workctx, &workctx.status);
+ mpd_qtrunc(&q, &q, &workctx, &workctx.status);
allnine = mpd_coeff_isallnine(&q);
floordigits = q.digits;
isodd = mpd_isodd(&q);
@@ -6192,9 +6330,17 @@
mpd_maxcontext(&workctx);
if (mpd_sign(a) == mpd_sign(b)) {
_mpd_qsub(&q, r, b, &workctx, &workctx.status);
+ if (workctx.status&MPD_Errors) {
+ mpd_seterror(r, workctx.status&MPD_Errors, status);
+ goto finish;
+ }
}
else {
_mpd_qadd(&q, r, b, &workctx, &workctx.status);
+ if (workctx.status&MPD_Errors) {
+ mpd_seterror(r, workctx.status&MPD_Errors, status);
+ goto finish;
+ }
}
cmp = mpd_cmp_total_mag(&q, r);
@@ -6253,6 +6399,9 @@
else {
shift = -expdiff;
rnd = mpd_qshiftr(result, a, shift, status);
+ if (rnd == MPD_UINT_MAX) {
+ return;
+ }
result->exp = exp;
_mpd_apply_round_excess(result, rnd, ctx, status);
*status |= MPD_Rounded;
@@ -6267,7 +6416,7 @@
}
/* Round to an integer according to 'action' and ctx->round. */
-enum {TO_INT_EXACT, TO_INT_SILENT, TO_INT_FLOOR, TO_INT_CEIL};
+enum {TO_INT_EXACT, TO_INT_SILENT, TO_INT_TRUNC, TO_INT_FLOOR, TO_INT_CEIL};
static void
_mpd_qround_to_integral(int action, mpd_t *result, const mpd_t *a,
const mpd_context_t *ctx, uint32_t *status)
@@ -6291,6 +6440,9 @@
}
rnd = mpd_qshiftr(result, a, -a->exp, status);
+ if (rnd == MPD_UINT_MAX) {
+ return;
+ }
result->exp = 0;
if (action == TO_INT_EXACT || action == TO_INT_SILENT) {
@@ -6302,9 +6454,14 @@
}
}
}
+ else if (action == TO_INT_FLOOR) {
+ if (rnd && mpd_isnegative(result)) {
+ _mpd_qsub(result, result, &one, ctx, status);
+ }
+ }
else if (action == TO_INT_CEIL) {
- if (rnd) {
- mpd_qadd(result, result, &one, ctx, status);
+ if (rnd && mpd_ispositive(result)) {
+ _mpd_qadd(result, result, &one, ctx, status);
}
}
}
@@ -6324,6 +6481,13 @@
}
void
+mpd_qtrunc(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
+ uint32_t *status)
+{
+ (void)_mpd_qround_to_integral(TO_INT_TRUNC, result, a, ctx, status);
+}
+
+void
mpd_qfloor(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx,
uint32_t *status)
{
@@ -6411,8 +6575,9 @@
v = &vtmp;
if (result == a) {
- if ((v = mpd_qncopy(a)) == NULL) {
- goto finish;
+ if ((v = mpd_qncopy(a)) == NULL) { /* GCOV_NOT_REACHED */
+ mpd_seterror(result, MPD_Malloc_error, status); /* GCOV_NOT_REACHED */
+ goto finish; /* GCOV_NOT_REACHED */
}
}
@@ -6448,9 +6613,10 @@
mpd_qsub(z, &s, &t, &maxcontext, status);
}
- z->exp -= adj;
- mpd_set_flags(z, sign);
-
+ if (!mpd_isspecial(z)) {
+ z->exp -= adj;
+ mpd_set_flags(z, sign);
+ }
finish:
mpd_del(&s);
@@ -6486,11 +6652,13 @@
if (q == a || q == b) {
if ((qq = mpd_qnew()) == NULL) {
+ *status |= MPD_Malloc_error;
goto nanresult;
}
}
if (r == a || r == b) {
if ((rr = mpd_qnew()) == NULL) {
+ *status |= MPD_Malloc_error;
goto nanresult;
}
}
@@ -6501,7 +6669,7 @@
_mpd_qreciprocal(rr, &bb, &workctx, &workctx.status);
mpd_qmul(qq, &aa, rr, &workctx, &workctx.status);
- mpd_qfloor(qq, qq, &workctx, &workctx.status);
+ mpd_qtrunc(qq, qq, &workctx, &workctx.status);
workctx.prec = aa.digits + 3;
/* get the remainder */
@@ -6510,9 +6678,13 @@
/* Fix the result. Algorithm from: Karl Hasselstrom, Fast Division of Large Integers */
for (k = 0;; k++) {
+ if (mpd_isspecial(rr)) {
+ *status |= (workctx.status&MPD_Errors);
+ goto nanresult;
+ }
if (k > 2) {
- mpd_err_warn("_mpd_barrett_divmod: k > 2 in correcting loop");
- abort(); /* debug */
+ mpd_err_warn("_mpd_barrett_divmod: k > 2 in correcting loop"); /* GCOV_NOT_REACHED */
+ abort(); /* GCOV_NOT_REACHED */
}
else if (_mpd_cmp(&zero, rr) == 1) {
mpd_qadd(rr, rr, &bb, &workctx, &workctx.status);
@@ -6528,11 +6700,15 @@
}
if (qq != q) {
- mpd_qcopy(q, qq, status);
+ if (!mpd_qcopy(q, qq, status)) {
+ goto nanresult; /* GCOV_UNLIKELY */
+ }
mpd_del(qq);
}
if (rr != r) {
- mpd_qcopy(r, rr, status);
+ if (!mpd_qcopy(r, rr, status)) {
+ goto nanresult; /* GCOV_UNLIKELY */
+ }
mpd_del(rr);
}
@@ -6541,9 +6717,9 @@
nanresult:
- if (qq) mpd_del(qq);
- if (rr) mpd_del(rr);
- mpd_seterror(q, MPD_Malloc_error, status);
+ if (qq && qq != q) mpd_del(qq);
+ if (rr && rr != r) mpd_del(rr);
+ mpd_setspecial(q, MPD_POS, MPD_NAN);
mpd_setspecial(r, MPD_POS, MPD_NAN);
}
@@ -6634,7 +6810,8 @@
v = &vtmp;
if (result == a) {
if ((v = mpd_qncopy(a)) == NULL) {
- goto finish;
+ mpd_seterror(result, MPD_Malloc_error, status);
+ return;
}
}
@@ -6696,7 +6873,6 @@
}
-finish:
mpd_del(&s);
mpd_del(&t);
if (v != &vtmp) mpd_del(v);
@@ -6753,7 +6929,11 @@
u.exp = u.digits - ctx->prec + result->exp - 1;
_mpd_qsub(tmp, result, &u, &maxctx, status);
+ if (*status&MPD_Errors) goto nanresult;
+
_mpd_qmul(tmp, tmp, tmp, &maxctx, status);
+ if (*status&MPD_Errors) goto nanresult;
+
if (_mpd_cmp(tmp, a) == 1) {
u.exp += 1;
u.data[0] = 1;
@@ -6761,13 +6941,22 @@
}
else {
_mpd_qadd(tmp, result, &u, &maxctx, status);
+ if (*status&MPD_Errors) goto nanresult;
+
_mpd_qmul(tmp, tmp, tmp, &maxctx, status);
+ if (*status&MPD_Errors) goto nanresult;
+
if (_mpd_cmp(tmp, a) == -1) {
u.exp += 1;
u.data[0] = 1;
_mpd_qadd(result, result, &u, &maxctx, status);
}
}
+
+ return;
+
+nanresult:
+ mpd_setspecial(result, MPD_POS, MPD_NAN);
}
void
@@ -6780,9 +6969,9 @@
MPD_NEW_STATIC(v,0,0,0,0); /* a, normalized to a number between 1 and 10 */
MPD_NEW_STATIC(vtmp,0,0,0,0);
MPD_NEW_STATIC(tmp,0,0,0,0);
- MPD_NEW_STATIC(aa,0,0,0,0);
mpd_ssize_t ideal_exp, shift;
mpd_ssize_t target_prec, fracdigits;
+ mpd_ssize_t a_exp, a_digits;
mpd_ssize_t adj, tz;
mpd_uint_t dummy, t;
int exact = 0;
@@ -6814,16 +7003,12 @@
}
if (!mpd_qcopy(&v, a, status)) {
- mpd_seterror(result, MPD_Invalid_operation, status);
+ mpd_seterror(result, MPD_Malloc_error, status);
goto finish;
}
- if (result == a) {
- if (!mpd_qcopy(&aa, a, status)) {
- mpd_seterror(result, MPD_Invalid_operation, status);
- goto finish;
- }
- a = &aa;
- }
+
+ a_exp = a->exp;
+ a_digits = a->digits;
/* normalize a to 1 <= v < 100 */
if ((v.digits+v.exp) & 1) {
@@ -6841,11 +7026,11 @@
t = t < 1000 ? t*10 : t;
t = t < 1000 ? t*10 : t;
}
- adj = (a->exp-v.exp) / 2;
+ adj = (a_exp-v.exp) / 2;
/* use excess digits */
- target_prec = (a->digits > ctx->prec) ? a->digits : ctx->prec;
+ target_prec = (a_digits > ctx->prec) ? a_digits : ctx->prec;
target_prec += 2;
varcontext.prec = target_prec + 3;
@@ -6859,12 +7044,17 @@
tz = mpd_trail_zeros(result);
if ((result->digits-tz)*2-1 <= v.digits) {
_mpd_qmul(&tmp, result, result, &varcontext, &workstatus);
+ if (workstatus&MPD_Errors) {
+ mpd_seterror(result, workstatus&MPD_Errors, status);
+ goto finish;
+ }
exact = (_mpd_cmp(&tmp, &v) == 0);
}
*status |= (workstatus&MPD_Errors);
if (!exact && !mpd_isspecial(result) && !mpd_iszero(result)) {
_mpd_fix_sqrt(result, &v, &tmp, &varcontext, status);
+ if (mpd_isspecial(result)) goto finish;
*status |= (MPD_Rounded|MPD_Inexact);
}
@@ -6914,7 +7104,7 @@
x = a->digits+a->exp;
#ifdef CONFIG_64
- #if defined(__x86_64__) && defined(HAVE_80BIT_LONG_DOUBLE)
+ #ifdef USE_80BIT_LONG_DOUBLE
return (long double)x / log10(base) + 3;
#else
/* x > floor(((1ULL<<53)-3) * log10(2)) */
@@ -6938,7 +7128,7 @@
_mpd_importsize(size_t srclen, uint32_t base)
{
#if SIZE_MAX == UINT64_MAX
- #if defined(__x86_64__) && defined(HAVE_80BIT_LONG_DOUBLE)
+ #ifdef USE_80BIT_LONG_DOUBLE
long double x = (long double)srclen * (log10(base)/MPD_RDIGITS) + 3;
#else
double x;
@@ -6977,7 +7167,7 @@
static inline void
_from_base_u16(mpd_uint_t *w, mpd_ssize_t wlen,
- const mpd_uint_t *u, size_t ulen, uint16_t ubase)
+ const mpd_uint_t *u, size_t ulen, uint32_t ubase)
{
mpd_ssize_t m = 1;
mpd_uint_t carry;
@@ -7074,11 +7264,13 @@
if (src->exp >= 0) {
if (!mpd_qshiftl(tsrc, src, src->exp, status)) {
+ mpd_del(tsrc);
return SIZE_MAX;
}
}
else {
if (mpd_qshiftr(tsrc, src, -src->exp, status) == MPD_UINT_MAX) {
+ mpd_del(tsrc);
return SIZE_MAX;
}
}
@@ -7126,11 +7318,13 @@
if (src->exp >= 0) {
if (!mpd_qshiftl(tsrc, src, src->exp, status)) {
+ mpd_del(tsrc);
return SIZE_MAX;
}
}
else {
if (mpd_qshiftr(tsrc, src, -src->exp, status) == MPD_UINT_MAX) {
+ mpd_del(tsrc);
return SIZE_MAX;
}
}
@@ -7277,12 +7471,12 @@
/* Testcases for Newton Division */
/*********************************************************************/
-void
+static void
mpd_qtest_newtondiv(mpd_t *q, const mpd_t *a, const mpd_t *b,
const mpd_context_t *ctx, uint32_t *status)
{
MPD_NEW_STATIC(aligned,0,0,0,0);
- mpd_uint_t ld, carry = 0;
+ mpd_uint_t ld;
mpd_ssize_t shift, exp, tz;
mpd_ssize_t newsize;
mpd_uint_t rem;
@@ -7346,6 +7540,10 @@
{
MPD_NEW_STATIC(r,0,0,0,0);
_mpd_qbarrett_divmod(q, &r, a, b, status);
+ if (mpd_isspecial(q) || mpd_isspecial(&r)) {
+ mpd_del(&r);
+ goto finish;
+ }
rem = !mpd_iszerocoeff(&r);
mpd_del(&r);
newsize = q->len;
@@ -7361,14 +7559,7 @@
if (rem) {
ld = mpd_lsd(q->data[0]);
if (ld == 0 || ld == 5) {
- carry = _mpd_baseincr(q->data, q->len);
- if (carry) {
- if (!mpd_qresize(q, q->len+1, status)) {
- mpd_seterror(q, MPD_Malloc_error, status);
- goto finish;
- }
- q->data[q->len] = 1;
- }
+ q->data[0] += 1;
}
}
else if (1) { /* SET_IDEAL_EXP */
@@ -7388,7 +7579,7 @@
mpd_qfinalize(q, ctx, status);
}
-void
+static void
_mpd_qtest_barrett_divmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b,
const mpd_context_t *ctx, uint32_t *status)
{
@@ -7402,7 +7593,7 @@
ideal_exp = (a->exp > b->exp) ? b->exp : a->exp;
if (mpd_iszerocoeff(a)) {
if (!mpd_qcopy(r, a, status)) {
- goto nanresult;
+ goto nanresult; /* GCOV_NOT_REACHED */
}
r->exp = ideal_exp;
_settriple(q, sign_ab, 0, 0);
@@ -7474,6 +7665,9 @@
}
_mpd_qbarrett_divmod(q, r, a, b, status);
+ if (mpd_isspecial(q) || mpd_isspecial(r)) {
+ goto nanresult;
+ }
if (mpd_isinfinite(q) || q->digits > ctx->prec) {
*status |= MPD_Division_impossible;
goto nanresult;
@@ -7489,8 +7683,8 @@
mpd_set_flags(q, sign_ab);
q->exp = 0;
if (q->digits > ctx->prec) {
- *status |= MPD_Division_impossible;
- goto nanresult;
+ *status |= MPD_Division_impossible; /* GCOV_NOT_REACHED */
+ goto nanresult; /* GCOV_NOT_REACHED */
}
rsize = _mpd_real_size(r->data, rsize);
@@ -7511,11 +7705,11 @@
goto out;
}
-void
+static void
mpd_qtest_newtondivint(mpd_t *q, const mpd_t *a, const mpd_t *b,
const mpd_context_t *ctx, uint32_t *status)
{
- mpd_t *r;
+ MPD_NEW_STATIC(r,0,0,0,0);
uint8_t sign = mpd_sign(a)^mpd_sign(b);
if (mpd_isspecial(a) || mpd_isspecial(b)) {
@@ -7535,7 +7729,7 @@
return;
}
/* debug */
- abort();
+ abort(); /* GCOV_NOT_REACHED */
}
if (mpd_iszerocoeff(b)) {
if (mpd_iszerocoeff(a)) {
@@ -7548,17 +7742,16 @@
return;
}
- r = mpd_qnew();
- _mpd_qtest_barrett_divmod(q, r, a, b, ctx, status);
- mpd_del(r);
+ _mpd_qtest_barrett_divmod(q, &r, a, b, ctx, status);
+ mpd_del(&r);
mpd_qfinalize(q, ctx, status);
}
-void
+static void
mpd_qtest_newtonrem(mpd_t *r, const mpd_t *a, const mpd_t *b,
const mpd_context_t *ctx, uint32_t *status)
{
- mpd_t *q;
+ MPD_NEW_STATIC(q,0,0,0,0);
if (mpd_isspecial(a) || mpd_isspecial(b)) {
if (mpd_qcheck_nans(r, a, b, ctx, status)) {
@@ -7573,7 +7766,7 @@
return;
}
/* debug */
- abort();
+ abort(); /* GCOV_NOT_REACHED */
}
if (mpd_iszerocoeff(b)) {
if (mpd_iszerocoeff(a)) {
@@ -7585,13 +7778,12 @@
return;
}
- q = mpd_qnew();
- _mpd_qtest_barrett_divmod(q, r, a, b, ctx, status);
- mpd_del(q);
+ _mpd_qtest_barrett_divmod(&q, r, a, b, ctx, status);
+ mpd_del(&q);
mpd_qfinalize(r, ctx, status);
}
-void
+static void
mpd_qtest_newtondivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b,
const mpd_context_t *ctx, uint32_t *status)
{
@@ -7619,7 +7811,7 @@
return;
}
/* debug */
- abort();
+ abort(); /* GCOV_NOT_REACHED */
}
if (mpd_iszerocoeff(b)) {
if (mpd_iszerocoeff(a)) {
@@ -7640,5 +7832,36 @@
mpd_qfinalize(r, ctx, status);
}
+void
+mpd_test_newtondiv(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qtest_newtondiv(q, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_test_newtondivint(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qtest_newtondivint(q, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_test_newtonrem(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qtest_newtonrem(r, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_test_newtondivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qtest_newtondivmod(q, r, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal32.h
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal32.h (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal32.h Mon Nov 8 15:12:49 2010
@@ -34,9 +34,8 @@
typedef uint64_t mpd_uuint_t; /* double width unsigned mod type */
#endif
-/* enable CONFIG_32+ANSI on 64-bit platforms without resorting to -m32 */
-#define MPD_SIZE_MAX UINT32_MAX
-typedef uint32_t mpd_size_t; /* unsigned size type */
+#define MPD_SIZE_MAX SIZE_MAX
+typedef size_t mpd_size_t; /* unsigned size type */
/* type for dec->len, dec->exp, ctx->prec */
#define MPD_SSIZE_MAX INT32_MAX
@@ -62,8 +61,8 @@
#define MPD_MAXIMPORT 94444445L /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */
-#if SIZE_MAX < MPD_SIZE_MAX
- #error "unsupported platform: need size_t >= mpd_size_t"
+#if MPD_SIZE_MAX != MPD_UINT_MAX
+ #error "unsupported platform: need mpd_size_t == mpd_uint_t"
#endif
@@ -154,11 +153,13 @@
#define MPD_MINALLOC_MAX 64
extern mpd_ssize_t MPD_MINALLOC;
extern void (* mpd_traphandler)(mpd_context_t *);
+void mpd_dflt_traphandler(mpd_context_t *);
void mpd_setminalloc(mpd_ssize_t n);
void mpd_init(mpd_context_t *ctx, mpd_ssize_t prec);
void mpd_maxcontext(mpd_context_t *ctx);
+void mpd_maxcontext_plus(mpd_context_t *workctx, const mpd_context_t *ctx);
void mpd_defaultcontext(mpd_context_t *ctx);
void mpd_basiccontext(mpd_context_t *ctx);
int mpd_ieee_context(mpd_context_t *ctx, int bits);
@@ -265,9 +266,9 @@
/* quietly assign a C integer type to an mpd_t */
void mpd_qset_ssize(mpd_t *result, mpd_ssize_t a, const mpd_context_t *ctx, uint32_t *status);
void mpd_qset_i32(mpd_t *result, int32_t a, const mpd_context_t *ctx, uint32_t *status);
+void mpd_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, uint32_t *status);
void mpd_qset_uint(mpd_t *result, mpd_uint_t a, const mpd_context_t *ctx, uint32_t *status);
void mpd_qset_u32(mpd_t *result, uint32_t a, const mpd_context_t *ctx, uint32_t *status);
-void mpd_qset_i64(mpd_t *result, int64_t a, const mpd_context_t *ctx, uint32_t *status);
void mpd_qset_u64(mpd_t *result, uint64_t a, const mpd_context_t *ctx, uint32_t *status);
/* quietly assign a C integer type to an mpd_t with a static coefficient */
@@ -280,6 +281,7 @@
mpd_ssize_t mpd_qget_ssize(const mpd_t *dec, uint32_t *status);
int32_t mpd_qget_i32(const mpd_t *dec, uint32_t *status);
mpd_uint_t mpd_qget_uint(const mpd_t *dec, uint32_t *status);
+mpd_uint_t mpd_qabs_uint(const mpd_t *dec, uint32_t *status);
uint32_t mpd_qget_u32(const mpd_t *dec, uint32_t *status);
@@ -321,6 +323,7 @@
void mpd_qround_to_intx(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
void mpd_qround_to_int(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
+void mpd_qtrunc(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
void mpd_qfloor(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
void mpd_qceil(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
@@ -386,6 +389,106 @@
/******************************************************************************/
+/* Signalling functions */
+/******************************************************************************/
+
+char * mpd_format(const mpd_t *dec, const char *fmt, mpd_context_t *ctx);
+void mpd_import_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx);
+void mpd_import_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx);
+size_t mpd_export_u16(uint16_t *rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx);
+size_t mpd_export_u32(uint32_t *rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx);
+void mpd_finalize(mpd_t *result, mpd_context_t *ctx);
+int mpd_check_nan(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+int mpd_check_nans(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_set_string(mpd_t *result, const char *s, mpd_context_t *ctx);
+void mpd_maxcoeff(mpd_t *result, mpd_context_t *ctx);
+void mpd_sset_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx);
+void mpd_sset_i32(mpd_t *result, int32_t a, mpd_context_t *ctx);
+void mpd_sset_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx);
+void mpd_sset_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx);
+void mpd_set_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx);
+void mpd_set_i32(mpd_t *result, int32_t a, mpd_context_t *ctx);
+void mpd_set_i64(mpd_t *result, int64_t a, mpd_context_t *ctx);
+void mpd_set_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx);
+void mpd_set_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx);
+void mpd_set_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx);
+mpd_ssize_t mpd_get_ssize(const mpd_t *a, mpd_context_t *ctx);
+int32_t mpd_get_i32(const mpd_t *a, mpd_context_t *ctx);
+mpd_uint_t mpd_get_uint(const mpd_t *a, mpd_context_t *ctx);
+mpd_uint_t mpd_abs_uint(const mpd_t *a, mpd_context_t *ctx);
+uint32_t mpd_get_u32(const mpd_t *a, mpd_context_t *ctx);
+void mpd_and(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_copy(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_canonical(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_copy_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_copy_negate(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_copy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_invert(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_logb(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_or(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_rotate(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_scaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_shiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
+mpd_uint_t mpd_shiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
+void mpd_shiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
+void mpd_shift(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_xor(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+int mpd_cmp(const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+int mpd_compare(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+int mpd_compare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_add(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_add_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
+void mpd_add_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
+void mpd_add_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
+void mpd_add_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
+void mpd_sub(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_sub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
+void mpd_sub_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
+void mpd_sub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
+void mpd_sub_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
+void mpd_div(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_div_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
+void mpd_div_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
+void mpd_div_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
+void mpd_div_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
+void mpd_divmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_divint(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_exp(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_fma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, mpd_context_t *ctx);
+void mpd_ln(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_log10(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_max(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_max_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_min(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_min_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_mul(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_mul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
+void mpd_mul_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
+void mpd_mul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
+void mpd_mul_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
+void mpd_next_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_next_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_next_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_pow(mpd_t *result, const mpd_t *base, const mpd_t *exp, mpd_context_t *ctx);
+void mpd_powmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod, mpd_context_t *ctx);
+void mpd_quantize(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_rescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, mpd_context_t *ctx);
+void mpd_reduce(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_rem(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_rem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_round_to_intx(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_round_to_int(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_trunc(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_floor(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_ceil(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_sqrt(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_invroot(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+
+
+/******************************************************************************/
/* Get attributes of a decimal */
/******************************************************************************/
@@ -473,7 +576,7 @@
#define mpd_err_fatal(format, ...) \
mpd_err_doit(MPD_ERR_EXIT, "%s:%d: error: " format, __FILE__, __LINE__, ##__VA_ARGS__)
#define mpd_err_warn(format, ...) \
- mpd_err_doit(MPD_ERR_WARN, "%s:%d: error: " format, __FILE__, __LINE__, ##__VA_ARGS__)
+ mpd_err_doit(MPD_ERR_WARN, "%s:%d: warning: " format, __FILE__, __LINE__, ##__VA_ARGS__)
void mpd_err_doit(int action, const char *fmt, ...);
@@ -493,8 +596,6 @@
void *mpd_calloc(mpd_size_t nmemb, mpd_size_t size);
void *mpd_realloc(void *ptr, mpd_size_t nmemb, mpd_size_t size, uint8_t *err);
void *mpd_sh_alloc(mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size);
-void *mpd_sh_calloc(mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size);
-void *mpd_sh_realloc(void *ptr, mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size, uint8_t *err);
mpd_t *mpd_qnew(void);
mpd_t *mpd_new(mpd_context_t *ctx);
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal64.h
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal64.h (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/mpdecimal64.h Mon Nov 8 15:12:49 2010
@@ -29,7 +29,6 @@
#define MPD_BITS_PER_UINT 64
typedef uint64_t mpd_uint_t; /* unsigned mod type */
-/* enable CONFIG_32+ANSI on 64-bit platforms without resorting to -m32 */
#define MPD_SIZE_MAX SIZE_MAX
typedef size_t mpd_size_t; /* unsigned size type */
@@ -52,9 +51,9 @@
#define MPD_MAX_EMAX 999999999999999999LL /* ELIMIT-1 */
#define MPD_MIN_EMIN (-999999999999999999LL) /* -EMAX */
#define MPD_MIN_ETINY (MPD_MIN_EMIN-(MPD_MAX_PREC-1))
-#define MPD_EXP_INF (MPD_ELIMIT+1)
-#define MPD_EXP_CLAMP (2*MPD_MIN_ETINY)
-#define MPD_MAXIMPORT 105263157894736842L /* (2*MPD_MAX_PREC)/MPD_RDIGITS */
+#define MPD_EXP_INF 2000000000000000001LL
+#define MPD_EXP_CLAMP (-4000000000000000001LL)
+#define MPD_MAXIMPORT 105263157894736842L /* ceil((2*MPD_MAX_PREC)/MPD_RDIGITS) */
#if MPD_SIZE_MAX != MPD_UINT_MAX
@@ -149,11 +148,13 @@
#define MPD_MINALLOC_MAX 64
extern mpd_ssize_t MPD_MINALLOC;
extern void (* mpd_traphandler)(mpd_context_t *);
+void mpd_dflt_traphandler(mpd_context_t *);
void mpd_setminalloc(mpd_ssize_t n);
void mpd_init(mpd_context_t *ctx, mpd_ssize_t prec);
void mpd_maxcontext(mpd_context_t *ctx);
+void mpd_maxcontext_plus(mpd_context_t *workctx, const mpd_context_t *ctx);
void mpd_defaultcontext(mpd_context_t *ctx);
void mpd_basiccontext(mpd_context_t *ctx);
int mpd_ieee_context(mpd_context_t *ctx, int bits);
@@ -277,6 +278,7 @@
mpd_ssize_t mpd_qget_ssize(const mpd_t *dec, uint32_t *status);
int64_t mpd_qget_i64(const mpd_t *dec, uint32_t *status);
mpd_uint_t mpd_qget_uint(const mpd_t *dec, uint32_t *status);
+mpd_uint_t mpd_qabs_uint(const mpd_t *dec, uint32_t *status);
uint64_t mpd_qget_u64(const mpd_t *dec, uint32_t *status);
@@ -318,6 +320,7 @@
void mpd_qround_to_intx(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
void mpd_qround_to_int(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
+void mpd_qtrunc(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
void mpd_qfloor(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
void mpd_qceil(mpd_t *result, const mpd_t *a, const mpd_context_t *ctx, uint32_t *status);
@@ -391,6 +394,116 @@
/******************************************************************************/
+/* Signalling functions */
+/******************************************************************************/
+
+char * mpd_format(const mpd_t *dec, const char *fmt, mpd_context_t *ctx);
+void mpd_import_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx);
+void mpd_import_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen, uint8_t srcsign, uint32_t base, mpd_context_t *ctx);
+size_t mpd_export_u16(uint16_t *rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx);
+size_t mpd_export_u32(uint32_t *rdata, size_t rlen, uint32_t base, const mpd_t *src, mpd_context_t *ctx);
+void mpd_finalize(mpd_t *result, mpd_context_t *ctx);
+int mpd_check_nan(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+int mpd_check_nans(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_set_string(mpd_t *result, const char *s, mpd_context_t *ctx);
+void mpd_maxcoeff(mpd_t *result, mpd_context_t *ctx);
+void mpd_sset_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx);
+void mpd_sset_i32(mpd_t *result, int32_t a, mpd_context_t *ctx);
+void mpd_sset_i64(mpd_t *result, int64_t a, mpd_context_t *ctx);
+void mpd_sset_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx);
+void mpd_sset_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx);
+void mpd_sset_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx);
+void mpd_set_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx);
+void mpd_set_i32(mpd_t *result, int32_t a, mpd_context_t *ctx);
+void mpd_set_i64(mpd_t *result, int64_t a, mpd_context_t *ctx);
+void mpd_set_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx);
+void mpd_set_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx);
+void mpd_set_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx);
+mpd_ssize_t mpd_get_ssize(const mpd_t *a, mpd_context_t *ctx);
+int64_t mpd_get_i64(const mpd_t *a, mpd_context_t *ctx);
+mpd_uint_t mpd_get_uint(const mpd_t *a, mpd_context_t *ctx);
+mpd_uint_t mpd_abs_uint(const mpd_t *a, mpd_context_t *ctx);
+uint64_t mpd_get_u64(const mpd_t *a, mpd_context_t *ctx);
+void mpd_and(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_copy(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_canonical(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_copy_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_copy_negate(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_copy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_invert(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_logb(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_or(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_rotate(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_scaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_shiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
+mpd_uint_t mpd_shiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
+void mpd_shiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx);
+void mpd_shift(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_xor(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+int mpd_cmp(const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+int mpd_compare(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+int mpd_compare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_add(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_add_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
+void mpd_add_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
+void mpd_add_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
+void mpd_add_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
+void mpd_add_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
+void mpd_add_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
+void mpd_sub(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_sub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
+void mpd_sub_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
+void mpd_sub_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
+void mpd_sub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
+void mpd_sub_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
+void mpd_sub_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
+void mpd_div(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_div_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
+void mpd_div_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
+void mpd_div_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
+void mpd_div_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
+void mpd_div_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
+void mpd_div_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
+void mpd_divmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_divint(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_exp(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_fma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c, mpd_context_t *ctx);
+void mpd_ln(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_log10(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_max(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_max_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_min(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_min_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_mul(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_mul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx);
+void mpd_mul_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx);
+void mpd_mul_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx);
+void mpd_mul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx);
+void mpd_mul_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx);
+void mpd_mul_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx);
+void mpd_next_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_next_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_next_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_pow(mpd_t *result, const mpd_t *base, const mpd_t *exp, mpd_context_t *ctx);
+void mpd_powmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod, mpd_context_t *ctx);
+void mpd_quantize(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_rescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, mpd_context_t *ctx);
+void mpd_reduce(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_rem(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_rem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+void mpd_round_to_intx(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_round_to_int(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_trunc(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_floor(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_ceil(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_sqrt(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+void mpd_invroot(mpd_t *result, const mpd_t *a, mpd_context_t *ctx);
+
+
+/******************************************************************************/
/* Get attributes of a decimal */
/******************************************************************************/
@@ -478,7 +591,7 @@
#define mpd_err_fatal(format, ...) \
mpd_err_doit(MPD_ERR_EXIT, "%s:%d: error: " format, __FILE__, __LINE__, ##__VA_ARGS__)
#define mpd_err_warn(format, ...) \
- mpd_err_doit(MPD_ERR_WARN, "%s:%d: error: " format, __FILE__, __LINE__, ##__VA_ARGS__)
+ mpd_err_doit(MPD_ERR_WARN, "%s:%d: warning: " format, __FILE__, __LINE__, ##__VA_ARGS__)
void mpd_err_doit(int action, const char *fmt, ...);
@@ -498,8 +611,6 @@
void *mpd_calloc(mpd_size_t nmemb, mpd_size_t size);
void *mpd_realloc(void *ptr, mpd_size_t nmemb, mpd_size_t size, uint8_t *err);
void *mpd_sh_alloc(mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size);
-void *mpd_sh_calloc(mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size);
-void *mpd_sh_realloc(void *ptr, mpd_size_t struct_size, mpd_size_t nmemb, mpd_size_t size, uint8_t *err);
mpd_t *mpd_qnew(void);
mpd_t *mpd_new(mpd_context_t *ctx);
Added: python/branches/py3k-cdecimal/Modules/cdecimal/mpsignal.c
==============================================================================
--- (empty file)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/mpsignal.c Mon Nov 8 15:12:49 2010
@@ -0,0 +1,932 @@
+#include "mpdecimal.h"
+
+
+char *
+mpd_format(const mpd_t *dec, const char *fmt, mpd_context_t *ctx)
+{
+ char *ret;
+ uint32_t status = 0;
+ ret = mpd_qformat(dec, fmt, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+ return ret;
+}
+
+void
+mpd_import_u16(mpd_t *result, const uint16_t *srcdata, size_t srclen,
+ uint8_t srcsign, uint32_t base, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qimport_u16(result, srcdata, srclen, srcsign, base, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_import_u32(mpd_t *result, const uint32_t *srcdata, size_t srclen,
+ uint8_t srcsign, uint32_t base, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qimport_u32(result, srcdata, srclen, srcsign, base, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+size_t
+mpd_export_u16(uint16_t *rdata, size_t rlen, uint32_t base, const mpd_t *src,
+ mpd_context_t *ctx)
+{
+ size_t n;
+ uint32_t status = 0;
+ n = mpd_qexport_u16(rdata, rlen, base, src, &status);
+ mpd_addstatus_raise(ctx, status);
+ return n;
+}
+
+size_t
+mpd_export_u32(uint32_t *rdata, size_t rlen, uint32_t base, const mpd_t *src,
+ mpd_context_t *ctx)
+{
+ size_t n;
+ uint32_t status = 0;
+ n = mpd_qexport_u32(rdata, rlen, base, src, &status);
+ mpd_addstatus_raise(ctx, status);
+ return n;
+}
+
+void
+mpd_finalize(mpd_t *result, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qfinalize(result, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+int
+mpd_check_nan(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ if (mpd_qcheck_nan(result, a, ctx, &status)) {
+ mpd_addstatus_raise(ctx, status);
+ return 1;
+ }
+ return 0;
+}
+
+int
+mpd_check_nans(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ if (mpd_qcheck_nans(result, a, b, ctx, &status)) {
+ mpd_addstatus_raise(ctx, status);
+ return 1;
+ }
+ return 0;
+}
+
+void
+mpd_set_string(mpd_t *result, const char *s, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qset_string(result, s, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_maxcoeff(mpd_t *result, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qmaxcoeff(result, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+/* set static mpd from signed integer */
+void
+mpd_sset_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qsset_ssize(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_sset_i32(mpd_t *result, int32_t a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qsset_i32(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+#ifdef CONFIG_64
+void
+mpd_sset_i64(mpd_t *result, int64_t a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qsset_i64(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+/* set static mpd from unsigned integer */
+void
+mpd_sset_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qsset_uint(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_sset_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qsset_u32(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+#ifdef CONFIG_64
+void
+mpd_sset_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qsset_u64(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+/* set mpd from signed integer */
+void
+mpd_set_ssize(mpd_t *result, mpd_ssize_t a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qset_ssize(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_set_i32(mpd_t *result, int32_t a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qset_i32(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_set_i64(mpd_t *result, int64_t a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qset_i64(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+/* set mpd from unsigned integer */
+void
+mpd_set_uint(mpd_t *result, mpd_uint_t a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qset_uint(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_set_u32(mpd_t *result, uint32_t a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qset_u32(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_set_u64(mpd_t *result, uint64_t a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qset_u64(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+/* convert mpd to signed integer */
+mpd_ssize_t
+mpd_get_ssize(const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_ssize_t ret;
+
+ ret = mpd_qget_ssize(a, &status);
+ mpd_addstatus_raise(ctx, status);
+ return ret;
+}
+
+#ifdef CONFIG_32
+int32_t
+mpd_get_i32(const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ int32_t ret;
+
+ ret = mpd_qget_i32(a, &status);
+ mpd_addstatus_raise(ctx, status);
+ return ret;
+}
+#else
+int64_t
+mpd_get_i64(const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ int64_t ret;
+
+ ret = mpd_qget_i64(a, &status);
+ mpd_addstatus_raise(ctx, status);
+ return ret;
+}
+#endif
+
+mpd_uint_t
+mpd_get_uint(const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_uint_t ret;
+
+ ret = mpd_qget_uint(a, &status);
+ mpd_addstatus_raise(ctx, status);
+ return ret;
+}
+
+mpd_uint_t
+mpd_abs_uint(const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_uint_t ret;
+
+ ret = mpd_qabs_uint(a, &status);
+ mpd_addstatus_raise(ctx, status);
+ return ret;
+}
+
+#ifdef CONFIG_32
+uint32_t
+mpd_get_u32(const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ uint32_t ret;
+
+ ret = mpd_qget_u32(a, &status);
+ mpd_addstatus_raise(ctx, status);
+ return ret;
+}
+#else
+uint64_t
+mpd_get_u64(const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ uint64_t ret;
+
+ ret = mpd_qget_u64(a, &status);
+ mpd_addstatus_raise(ctx, status);
+ return ret;
+}
+#endif
+
+void
+mpd_and(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qand(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_copy(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ if (!mpd_qcopy(result, a, &status)) {
+ mpd_addstatus_raise(ctx, status);
+ }
+}
+
+void
+mpd_canonical(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ mpd_copy(result, a, ctx);
+}
+
+void
+mpd_copy_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ if (!mpd_qcopy_abs(result, a, &status)) {
+ mpd_addstatus_raise(ctx, status);
+ }
+}
+
+void
+mpd_copy_negate(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ if (!mpd_qcopy_negate(result, a, &status)) {
+ mpd_addstatus_raise(ctx, status);
+ }
+}
+
+void
+mpd_copy_sign(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ if (!mpd_qcopy_sign(result, a, b, &status)) {
+ mpd_addstatus_raise(ctx, status);
+ }
+}
+
+void
+mpd_invert(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qinvert(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_logb(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qlogb(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_or(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qor(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_rotate(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qrotate(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_scaleb(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qscaleb(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_shiftl(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qshiftl(result, a, n, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+mpd_uint_t
+mpd_shiftr(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_uint_t rnd;
+
+ rnd = mpd_qshiftr(result, a, n, &status);
+ mpd_addstatus_raise(ctx, status);
+ return rnd;
+}
+
+void
+mpd_shiftn(mpd_t *result, const mpd_t *a, mpd_ssize_t n, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qshiftn(result, a, n, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_shift(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qshift(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_xor(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qxor(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_abs(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qabs(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+int
+mpd_cmp(const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ int c;
+ c = mpd_qcmp(a, b, &status);
+ mpd_addstatus_raise(ctx, status);
+ return c;
+}
+
+int
+mpd_compare(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ int c;
+ c = mpd_qcompare(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+ return c;
+}
+
+int
+mpd_compare_signal(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ int c;
+ c = mpd_qcompare_signal(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+ return c;
+}
+
+void
+mpd_add(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qadd(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_sub(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qsub(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_add_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qadd_ssize(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_add_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qadd_i32(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+#ifdef CONFIG_64
+void
+mpd_add_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qadd_i64(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_add_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qadd_uint(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_add_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qadd_u32(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+#ifdef CONFIG_64
+void
+mpd_add_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qadd_u64(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_sub_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qsub_ssize(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_sub_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qsub_i32(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+#ifdef CONFIG_64
+void
+mpd_sub_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qsub_i64(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_sub_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qsub_uint(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_sub_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qsub_u32(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+#ifdef CONFIG_64
+void
+mpd_sub_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qsub_u64(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_div(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qdiv(q, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_div_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qdiv_ssize(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_div_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qdiv_i32(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+#ifdef CONFIG_64
+void
+mpd_div_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qdiv_i64(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_div_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qdiv_uint(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_div_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qdiv_u32(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+#ifdef CONFIG_64
+void
+mpd_div_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qdiv_u64(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_divmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qdivmod(q, r, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_divint(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qdivint(q, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_exp(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qexp(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_fma(mpd_t *result, const mpd_t *a, const mpd_t *b, const mpd_t *c,
+ mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qfma(result, a, b, c, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_ln(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qln(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_log10(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qlog10(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_max(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qmax(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_max_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qmax_mag(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_min(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qmin(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_min_mag(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qmin_mag(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qminus(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_mul(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qmul(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_mul_ssize(mpd_t *result, const mpd_t *a, mpd_ssize_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qmul_ssize(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_mul_i32(mpd_t *result, const mpd_t *a, int32_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qmul_i32(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+#ifdef CONFIG_64
+void
+mpd_mul_i64(mpd_t *result, const mpd_t *a, int64_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qmul_i64(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_mul_uint(mpd_t *result, const mpd_t *a, mpd_uint_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qmul_uint(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_mul_u32(mpd_t *result, const mpd_t *a, uint32_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qmul_u32(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+#ifdef CONFIG_64
+void
+mpd_mul_u64(mpd_t *result, const mpd_t *a, uint64_t b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qmul_u64(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+#endif
+
+void
+mpd_next_minus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qnext_minus(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_next_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qnext_plus(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_next_toward(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qnext_toward(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_plus(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qplus(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_pow(mpd_t *result, const mpd_t *base, const mpd_t *exp, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qpow(result, base, exp, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_powmod(mpd_t *result, const mpd_t *base, const mpd_t *exp, const mpd_t *mod,
+ mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qpowmod(result, base, exp, mod, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_quantize(mpd_t *result, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qquantize(result, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_rescale(mpd_t *result, const mpd_t *a, mpd_ssize_t exp, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qrescale(result, a, exp, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_reduce(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qreduce(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_rem(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qrem(r, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_rem_near(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qrem_near(r, a, b, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_round_to_intx(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qround_to_intx(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_round_to_int(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qround_to_int(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_trunc(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qtrunc(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_floor(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qfloor(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_ceil(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qceil(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_sqrt(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qsqrt(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+void
+mpd_invroot(mpd_t *result, const mpd_t *a, mpd_context_t *ctx)
+{
+ uint32_t status = 0;
+ mpd_qinvroot(result, a, ctx, &status);
+ mpd_addstatus_raise(ctx, status);
+}
+
+
+
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mptest.h
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/mptest.h (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/mptest.h Mon Nov 8 15:12:49 2010
@@ -9,21 +9,24 @@
#include "mpdecimal.h"
+#ifndef _MSC_VER
+ #define IMPORTEXPORT
+#endif
/* newton division undergoes the same rigorous tests as standard division */
-void mpd_qtest_newtondiv(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
-void mpd_qtest_newtondivint(mpd_t *q, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
-void mpd_qtest_newtonrem(mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
-void mpd_qtest_newtondivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, const mpd_context_t *ctx, uint32_t *status);
+IMPORTEXPORT void mpd_test_newtondiv(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+IMPORTEXPORT void mpd_test_newtondivint(mpd_t *q, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+IMPORTEXPORT void mpd_test_newtonrem(mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
+IMPORTEXPORT void mpd_test_newtondivmod(mpd_t *q, mpd_t *r, const mpd_t *a, const mpd_t *b, mpd_context_t *ctx);
/* fenv */
-unsigned int mpd_set_fenv(void);
-void mpd_restore_fenv(unsigned int);
+IMPORTEXPORT unsigned int mpd_set_fenv(void);
+IMPORTEXPORT void mpd_restore_fenv(unsigned int);
-mpd_uint_t *_mpd_fntmul(const mpd_uint_t *u, const mpd_uint_t *v, mpd_size_t ulen, mpd_size_t vlen, mpd_size_t *rsize);
-mpd_uint_t *_mpd_kmul(const mpd_uint_t *u, const mpd_uint_t *v, mpd_size_t ulen, mpd_size_t vlen, mpd_size_t *rsize);
-mpd_uint_t *_mpd_kmul_fnt(const mpd_uint_t *u, const mpd_uint_t *v, mpd_size_t ulen, mpd_size_t vlen, mpd_size_t *rsize);
+IMPORTEXPORT mpd_uint_t *_mpd_fntmul(const mpd_uint_t *u, const mpd_uint_t *v, mpd_size_t ulen, mpd_size_t vlen, mpd_size_t *rsize);
+IMPORTEXPORT mpd_uint_t *_mpd_kmul(const mpd_uint_t *u, const mpd_uint_t *v, mpd_size_t ulen, mpd_size_t vlen, mpd_size_t *rsize);
+IMPORTEXPORT mpd_uint_t *_mpd_kmul_fnt(const mpd_uint_t *u, const mpd_uint_t *v, mpd_size_t ulen, mpd_size_t vlen, mpd_size_t *rsize);
#endif
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/mptypes.h
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/mptypes.h (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/mptypes.h Mon Nov 8 15:12:49 2010
@@ -7,6 +7,12 @@
#ifndef MPTYPES_H
#define MPTYPES_H
+#if defined(_MSC_VER)
+ #define PRIi64 "lld"
+ #define PRIu64 "llu"
+ #define PRIi32 "d"
+ #define PRIu32 "u"
+#endif
#if defined(CONFIG_64)
#if defined(_MSC_VER) || defined(__OpenBSD__)
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/numbertheory.h
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/numbertheory.h (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/numbertheory.h Mon Nov 8 15:12:49 2010
@@ -27,13 +27,6 @@
void _mpd_init_w3table(mpd_uint_t w3table[3], int sign, int modnum);
-static inline void
-std_setmodulus(int modnum, mpd_uint_t *umod)
-{
- *umod = mpd_moduli[modnum];
-}
-
-
#ifdef PPRO
static inline void
ppro_setmodulus(int modnum, mpd_uint_t *umod, double *dmod, uint32_t dinvmod[3])
@@ -43,6 +36,12 @@
dinvmod[1] = mpd_invmoduli[modnum][1];
dinvmod[2] = mpd_invmoduli[modnum][2];
}
+#else
+static inline void
+std_setmodulus(int modnum, mpd_uint_t *umod)
+{
+ *umod = mpd_moduli[modnum];
+}
#endif
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/sixstep.c
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/sixstep.c (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/sixstep.c Mon Nov 8 15:12:49 2010
@@ -29,7 +29,7 @@
/* forward transform with sign = -1 */
int
-six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum, int ordered)
+six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
{
struct fnt_params *tparams;
mpd_size_t log2n, C, R;
@@ -47,12 +47,15 @@
assert(n >= 16);
assert(n <= MPD_MAXTRANSFORM_2N);
- log2n = BSR(n);
+ log2n = mpd_bsr(n);
C = (ONE_UM << (log2n / 2)); /* number of columns */
R = (ONE_UM << (log2n - (log2n / 2))); /* number of rows */
- transpose_pow2(a, R, C); /* view a as a RxC matrix, tranpose */
+ /* view 'a' as an RxC matrix, transpose */
+ if (!transpose_pow2(a, R, C)) {
+ return 0;
+ }
if ((tparams = _mpd_init_fnt_params(R, -1, modnum)) == NULL) {
return 0;
@@ -61,7 +64,10 @@
fnt_dif2(x, R, tparams);
}
- transpose_pow2(a, C, R);
+ if (!transpose_pow2(a, C, R)) {
+ mpd_free(tparams);
+ return 0;
+ }
SETMODULUS(modnum);
@@ -93,9 +99,14 @@
mpd_free(tparams);
+#if 0
+ /* An unordered transform is sufficient for convolution. */
if (ordered) {
- transpose_pow2(a, R, C);
+ if (!transpose_pow2(a, R, C)) {
+ return 0;
+ }
}
+#endif
return 1;
}
@@ -103,7 +114,7 @@
/* reverse transform, sign = 1 */
int
-inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum, int ordered)
+inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum)
{
struct fnt_params *tparams;
mpd_size_t log2n, C, R;
@@ -121,14 +132,19 @@
assert(n >= 16);
assert(n <= MPD_MAXTRANSFORM_2N);
- log2n = BSR(n);
+ log2n = mpd_bsr(n);
C = (ONE_UM << (log2n / 2)); /* number of columns */
R = (ONE_UM << (log2n - (log2n / 2))); /* number of rows */
+#if 0
+ /* An unordered transform is sufficient for convolution. */
if (ordered) {
- transpose_pow2(a, C, R);
+ if (!transpose_pow2(a, C, R)) {
+ return 0;
+ }
}
+#endif
if ((tparams = _mpd_init_fnt_params(C, 1, modnum)) == NULL) {
return 0;
@@ -137,7 +153,10 @@
fnt_dif2(x, C, tparams);
}
- transpose_pow2(a, R, C);
+ if (!transpose_pow2(a, R, C)) {
+ mpd_free(tparams);
+ return 0;
+ }
SETMODULUS(modnum);
@@ -168,7 +187,9 @@
}
mpd_free(tparams);
- transpose_pow2(a, C, R);
+ if (!transpose_pow2(a, C, R)) {
+ return 0;
+ }
return 1;
}
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/sixstep.h
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/sixstep.h (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/sixstep.h Mon Nov 8 15:12:49 2010
@@ -12,8 +12,8 @@
#include <stdio.h>
-int six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum, int ordered);
-int inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum, int ordered);
+int six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum);
+int inv_six_step_fnt(mpd_uint_t *a, mpd_size_t n, int modnum);
#endif
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/transpose.c
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/transpose.c (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/transpose.c Mon Nov 8 15:12:49 2010
@@ -66,7 +66,7 @@
r = 2;
}
else {
- mpd_err_fatal("swap_halfrows_pow2: illegal argument for \"dir\"");
+ abort(); /* GCOV_NOT_REACHED */
}
m = cols - 1;
@@ -241,7 +241,7 @@
}
}
else {
- mpd_err_fatal("transpose_pow2: illegal matrix size");
+ abort(); /* GCOV_NOT_REACHED */
}
return 1;
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/typearith.h
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/typearith.h (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/typearith.h Mon Nov 8 15:12:49 2010
@@ -22,7 +22,164 @@
*/
#if defined(CONFIG_64)
-#if defined(__GNUC__) && defined(__x86_64__) && !defined(TEST_UINT128_T)
+#if defined(ANSI)
+#if defined(HAVE_UINT128_T)
+static inline void
+_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b)
+{
+ __uint128_t hl;
+
+ hl = (__uint128_t)a * b;
+
+ *hi = hl >> 64;
+ *lo = (mpd_uint_t)hl;
+}
+
+static inline void
+_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo,
+ mpd_uint_t d)
+{
+ __uint128_t hl;
+
+ hl = ((__uint128_t)hi<<64) + lo;
+ *q = (mpd_uint_t)(hl / d); /* quotient is known to fit */
+ *r = (mpd_uint_t)(hl - (__uint128_t)(*q) * d);
+}
+#else
+static inline void
+_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b)
+{
+ uint32_t w[4], carry;
+ uint32_t ah, al, bh, bl;
+ uint64_t hl;
+
+ ah = (uint32_t)(a>>32); al = (uint32_t)a;
+ bh = (uint32_t)(b>>32); bl = (uint32_t)b;
+
+ hl = (uint64_t)al * bl;
+ w[0] = (uint32_t)hl;
+ carry = (uint32_t)(hl>>32);
+
+ hl = (uint64_t)ah * bl + carry;
+ w[1] = (uint32_t)hl;
+ w[2] = (uint32_t)(hl>>32);
+
+ hl = (uint64_t)al * bh + w[1];
+ w[1] = (uint32_t)hl;
+ carry = (uint32_t)(hl>>32);
+
+ hl = ((uint64_t)ah * bh + w[2]) + carry;
+ w[2] = (uint32_t)hl;
+ w[3] = (uint32_t)(hl>>32);
+
+ *hi = ((uint64_t)w[3]<<32) + w[2];
+ *lo = ((uint64_t)w[1]<<32) + w[0];
+}
+
+/*
+ * By Henry S. Warren: http://www.hackersdelight.org/HDcode/divlu.c.txt
+ * http://www.hackersdelight.org/permissions.htm:
+ * "You are free to use, copy, and distribute any of the code on this web
+ * site, whether modified by you or not. You need not give attribution."
+ *
+ * Slightly modified, comments are mine.
+ */
+static inline int
+nlz(uint64_t x)
+{
+ int n;
+
+ if (x == 0) return(64);
+
+ n = 0;
+ if (x <= 0x00000000FFFFFFFF) {n = n +32; x = x <<32;}
+ if (x <= 0x0000FFFFFFFFFFFF) {n = n +16; x = x <<16;}
+ if (x <= 0x00FFFFFFFFFFFFFF) {n = n + 8; x = x << 8;}
+ if (x <= 0x0FFFFFFFFFFFFFFF) {n = n + 4; x = x << 4;}
+ if (x <= 0x3FFFFFFFFFFFFFFF) {n = n + 2; x = x << 2;}
+ if (x <= 0x7FFFFFFFFFFFFFFF) {n = n + 1;}
+
+ return n;
+}
+
+static inline void
+_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t u1, mpd_uint_t u0,
+ mpd_uint_t v)
+{
+ const mpd_uint_t b = 4294967296;
+ mpd_uint_t un1, un0,
+ vn1, vn0,
+ q1, q0,
+ un32, un21, un10,
+ rhat, t;
+ int s;
+
+ assert(u1 < v);
+
+ s = nlz(v);
+ v = v << s;
+ vn1 = v >> 32;
+ vn0 = v & 0xFFFFFFFF;
+
+ t = (s == 0) ? 0 : u0 >> (64 - s);
+ un32 = (u1 << s) | t;
+ un10 = u0 << s;
+
+ un1 = un10 >> 32;
+ un0 = un10 & 0xFFFFFFFF;
+
+ q1 = un32 / vn1;
+ rhat = un32 - q1*vn1;
+again1:
+ if (q1 >= b || q1*vn0 > b*rhat + un1) {
+ q1 = q1 - 1;
+ rhat = rhat + vn1;
+ if (rhat < b) goto again1;
+ }
+
+ /*
+ * Before again1 we had:
+ * (1) q1*vn1 + rhat = un32
+ * (2) q1*vn1*b + rhat*b + un1 = un32*b + un1
+ *
+ * The statements inside the if-clause do not change the value
+ * of the left-hand side of (2), and the loop is only exited
+ * if q1*vn0 <= rhat*b + un1, so:
+ *
+ * (3) q1*vn1*b + q1*vn0 <= un32*b + un1
+ * (4) q1*v <= un32*b + un1
+ * (5) 0 <= un32*b + un1 - q1*v
+ *
+ * By (5) we are certain that the possible add-back step from
+ * Knuth's algorithm D is never required.
+ *
+ * Since the final quotient is less than 2**64, the following
+ * must be true:
+ *
+ * (6) un32*b + un1 - q1*v <= UINT64_MAX
+ *
+ * This means that in the following line, the high words
+ * of un32*b and q1*v can be discarded without any effect
+ * on the result.
+ */
+ un21 = un32*b + un1 - q1*v;
+
+ q0 = un21 / vn1;
+ rhat = un21 - q0*vn1;
+again2:
+ if (q0 >= b || q0*vn0 > b*rhat + un0) {
+ q0 = q0 - 1;
+ rhat = rhat + vn1;
+ if (rhat < b) goto again2;
+ }
+
+ *q = q1*b + q0;
+ *r = (un21*b + un0 - q0*v) >> s;
+}
+#endif
+
+/* END ANSI */
+#elif defined(ASM)
static inline void
_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b)
{
@@ -53,31 +210,8 @@
*q = qq;
*r = rr;
}
-/* END __GNUC__ (amd64) */
-#elif defined(HAVE_UINT128_T)
-static inline void
-_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b)
-{
- __uint128_t hl;
-
- hl = (__uint128_t)a * b;
-
- *hi = hl >> 64;
- *lo = (mpd_uint_t)hl;
-}
-
-static inline void
-_mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo,
- mpd_uint_t d)
-{
- __uint128_t hl;
-
- hl = ((__uint128_t)hi<<64) + lo;
- *q = (mpd_uint_t)(hl / d); /* quotient is known to fit */
- *r = (mpd_uint_t)(hl - (__uint128_t)(*q) * d);
-}
-/* END HAVE_UINT128_T */
-#elif defined(_MSC_VER)
+/* END GCC ASM */
+#elif defined(MASM)
#include <intrin.h>
#pragma intrinsic(_umul128)
@@ -89,8 +223,8 @@
void _mpd_div_words(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t hi, mpd_uint_t lo,
mpd_uint_t d);
-/* END _MSC_VER (amd64) */
+/* END MASM (_MSC_VER) */
#else
#error "need platform specific 128 bit multiplication and division"
#endif
@@ -98,51 +232,51 @@
static inline void
_mpd_divmod_pow10(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t v, mpd_uint_t exp)
{
- assert(exp <= 19);
+ assert(exp <= 19);
- if (exp <= 9) {
- if (exp <= 4) {
- switch (exp) {
- case 0: *q = v; *r = 0; break;
- case 1: *q = v / 10ULL; *r = v - *q * 10ULL; break;
- case 2: *q = v / 100ULL; *r = v - *q * 100ULL; break;
- case 3: *q = v / 1000ULL; *r = v - *q * 1000ULL; break;
- case 4: *q = v / 10000ULL; *r = v - *q * 10000ULL; break;
- }
- }
- else {
- switch (exp) {
- case 5: *q = v / 100000ULL; *r = v - *q * 100000ULL; break;
- case 6: *q = v / 1000000ULL; *r = v - *q * 1000000ULL; break;
- case 7: *q = v / 10000000ULL; *r = v - *q * 10000000ULL; break;
- case 8: *q = v / 100000000ULL; *r = v - *q * 100000000ULL; break;
- case 9: *q = v / 1000000000ULL; *r = v - *q * 1000000000ULL; break;
- }
- }
- }
- else {
- if (exp <= 14) {
- switch (exp) {
- case 10: *q = v / 10000000000ULL; *r = v - *q * 10000000000ULL; break;
- case 11: *q = v / 100000000000ULL; *r = v - *q * 100000000000ULL; break;
- case 12: *q = v / 1000000000000ULL; *r = v - *q * 1000000000000ULL; break;
- case 13: *q = v / 10000000000000ULL; *r = v - *q * 10000000000000ULL; break;
- case 14: *q = v / 100000000000000ULL; *r = v - *q * 100000000000000ULL; break;
- }
- }
- else {
- switch (exp) {
- case 15: *q = v / 1000000000000000ULL; *r = v - *q * 1000000000000000ULL; break;
- case 16: *q = v / 10000000000000000ULL; *r = v - *q * 10000000000000000ULL; break;
- case 17: *q = v / 100000000000000000ULL; *r = v - *q * 100000000000000000ULL; break;
- case 18: *q = v / 1000000000000000000ULL; *r = v - *q * 1000000000000000000ULL; break;
- case 19: *q = v / 10000000000000000000ULL; *r = v - *q * 10000000000000000000ULL; break;
- }
- }
- }
+ if (exp <= 9) {
+ if (exp <= 4) {
+ switch (exp) {
+ case 0: *q = v; *r = 0; break;
+ case 1: *q = v / 10ULL; *r = v - *q * 10ULL; break;
+ case 2: *q = v / 100ULL; *r = v - *q * 100ULL; break;
+ case 3: *q = v / 1000ULL; *r = v - *q * 1000ULL; break;
+ case 4: *q = v / 10000ULL; *r = v - *q * 10000ULL; break;
+ }
+ }
+ else {
+ switch (exp) {
+ case 5: *q = v / 100000ULL; *r = v - *q * 100000ULL; break;
+ case 6: *q = v / 1000000ULL; *r = v - *q * 1000000ULL; break;
+ case 7: *q = v / 10000000ULL; *r = v - *q * 10000000ULL; break;
+ case 8: *q = v / 100000000ULL; *r = v - *q * 100000000ULL; break;
+ case 9: *q = v / 1000000000ULL; *r = v - *q * 1000000000ULL; break;
+ }
+ }
+ }
+ else {
+ if (exp <= 14) {
+ switch (exp) {
+ case 10: *q = v / 10000000000ULL; *r = v - *q * 10000000000ULL; break;
+ case 11: *q = v / 100000000000ULL; *r = v - *q * 100000000000ULL; break;
+ case 12: *q = v / 1000000000000ULL; *r = v - *q * 1000000000000ULL; break;
+ case 13: *q = v / 10000000000000ULL; *r = v - *q * 10000000000000ULL; break;
+ case 14: *q = v / 100000000000000ULL; *r = v - *q * 100000000000000ULL; break;
+ }
+ }
+ else {
+ switch (exp) {
+ case 15: *q = v / 1000000000000000ULL; *r = v - *q * 1000000000000000ULL; break;
+ case 16: *q = v / 10000000000000000ULL; *r = v - *q * 10000000000000000ULL; break;
+ case 17: *q = v / 100000000000000000ULL; *r = v - *q * 100000000000000000ULL; break;
+ case 18: *q = v / 1000000000000000000ULL; *r = v - *q * 1000000000000000000ULL; break;
+ case 19: *q = v / 10000000000000000000ULL; *r = v - *q * 10000000000000000000ULL; break; /* GCOV_NOT_REACHED */
+ }
+ }
+ }
}
-/* END CONFIG_64 */
+/* END CONFIG_64 */
#elif defined(CONFIG_32)
#if defined(ANSI)
#if !defined(LEGACY_COMPILER)
@@ -179,19 +313,19 @@
ah = (uint16_t)(a>>16); al = (uint16_t)a;
bh = (uint16_t)(b>>16); bl = (uint16_t)b;
- hl = al * bl;
+ hl = (uint32_t)al * bl;
w[0] = (uint16_t)hl;
carry = (uint16_t)(hl>>16);
- hl = ah * bl + carry;
+ hl = (uint32_t)ah * bl + carry;
w[1] = (uint16_t)hl;
w[2] = (uint16_t)(hl>>16);
- hl = al * bh + w[1];
+ hl = (uint32_t)al * bh + w[1];
w[1] = (uint16_t)hl;
carry = (uint16_t)(hl>>16);
- hl = ah * bh + w[2] + carry;
+ hl = ((uint32_t)ah * bh + w[2]) + carry;
w[2] = (uint16_t)hl;
w[3] = (uint16_t)(hl>>16);
@@ -200,7 +334,7 @@
}
/*
- * By Henry S. Warren: http://www.hackersdelight.org/HDcode/divlu.c
+ * By Henry S. Warren: http://www.hackersdelight.org/HDcode/divlu.c.txt
* http://www.hackersdelight.org/permissions.htm:
* "You are free to use, copy, and distribute any of the code on this web
* site, whether modified by you or not. You need not give attribution."
@@ -233,7 +367,7 @@
vn1, vn0,
q1, q0,
un32, un21, un10,
- rhat;
+ rhat, t;
int s;
assert(u1 < v);
@@ -243,7 +377,8 @@
vn1 = v >> 16;
vn0 = v & 0xFFFF;
- un32 = (u1 << s) | (u0 >> (32 - s));
+ t = (s == 0) ? 0 : u0 >> (32 - s);
+ un32 = (u1 << s) | t;
un10 = u0 << s;
un1 = un10 >> 16;
@@ -300,14 +435,13 @@
#endif /* END ANSI + LEGACY_COMPILER */
/* END ANSI */
-
-#elif defined(__GNUC__) && defined(__i386__)
+#elif defined(ASM)
static inline void
_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b)
{
mpd_uint_t h, l;
- asm( "mull %3\n\t"\
+ asm ( "mull %3\n\t"\
: "=d" (h), "=a" (l)\
: "%a" (a), "rm" (b)\
: "cc"
@@ -332,9 +466,8 @@
*q = qq;
*r = rr;
}
-/* END __GNUC__ (i386) */
-
-#elif defined(_MSC_VER)
+/* END GCC ASM */
+#elif defined(MASM)
static inline void __cdecl
_mpd_mul_words(mpd_uint_t *hi, mpd_uint_t *lo, mpd_uint_t a, mpd_uint_t b)
{
@@ -368,8 +501,7 @@
*q = qq;
*r = rr;
}
-/* END _MSC_VER (i386) */
-
+/* END MASM (_MSC_VER) */
#else
#error "need platform specific 64 bit multiplication and division"
#endif
@@ -377,26 +509,26 @@
static inline void
_mpd_divmod_pow10(mpd_uint_t *q, mpd_uint_t *r, mpd_uint_t v, mpd_uint_t exp)
{
- assert(exp <= 9);
+ assert(exp <= 9);
- if (exp <= 4) {
- switch (exp) {
- case 0: *q = v; *r = 0; break;
- case 1: *q = v / 10ULL; *r = v - *q * 10ULL; break;
- case 2: *q = v / 100ULL; *r = v - *q * 100ULL; break;
- case 3: *q = v / 1000ULL; *r = v - *q * 1000ULL; break;
- case 4: *q = v / 10000ULL; *r = v - *q * 10000ULL; break;
- }
- }
- else {
- switch (exp) {
- case 5: *q = v / 100000ULL; *r = v - *q * 100000ULL; break;
- case 6: *q = v / 1000000ULL; *r = v - *q * 1000000ULL; break;
- case 7: *q = v / 10000000ULL; *r = v - *q * 10000000ULL; break;
- case 8: *q = v / 100000000ULL; *r = v - *q * 100000000ULL; break;
- case 9: *q = v / 1000000000ULL; *r = v - *q * 1000000000ULL; break;
- }
- }
+ if (exp <= 4) {
+ switch (exp) {
+ case 0: *q = v; *r = 0; break;
+ case 1: *q = v / 10ULL; *r = v - *q * 10ULL; break;
+ case 2: *q = v / 100ULL; *r = v - *q * 100ULL; break;
+ case 3: *q = v / 1000ULL; *r = v - *q * 1000ULL; break;
+ case 4: *q = v / 10000ULL; *r = v - *q * 10000ULL; break;
+ }
+ }
+ else {
+ switch (exp) {
+ case 5: *q = v / 100000ULL; *r = v - *q * 100000ULL; break;
+ case 6: *q = v / 1000000ULL; *r = v - *q * 1000000ULL; break;
+ case 7: *q = v / 10000000ULL; *r = v - *q * 10000000ULL; break;
+ case 8: *q = v / 100000000ULL; *r = v - *q * 100000000ULL; break;
+ case 9: *q = v / 1000000000ULL; *r = v - *q * 1000000000ULL; break; /* GCOV_NOT_REACHED */
+ }
+ }
}
/* END CONFIG_32 */
@@ -429,7 +561,7 @@
add_size_t(mpd_size_t a, mpd_size_t b)
{
if (a > MPD_SIZE_MAX - b) {
- mpd_err_fatal("add_size_t(): overflow: check the context");
+ mpd_err_fatal("add_size_t(): overflow: check the context"); /* GCOV_NOT_REACHED */
}
return a + b;
}
@@ -438,7 +570,7 @@
sub_size_t(mpd_size_t a, mpd_size_t b)
{
if (b > a) {
- mpd_err_fatal("sub_size_t(): overflow: check the context");
+ mpd_err_fatal("sub_size_t(): overflow: check the context"); /* GCOV_NOT_REACHED */
}
return a - b;
}
@@ -454,7 +586,7 @@
_mpd_mul_words(&hi, &lo, (mpd_uint_t)a, (mpd_uint_t)b);
if (hi) {
- mpd_err_fatal("mul_size_t(): overflow: check the context");
+ mpd_err_fatal("mul_size_t(): overflow: check the context"); /* GCOV_NOT_REACHED */
}
return lo;
}
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/umodarith.h
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/umodarith.h (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/umodarith.h Mon Nov 8 15:12:49 2010
@@ -92,87 +92,19 @@
return d;
}
-
-#if defined(ANSI)
-#if !defined(LEGACY_COMPILER)
-/* HAVE_UINT64_T */
-static inline
-mpd_uint_t std_mulmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m)
-{
- return ((mpd_uuint_t) a * b) % m;
-}
-
-static inline void
-std_mulmod2c(mpd_uint_t *a, mpd_uint_t *b, mpd_uint_t w, mpd_uint_t m)
-{
- *a = ((mpd_uuint_t) *a * w) % m;
- *b = ((mpd_uuint_t) *b * w) % m;
-}
-
-static inline void
-std_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1,
- mpd_uint_t m)
-{
- *a0 = ((mpd_uuint_t) *a0 * b0) % m;
- *a1 = ((mpd_uuint_t) *a1 * b1) % m;
-}
-/* END HAVE_UINT64_T */
-#else
-/* LEGACY_COMPILER */
-static inline
-mpd_uint_t std_mulmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m)
-{
- mpd_uint_t hi, lo, q, r;
- _mpd_mul_words(&hi, &lo, a, b);
- _mpd_div_words(&q, &r, hi, lo, m);
- return r;
-}
-
-static inline void
-std_mulmod2c(mpd_uint_t *a, mpd_uint_t *b, mpd_uint_t w, mpd_uint_t m)
-{
- *a = std_mulmod(*a, w, m);
- *b = std_mulmod(*b, w, m);
-}
-
-static inline void
-std_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1,
- mpd_uint_t m)
-{
- *a0 = std_mulmod(*a0, b0, m);
- *a1 = std_mulmod(*a1, b1, m);
-}
-#endif /* LEGACY_COMPILER */
-
-static inline
-mpd_uint_t std_powmod(mpd_uint_t base, mpd_uint_t exp, mpd_uint_t umod)
-{
- mpd_uint_t r = 1;
-
- while (exp > 0) {
- if (exp & 1)
- r = std_mulmod(r, base, umod);
- base = std_mulmod(base, base, umod);
- exp >>= 1;
- }
-
- return r;
-}
-#endif /* ANSI */
-
+#ifdef CONFIG_64
/**************************************************************************/
-/* x64 modular arithmetic */
+/* 64-bit modular arithmetic */
/**************************************************************************/
/*
- * Description of the algorithm in apfloat.pdf, Chapter 7.1.1, by Mikko Tommila.
- * http://www.apfloat.org/apfloat/2.41/
+ * Description of the algorithm in apfloat.pdf, Chapter 7.1.1,
+ * by Mikko Tommila: http://www.apfloat.org/apfloat/2.41/
*
* ACL2 proof: umodarith.lisp: section "Fast modular reduction"
- */
+ */
-#ifdef CONFIG_64
static inline mpd_uint_t
x64_mulmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m)
{
@@ -298,8 +230,8 @@
*a1 = x64_mulmod(*a1, b1, m);
}
-static inline
-mpd_uint_t x64_powmod(mpd_uint_t base, mpd_uint_t exp, mpd_uint_t umod)
+static inline mpd_uint_t
+x64_powmod(mpd_uint_t base, mpd_uint_t exp, mpd_uint_t umod)
{
mpd_uint_t r = 1;
@@ -312,8 +244,83 @@
return r;
}
+
+/* END CONFIG_64 */
+#else /* CONFIG_32 */
+
+
+/**************************************************************************/
+/* 32-bit modular arithmetic */
+/**************************************************************************/
+
+#if defined(ANSI)
+#if !defined(LEGACY_COMPILER)
+/* HAVE_UINT64_T */
+static inline mpd_uint_t
+std_mulmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m)
+{
+ return ((mpd_uuint_t) a * b) % m;
+}
+
+static inline void
+std_mulmod2c(mpd_uint_t *a, mpd_uint_t *b, mpd_uint_t w, mpd_uint_t m)
+{
+ *a = ((mpd_uuint_t) *a * w) % m;
+ *b = ((mpd_uuint_t) *b * w) % m;
+}
+
+static inline void
+std_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1,
+ mpd_uint_t m)
+{
+ *a0 = ((mpd_uuint_t) *a0 * b0) % m;
+ *a1 = ((mpd_uuint_t) *a1 * b1) % m;
+}
+/* END HAVE_UINT64_T */
+#else
+/* LEGACY_COMPILER */
+static inline mpd_uint_t
+std_mulmod(mpd_uint_t a, mpd_uint_t b, mpd_uint_t m)
+{
+ mpd_uint_t hi, lo, q, r;
+ _mpd_mul_words(&hi, &lo, a, b);
+ _mpd_div_words(&q, &r, hi, lo, m);
+ return r;
+}
+
+static inline void
+std_mulmod2c(mpd_uint_t *a, mpd_uint_t *b, mpd_uint_t w, mpd_uint_t m)
+{
+ *a = std_mulmod(*a, w, m);
+ *b = std_mulmod(*b, w, m);
+}
+
+static inline void
+std_mulmod2(mpd_uint_t *a0, mpd_uint_t b0, mpd_uint_t *a1, mpd_uint_t b1,
+ mpd_uint_t m)
+{
+ *a0 = std_mulmod(*a0, b0, m);
+ *a1 = std_mulmod(*a1, b1, m);
+}
+/* END LEGACY_COMPILER */
#endif
+static inline mpd_uint_t
+std_powmod(mpd_uint_t base, mpd_uint_t exp, mpd_uint_t umod)
+{
+ mpd_uint_t r = 1;
+
+ while (exp > 0) {
+ if (exp & 1)
+ r = std_mulmod(r, base, umod);
+ base = std_mulmod(base, base, umod);
+ exp >>= 1;
+ }
+
+ return r;
+}
+#endif /* ANSI CONFIG_32 */
+
/**************************************************************************/
/* Pentium Pro modular arithmetic */
@@ -332,8 +339,8 @@
* - random tests are provided in tests/extended/ppro_mulmod.c
*/
-#ifdef PPRO
-#ifdef __GNUC__
+#if defined(PPRO)
+#if defined(ASM)
/* all operands < dmod */
static inline mpd_uint_t
@@ -440,8 +447,8 @@
);
}
-/* END PPRO __GNUC__ */
-#elif defined (_MSC_VER)
+/* END PPRO GCC ASM */
+#elif defined(MASM)
/* all operands < dmod */
static inline mpd_uint_t __cdecl
@@ -546,7 +553,7 @@
fistp DWORD PTR [eax]
}
}
-#endif /* PPRO _MSC_VER */
+#endif /* PPRO MASM (_MSC_VER) */
/* all operands < dmod */
@@ -565,6 +572,7 @@
return r;
}
#endif /* PPRO */
+#endif /* CONFIG_32 */
#endif /* UMODARITH_H */
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/vccompat.h
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/vccompat.h (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/vccompat.h Mon Nov 8 15:12:49 2010
@@ -26,6 +26,7 @@
#define strcasecmp _stricmp
#undef strtoll
#define strtoll _strtoi64
+ #define strdup _strdup
#endif
Modified: python/branches/py3k-cdecimal/Modules/cdecimal/vcdiv64.asm
==============================================================================
--- python/branches/py3k-cdecimal/Modules/cdecimal/vcdiv64.asm (original)
+++ python/branches/py3k-cdecimal/Modules/cdecimal/vcdiv64.asm Mon Nov 8 15:12:49 2010
@@ -21,8 +21,6 @@
ret 0
_mpd_div_words ENDP
_TEXT ENDS
-
-
-end
+END
More information about the Python-checkins
mailing list