diff options
author | Guido van Rossum <guido@python.org> | 1998-08-04 22:46:29 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1998-08-04 22:46:29 (GMT) |
commit | 1a8791e0b875df8e9428c2d9969f64e5967ac0b4 (patch) | |
tree | 4c0a38c8dbfc45a9b2d7343c17c4a969a8718162 /Objects/longobject.c | |
parent | 7d896ab1bbd5e15be7ae9203ead47f4f500a6a81 (diff) | |
download | cpython-1a8791e0b875df8e9428c2d9969f64e5967ac0b4.zip cpython-1a8791e0b875df8e9428c2d9969f64e5967ac0b4.tar.gz cpython-1a8791e0b875df8e9428c2d9969f64e5967ac0b4.tar.bz2 |
Changes for BeOS, QNX and long long, by Chris Herborth.
Diffstat (limited to 'Objects/longobject.c')
-rw-r--r-- | Objects/longobject.c | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/Objects/longobject.c b/Objects/longobject.c index b15a3f0..a6be3d9 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -277,6 +277,198 @@ PyLong_AsDouble(vv) return x * sign; } +#ifdef HAVE_LONG_LONG +/* + * long long support by Chris Herborth (chrish@qnx.com) + * + * For better or worse :-), I tried to follow the coding style already + * here. + */ + +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + +/* Hopefully this is portable... */ +#ifndef LONG_MAX +#define LONG_MAX 2147483647L +#endif +#ifndef ULONG_MAX +#define ULONG_MAX 4294967295U +#endif +#ifndef LONGLONG_MAX +#define LONGLONG_MAX 9223372036854775807LL +#endif +#ifndef ULONGLONG_MAX +#define ULONGLONG_MAX 0xffffffffffffffffULL +#endif + +/* Create a new long int object from a C long long int */ + +PyObject * +PyLong_FromLongLong(ival) + long long ival; +{ +#if SIZEOF_LONG_LONG == SIZEOF_LONG + /* In case the compiler is faking it. */ + return PyLong_FromLong( (long)ival ); +#else + if( ival <= (long long)LONG_MAX ) { + return PyLong_FromLong( (long)ival ); + } else if( ival <= (unsigned long long)ULONG_MAX ) { + return PyLong_FromUnsignedLong( (unsigned long)ival ); + } else { + /* Assume a C long long fits in at most 10 'digits'. + * Should be OK if we're assuming long fits in 5. + */ + PyLongObject *v = _PyLong_New(10); + + if (v != NULL) { + unsigned long long t = ival; + int i; + if (ival < 0) { + t = -ival; + v->ob_size = -(v->ob_size); + } + + for (i = 0; i < 10; i++) { + v->ob_digit[i] = (digit) (t & MASK); + t >>= SHIFT; + } + + v = long_normalize(v); + } + + return (PyObject *)v; + } + + /* If we got here, we're confused... */ + PyErr_SetString( PyExc_ArithmeticError, "invalid long integer" ); + return NULL; +#endif +} + +/* Create a new long int object from a C unsigned long long int */ +PyObject * +PyLong_FromUnsignedLongLong(ival) + unsigned long long ival; +{ +#if SIZEOF_LONG_LONG == SIZEOF_LONG + /* In case the compiler is faking it. */ + return PyLong_FromUnsignedLong( (unsigned long)ival ); +#else + if( ival <= (unsigned long long)ULONG_MAX ) { + return PyLong_FromUnsignedLong( (unsigned long)ival ); + } else { + /* Assume a C long fits in at most 10 'digits'. */ + PyLongObject *v = _PyLong_New(10); + + if (v != NULL) { + unsigned long long t = ival; + int i; + for (i = 0; i < 10; i++) { + v->ob_digit[i] = (digit) (t & MASK); + t >>= SHIFT; + } + + v = long_normalize(v); + } + + return (PyObject *)v; + } + + /* If we got here, we're confused... */ + PyErr_SetString( PyExc_ArithmeticError, "invalid unsigned long integer" ); + return NULL; +#endif +} + +/* Get a C long long int from a long int object. + Returns -1 and sets an error condition if overflow occurs. */ + +long long +PyLong_AsLongLong(vv) + PyObject *vv; +{ +#if SIZEOF_LONG_LONG == SIZEOF_LONG + /* In case the compiler is faking it. */ + return (long long)PyLong_AsLong( vv ); +#else + register PyLongObject *v; + long long x, prev; + int i, sign; + + if (vv == NULL || !PyLong_Check(vv)) { + PyErr_BadInternalCall(); + return -1; + } + + v = (PyLongObject *)vv; + i = v->ob_size; + sign = 1; + x = 0; + + if (i < 0) { + sign = -1; + i = -(i); + } + + while (--i >= 0) { + prev = x; + x = (x << SHIFT) + v->ob_digit[i]; + if ((x >> SHIFT) != prev) { + PyErr_SetString(PyExc_OverflowError, + "long int too long to convert"); + return -1; + } + } + + return x * sign; +#endif +} + +unsigned long long +PyLong_AsUnsignedLongLong(vv) + PyObject *vv; +{ +#if SIZEOF_LONG_LONG == 4 + /* In case the compiler is faking it. */ + return (unsigned long long)PyLong_AsUnsignedLong( vv ); +#else + register PyLongObject *v; + unsigned long long x, prev; + int i; + + if (vv == NULL || !PyLong_Check(vv)) { + PyErr_BadInternalCall(); + return (unsigned long long) -1; + } + + v = (PyLongObject *)vv; + i = v->ob_size; + x = 0; + + if (i < 0) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to unsigned long"); + return (unsigned long long) -1; + } + + while (--i >= 0) { + prev = x; + x = (x << SHIFT) + v->ob_digit[i]; + if ((x >> SHIFT) != prev) { + PyErr_SetString(PyExc_OverflowError, + "long int too long to convert"); + return (unsigned long long) -1; + } + } + + return x; +#endif +} +#endif /* HAVE_LONG_LONG */ + /* Multiply by a single digit, ignoring the sign. */ static PyLongObject * |