diff options
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/complexobject.c | 64 | ||||
-rw-r--r-- | Objects/doubledigits.c | 601 | ||||
-rw-r--r-- | Objects/floatobject.c | 201 | ||||
-rw-r--r-- | Objects/longobject.c | 12 |
4 files changed, 150 insertions, 728 deletions
diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 90b970e..acd5a4a 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -187,6 +187,38 @@ c_powi(Py_complex x, long n) } +double +c_abs(Py_complex z) +{ + /* sets errno = ERANGE on overflow; otherwise errno = 0 */ + double result; + + if (!Py_IS_FINITE(z.real) || !Py_IS_FINITE(z.imag)) { + /* C99 rules: if either the real or the imaginary part is an + infinity, return infinity, even if the other part is a + NaN. */ + if (Py_IS_INFINITY(z.real)) { + result = fabs(z.real); + errno = 0; + return result; + } + if (Py_IS_INFINITY(z.imag)) { + result = fabs(z.imag); + errno = 0; + return result; + } + /* either the real or imaginary part is a NaN, + and neither is infinite. Result should be NaN. */ + return Py_NAN; + } + result = hypot(z.real, z.imag); + if (!Py_IS_FINITE(result)) + errno = ERANGE; + else + errno = 0; + return result; +} + static PyObject * complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval) { @@ -321,8 +353,7 @@ complex_to_buf(char *buf, int bufsz, PyComplexObject *v, int precision) if (!Py_IS_FINITE(v->cval.imag)) { if (Py_IS_NAN(v->cval.imag)) strncpy(buf, "nan*j", 6); - /* else if (copysign(1, v->cval.imag) == 1) */ - else if (v->cval.imag > 0) + else if (copysign(1, v->cval.imag) == 1) strncpy(buf, "inf*j", 6); else strncpy(buf, "-inf*j", 7); @@ -578,9 +609,16 @@ static PyObject * complex_abs(PyComplexObject *v) { double result; + PyFPE_START_PROTECT("complex_abs", return 0) - result = hypot(v->cval.real,v->cval.imag); + result = c_abs(v->cval); PyFPE_END_PROTECT(result) + + if (errno == ERANGE) { + PyErr_SetString(PyExc_OverflowError, + "absolute value too large"); + return NULL; + } return PyFloat_FromDouble(result); } @@ -658,9 +696,29 @@ complex_getnewargs(PyComplexObject *v) return Py_BuildValue("(D)", &v->cval); } +#if 0 +static PyObject * +complex_is_finite(PyObject *self) +{ + Py_complex c; + c = ((PyComplexObject *)self)->cval; + return PyBool_FromLong((long)(Py_IS_FINITE(c.real) && + Py_IS_FINITE(c.imag))); +} + +PyDoc_STRVAR(complex_is_finite_doc, +"complex.is_finite() -> bool\n" +"\n" +"Returns True if the real and the imaginary part is finite."); +#endif + static PyMethodDef complex_methods[] = { {"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS, complex_conjugate_doc}, +#if 0 + {"is_finite", (PyCFunction)complex_is_finite, METH_NOARGS, + complex_is_finite_doc}, +#endif {"__getnewargs__", (PyCFunction)complex_getnewargs, METH_NOARGS}, {NULL, NULL} /* sentinel */ }; diff --git a/Objects/doubledigits.c b/Objects/doubledigits.c deleted file mode 100644 index 1f1c91c..0000000 --- a/Objects/doubledigits.c +++ /dev/null @@ -1,601 +0,0 @@ -/* Free-format floating point printer - * - * Based on "Floating-Point Printer Sample Code", by Robert G. Burger, - * http://www.cs.indiana.edu/~burger/fp/index.html - */ - -#include "Python.h" - -#if defined(__alpha) || defined(__i386) || defined(_M_IX86) || defined(_M_X64) || defined(_M_IA64) -#define LITTLE_ENDIAN_IEEE_DOUBLE -#elif !(defined(__ppc__) || defined(sparc) || defined(__sgi) || defined(_IBMR2) || defined(hpux)) -#error unknown machine type -#endif - -#if defined(_M_IX86) -#define UNSIGNED64 unsigned __int64 -#elif defined(__alpha) -#define UNSIGNED64 unsigned long -#else -#define UNSIGNED64 unsigned long long -#endif - -#ifndef U32 -#define U32 unsigned int -#endif - -/* exponent stored + 1024, hidden bit to left of decimal point */ -#define bias 1023 -#define bitstoright 52 -#define m1mask 0xf -#define hidden_bit 0x100000 -#ifdef LITTLE_ENDIAN_IEEE_DOUBLE -struct dblflt { - unsigned int m4: 16; - unsigned int m3: 16; - unsigned int m2: 16; - unsigned int m1: 4; - unsigned int e: 11; - unsigned int s: 1; -}; -#else -/* Big Endian IEEE Double Floats */ -struct dblflt { - unsigned int s: 1; - unsigned int e: 11; - unsigned int m1: 4; - unsigned int m2: 16; - unsigned int m3: 16; - unsigned int m4: 16; -}; -#endif -#define float_radix 2.147483648e9 - - -typedef UNSIGNED64 Bigit; -#define BIGSIZE 24 -#define MIN_E -1074 -#define MAX_FIVE 325 -#define B_P1 ((Bigit)1 << 52) - -typedef struct { - int l; - Bigit d[BIGSIZE]; -} Bignum; - -static Bignum R, S, MP, MM, five[MAX_FIVE]; -static Bignum S2, S3, S4, S5, S6, S7, S8, S9; -static int ruf, k, s_n, use_mp, qr_shift, sl, slr; - -static void mul10(Bignum *x); -static void big_short_mul(Bignum *x, Bigit y, Bignum *z); -/* -static void print_big(Bignum *x); -*/ -static int estimate(int n); -static void one_shift_left(int y, Bignum *z); -static void short_shift_left(Bigit x, int y, Bignum *z); -static void big_shift_left(Bignum *x, int y, Bignum *z); -static int big_comp(Bignum *x, Bignum *y); -static int sub_big(Bignum *x, Bignum *y, Bignum *z); -static void add_big(Bignum *x, Bignum *y, Bignum *z); -static int add_cmp(void); -static int qr(void); - -/*static int _PyFloat_Digits(char *buf, double v, int *signum);*/ -/*static void _PyFloat_DigitsInit(void);*/ - -#define ADD(x, y, z, k) {\ - Bigit x_add, z_add;\ - x_add = (x);\ - if ((k))\ - z_add = x_add + (y) + 1, (k) = (z_add <= x_add);\ - else\ - z_add = x_add + (y), (k) = (z_add < x_add);\ - (z) = z_add;\ -} - -#define SUB(x, y, z, b) {\ - Bigit x_sub, y_sub;\ - x_sub = (x); y_sub = (y);\ - if ((b))\ - (z) = x_sub - y_sub - 1, b = (y_sub >= x_sub);\ - else\ - (z) = x_sub - y_sub, b = (y_sub > x_sub);\ -} - -#define MUL(x, y, z, k) {\ - Bigit x_mul, low, high;\ - x_mul = (x);\ - low = (x_mul & 0xffffffff) * (y) + (k);\ - high = (x_mul >> 32) * (y) + (low >> 32);\ - (k) = high >> 32;\ - (z) = (low & 0xffffffff) | (high << 32);\ -} - -#define SLL(x, y, z, k) {\ - Bigit x_sll = (x);\ - (z) = (x_sll << (y)) | (k);\ - (k) = x_sll >> (64 - (y));\ -} - -static void -mul10(Bignum *x) -{ - int i, l; - Bigit *p, k; - - l = x->l; - for (i = l, p = &x->d[0], k = 0; i >= 0; i--) - MUL(*p, 10, *p++, k); - if (k != 0) - *p = k, x->l = l+1; -} - -static void -big_short_mul(Bignum *x, Bigit y, Bignum *z) -{ - int i, xl, zl; - Bigit *xp, *zp, k; - U32 high, low; - - xl = x->l; - xp = &x->d[0]; - zl = xl; - zp = &z->d[0]; - high = y >> 32; - low = y & 0xffffffff; - for (i = xl, k = 0; i >= 0; i--, xp++, zp++) { - Bigit xlow, xhigh, z0, t, c, z1; - xlow = *xp & 0xffffffff; - xhigh = *xp >> 32; - z0 = (xlow * low) + k; /* Cout is (z0 < k) */ - t = xhigh * low; - z1 = (xlow * high) + t; - c = (z1 < t); - t = z0 >> 32; - z1 += t; - c += (z1 < t); - *zp = (z1 << 32) | (z0 & 0xffffffff); - k = (xhigh * high) + (c << 32) + (z1 >> 32) + (z0 < k); - } - if (k != 0) - *zp = k, zl++; - z->l = zl; -} - -/* -static void -print_big(Bignum *x) -{ - int i; - Bigit *p; - - printf("#x"); - i = x->l; - p = &x->d[i]; - for (p = &x->d[i]; i >= 0; i--) { - Bigit b = *p--; - printf("%08x%08x", (int)(b >> 32), (int)(b & 0xffffffff)); - } -} -*/ - -static int -estimate(int n) -{ - if (n < 0) - return (int)(n*0.3010299956639812); - else - return 1+(int)(n*0.3010299956639811); -} - -static void -one_shift_left(int y, Bignum *z) -{ - int n, m, i; - Bigit *zp; - - n = y / 64; - m = y % 64; - zp = &z->d[0]; - for (i = n; i > 0; i--) *zp++ = 0; - *zp = (Bigit)1 << m; - z->l = n; -} - -static void -short_shift_left(Bigit x, int y, Bignum *z) -{ - int n, m, i, zl; - Bigit *zp; - - n = y / 64; - m = y % 64; - zl = n; - zp = &(z->d[0]); - for (i = n; i > 0; i--) *zp++ = 0; - if (m == 0) - *zp = x; - else { - Bigit high = x >> (64 - m); - *zp = x << m; - if (high != 0) - *++zp = high, zl++; - } - z->l = zl; -} - -static void -big_shift_left(Bignum *x, int y, Bignum *z) -{ - int n, m, i, xl, zl; - Bigit *xp, *zp, k; - - n = y / 64; - m = y % 64; - xl = x->l; - xp = &(x->d[0]); - zl = xl + n; - zp = &(z->d[0]); - for (i = n; i > 0; i--) *zp++ = 0; - if (m == 0) - for (i = xl; i >= 0; i--) *zp++ = *xp++; - else { - for (i = xl, k = 0; i >= 0; i--) - SLL(*xp++, m, *zp++, k); - if (k != 0) - *zp = k, zl++; - } - z->l = zl; -} - - -static int -big_comp(Bignum *x, Bignum *y) -{ - int i, xl, yl; - Bigit *xp, *yp; - - xl = x->l; - yl = y->l; - if (xl > yl) return 1; - if (xl < yl) return -1; - xp = &x->d[xl]; - yp = &y->d[xl]; - for (i = xl; i >= 0; i--, xp--, yp--) { - Bigit a = *xp; - Bigit b = *yp; - - if (a > b) return 1; - else if (a < b) return -1; - } - return 0; -} - -static int -sub_big(Bignum *x, Bignum *y, Bignum *z) -{ - int xl, yl, zl, b, i; - Bigit *xp, *yp, *zp; - - xl = x->l; - yl = y->l; - if (yl > xl) return 1; - xp = &x->d[0]; - yp = &y->d[0]; - zp = &z->d[0]; - - for (i = yl, b = 0; i >= 0; i--) - SUB(*xp++, *yp++, *zp++, b); - for (i = xl-yl; b && i > 0; i--) { - Bigit x_sub; - x_sub = *xp++; - *zp++ = x_sub - 1; - b = (x_sub == 0); - } - for (; i > 0; i--) *zp++ = *xp++; - if (b) return 1; - zl = xl; - while (*--zp == 0) zl--; - z->l = zl; - return 0; -} - -static void -add_big(Bignum *x, Bignum *y, Bignum *z) -{ - int xl, yl, k, i; - Bigit *xp, *yp, *zp; - - xl = x->l; - yl = y->l; - if (yl > xl) { - int tl; - Bignum *tn; - tl = xl; xl = yl; yl = tl; - tn = x; x = y; y = tn; - } - - xp = &x->d[0]; - yp = &y->d[0]; - zp = &z->d[0]; - - for (i = yl, k = 0; i >= 0; i--) - ADD(*xp++, *yp++, *zp++, k); - for (i = xl-yl; k && i > 0; i--) { - Bigit z_add; - z_add = *xp++ + 1; - k = (z_add == 0); - *zp++ = z_add; - } - for (; i > 0; i--) *zp++ = *xp++; - if (k) - *zp = 1, z->l = xl+1; - else - z->l = xl; -} - -static int -add_cmp() -{ - int rl, ml, sl, suml; - static Bignum sum; - - rl = R.l; - ml = (use_mp ? MP.l : MM.l); - sl = S.l; - - suml = rl >= ml ? rl : ml; - if ((sl > suml+1) || ((sl == suml+1) && (S.d[sl] > 1))) return -1; - if (sl < suml) return 1; - - add_big(&R, (use_mp ? &MP : &MM), &sum); - return big_comp(&sum, &S); -} - -static int -qr() -{ - if (big_comp(&R, &S5) < 0) - if (big_comp(&R, &S2) < 0) - if (big_comp(&R, &S) < 0) - return 0; - else { - sub_big(&R, &S, &R); - return 1; - } - else if (big_comp(&R, &S3) < 0) { - sub_big(&R, &S2, &R); - return 2; - } - else if (big_comp(&R, &S4) < 0) { - sub_big(&R, &S3, &R); - return 3; - } - else { - sub_big(&R, &S4, &R); - return 4; - } - else if (big_comp(&R, &S7) < 0) - if (big_comp(&R, &S6) < 0) { - sub_big(&R, &S5, &R); - return 5; - } - else { - sub_big(&R, &S6, &R); - return 6; - } - else if (big_comp(&R, &S9) < 0) - if (big_comp(&R, &S8) < 0) { - sub_big(&R, &S7, &R); - return 7; - } - else { - sub_big(&R, &S8, &R); - return 8; - } - else { - sub_big(&R, &S9, &R); - return 9; - } -} - -#define OUTDIG(d) { *buf++ = (d) + '0'; *buf = 0; return k; } - -int -_PyFloat_Digits(char *buf, double v, int *signum) -{ - struct dblflt *x; - int sign, e, f_n, m_n, i, d, tc1, tc2; - Bigit f; - - /* decompose float into sign, mantissa & exponent */ - x = (struct dblflt *)&v; - sign = x->s; - e = x->e; - f = (Bigit)(x->m1 << 16 | x->m2) << 32 | (U32)(x->m3 << 16 | x->m4); - if (e != 0) { - e = e - bias - bitstoright; - f |= (Bigit)hidden_bit << 32; - } - else if (f != 0) - /* denormalized */ - e = 1 - bias - bitstoright; - - *signum = sign; - if (f == 0) { - *buf++ = '0'; - *buf = 0; - return 0; - } - - ruf = !(f & 1); /* ruf = (even? f) */ - - /* Compute the scaling factor estimate, k */ - if (e > MIN_E) - k = estimate(e+52); - else { - int n; - Bigit y; - - for (n = e+52, y = (Bigit)1 << 52; f < y; n--) y >>= 1; - k = estimate(n); - } - - if (e >= 0) - if (f != B_P1) - use_mp = 0, f_n = e+1, s_n = 1, m_n = e; - else - use_mp = 1, f_n = e+2, s_n = 2, m_n = e; - else - if ((e == MIN_E) || (f != B_P1)) - use_mp = 0, f_n = 1, s_n = 1-e, m_n = 0; - else - use_mp = 1, f_n = 2, s_n = 2-e, m_n = 0; - - /* Scale it! */ - if (k == 0) { - short_shift_left(f, f_n, &R); - one_shift_left(s_n, &S); - one_shift_left(m_n, &MM); - if (use_mp) one_shift_left(m_n+1, &MP); - qr_shift = 1; - } - else if (k > 0) { - s_n += k; - if (m_n >= s_n) - f_n -= s_n, m_n -= s_n, s_n = 0; - else - f_n -= m_n, s_n -= m_n, m_n = 0; - short_shift_left(f, f_n, &R); - big_shift_left(&five[k-1], s_n, &S); - one_shift_left(m_n, &MM); - if (use_mp) one_shift_left(m_n+1, &MP); - qr_shift = 0; - } - else { - Bignum *power = &five[-k-1]; - - s_n += k; - big_short_mul(power, f, &S); - big_shift_left(&S, f_n, &R); - one_shift_left(s_n, &S); - big_shift_left(power, m_n, &MM); - if (use_mp) big_shift_left(power, m_n+1, &MP); - qr_shift = 1; - } - - /* fixup */ - if (add_cmp() <= -ruf) { - k--; - mul10(&R); - mul10(&MM); - if (use_mp) mul10(&MP); - } - - /* - printf("\nk = %d\n", k); - printf("R = "); print_big(&R); - printf("\nS = "); print_big(&S); - printf("\nM- = "); print_big(&MM); - if (use_mp) printf("\nM+ = "), print_big(&MP); - putchar('\n'); - fflush(0); - */ - - if (qr_shift) { - sl = s_n / 64; - slr = s_n % 64; - } - else { - big_shift_left(&S, 1, &S2); - add_big(&S2, &S, &S3); - big_shift_left(&S2, 1, &S4); - add_big(&S4, &S, &S5); - add_big(&S4, &S2, &S6); - add_big(&S4, &S3, &S7); - big_shift_left(&S4, 1, &S8); - add_big(&S8, &S, &S9); - } - -again: - if (qr_shift) { /* Take advantage of the fact that S = (ash 1 s_n) */ - if (R.l < sl) - d = 0; - else if (R.l == sl) { - Bigit *p; - - p = &R.d[sl]; - d = *p >> slr; - *p &= ((Bigit)1 << slr) - 1; - for (i = sl; (i > 0) && (*p == 0); i--) p--; - R.l = i; - } - else { - Bigit *p; - - p = &R.d[sl+1]; - d = *p << (64 - slr) | *(p-1) >> slr; - p--; - *p &= ((Bigit)1 << slr) - 1; - for (i = sl; (i > 0) && (*p == 0); i--) p--; - R.l = i; - } - } - else /* We need to do quotient-remainder */ - d = qr(); - - tc1 = big_comp(&R, &MM) < ruf; - tc2 = add_cmp() > -ruf; - if (!tc1) - if (!tc2) { - mul10(&R); - mul10(&MM); - if (use_mp) mul10(&MP); - *buf++ = d + '0'; - goto again; - } - else - OUTDIG(d+1) - else - if (!tc2) - OUTDIG(d) - else { - big_shift_left(&R, 1, &MM); - if (big_comp(&MM, &S) == -1) - OUTDIG(d) - else - OUTDIG(d+1) - } -} - -void -_PyFloat_DigitsInit() -{ - int n, i, l; - Bignum *b; - Bigit *xp, *zp, k; - - five[0].l = l = 0; - five[0].d[0] = 5; - for (n = MAX_FIVE-1, b = &five[0]; n > 0; n--) { - xp = &b->d[0]; - b++; - zp = &b->d[0]; - for (i = l, k = 0; i >= 0; i--) - MUL(*xp++, 5, *zp++, k); - if (k != 0) - *zp = k, l++; - b->l = l; - } - - /* - for (n = 1, b = &five[0]; n <= MAX_FIVE; n++) { - big_shift_left(b++, n, &R); - print_big(&R); - putchar('\n'); - } - fflush(0); - */ -} diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 745dfc3..a748abb 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -16,10 +16,6 @@ #include <ieeefp.h> #endif -#if !defined(__STDC__) -extern double fmod(double, double); -extern double pow(double, double); -#endif #ifdef _OSF_SOURCE /* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */ @@ -224,11 +220,11 @@ PyFloat_FromString(PyObject *v) p++; } if (PyOS_strnicmp(p, "inf", 4) == 0) { - return PyFloat_FromDouble(sign * Py_HUGE_VAL); + Py_RETURN_INF(sign); } #ifdef Py_NAN if(PyOS_strnicmp(p, "nan", 4) == 0) { - return PyFloat_FromDouble(Py_NAN); + Py_RETURN_NAN; } #endif PyOS_snprintf(buffer, sizeof(buffer), @@ -378,110 +374,6 @@ format_float(char *buf, size_t buflen, PyFloatObject *v, int precision) format_double(buf, buflen, PyFloat_AS_DOUBLE(v), precision); } -#ifdef Py_BROKEN_REPR -/* The following function is based on Tcl_PrintDouble, - * from tclUtil.c. - */ - -#define is_infinite(d) ( (d) > DBL_MAX || (d) < -DBL_MAX ) -#define is_nan(d) ((d) != (d)) - -static void -format_double_repr(char *dst, double value) -{ - char *p, c; - int exp; - int signum; - char buffer[30]; - - /* - * Handle NaN. - */ - - if (is_nan(value)) { - strcpy(dst, "nan"); - return; - } - - /* - * Handle infinities. - */ - - if (is_infinite(value)) { - if (value < 0) { - strcpy(dst, "-inf"); - } else { - strcpy(dst, "inf"); - } - return; - } - - /* - * Ordinary (normal and denormal) values. - */ - - exp = _PyFloat_Digits(buffer, value, &signum)+1; - if (signum) { - *dst++ = '-'; - } - p = buffer; - if (exp < -3 || exp > 17) { - /* - * E format for numbers < 1e-3 or >= 1e17. - */ - - *dst++ = *p++; - c = *p; - if (c != '\0') { - *dst++ = '.'; - while (c != '\0') { - *dst++ = c; - c = *++p; - } - } - sprintf(dst, "e%+d", exp-1); - } else { - /* - * F format for others. - */ - - if (exp <= 0) { - *dst++ = '0'; - } - c = *p; - while (exp-- > 0) { - if (c != '\0') { - *dst++ = c; - c = *++p; - } else { - *dst++ = '0'; - } - } - *dst++ = '.'; - if (c == '\0') { - *dst++ = '0'; - } else { - while (++exp < 0) { - *dst++ = '0'; - } - while (c != '\0') { - *dst++ = c; - c = *++p; - } - } - *dst++ = '\0'; - } -} - -static void -format_float_repr(char *buf, PyFloatObject *v) -{ - assert(PyFloat_Check(v)); - format_double_repr(buf, PyFloat_AS_DOUBLE(v)); -} - -#endif /* Py_BROKEN_REPR */ - /* Macro and helper that convert PyObject obj to a C double and store the value in dbl. If conversion to double raises an exception, obj is set to NULL, and the function invoking this macro returns NULL. If @@ -534,13 +426,8 @@ convert_to_double(PyObject **v, double *dbl) static PyObject * float_repr(PyFloatObject *v) { -#ifdef Py_BROKEN_REPR - char buf[30]; - format_float_repr(buf, v); -#else char buf[100]; format_float(buf, sizeof(buf), v, PREC_REPR); -#endif return PyUnicode_FromString(buf); } @@ -804,10 +691,13 @@ float_div(PyObject *v, PyObject *w) double a,b; CONVERT_TO_DOUBLE(v, a); CONVERT_TO_DOUBLE(w, b); +#ifdef Py_NAN if (b == 0.0) { - PyErr_SetString(PyExc_ZeroDivisionError, "float division"); + PyErr_SetString(PyExc_ZeroDivisionError, + "float division"); return NULL; } +#endif PyFPE_START_PROTECT("divide", return 0) a = a / b; PyFPE_END_PROTECT(a) @@ -819,12 +709,15 @@ float_rem(PyObject *v, PyObject *w) { double vx, wx; double mod; - CONVERT_TO_DOUBLE(v, vx); - CONVERT_TO_DOUBLE(w, wx); + CONVERT_TO_DOUBLE(v, vx); + CONVERT_TO_DOUBLE(w, wx); +#ifdef Py_NAN if (wx == 0.0) { - PyErr_SetString(PyExc_ZeroDivisionError, "float modulo"); + PyErr_SetString(PyExc_ZeroDivisionError, + "float modulo"); return NULL; } +#endif PyFPE_START_PROTECT("modulo", return 0) mod = fmod(vx, wx); /* note: checking mod*wx < 0 is incorrect -- underflows to @@ -928,6 +821,9 @@ float_pow(PyObject *v, PyObject *w, PyObject *z) } return PyFloat_FromDouble(0.0); } + if (iv == 1.0) { /* 1**w is 1, even 1**inf and 1**nan */ + return PyFloat_FromDouble(1.0); + } if (iv < 0.0) { /* Whether this is an error is a mess, and bumps into libm * bugs so we have to figure it out ourselves. @@ -995,6 +891,57 @@ float_bool(PyFloatObject *v) } static PyObject * +float_is_integer(PyObject *v) +{ + double x = PyFloat_AsDouble(v); + PyObject *o; + + if (x == -1.0 && PyErr_Occurred()) + return NULL; + if (!Py_IS_FINITE(x)) + Py_RETURN_FALSE; + PyFPE_START_PROTECT("is_integer", return NULL) + o = (floor(x) == x) ? Py_True : Py_False; + PyFPE_END_PROTECT(x) + if (errno != 0) { + PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError : + PyExc_ValueError); + return NULL; + } + Py_INCREF(o); + return o; +} + +#if 0 +static PyObject * +float_is_inf(PyObject *v) +{ + double x = PyFloat_AsDouble(v); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + return PyBool_FromLong((long)Py_IS_INFINITY(x)); +} + +static PyObject * +float_is_nan(PyObject *v) +{ + double x = PyFloat_AsDouble(v); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + return PyBool_FromLong((long)Py_IS_NAN(x)); +} + +static PyObject * +float_is_finite(PyObject *v) +{ + double x = PyFloat_AsDouble(v); + if (x == -1.0 && PyErr_Occurred()) + return NULL; + return PyBool_FromLong((long)Py_IS_FINITE(x)); +} +#endif + +static PyObject * float_trunc(PyObject *v) { double x = PyFloat_AsDouble(v); @@ -1368,7 +1315,7 @@ PyDoc_STRVAR(float__format__doc, static PyMethodDef float_methods[] = { - {"conjugate", (PyCFunction)float_float, METH_NOARGS, + {"conjugate", (PyCFunction)float_float, METH_NOARGS, "Returns self, the complex conjugate of any float."}, {"__trunc__", (PyCFunction)float_trunc, METH_NOARGS, "Returns the Integral closest to x between 0 and x."}, @@ -1377,6 +1324,16 @@ static PyMethodDef float_methods[] = { "When an argument is passed, works like built-in round(x, ndigits)."}, {"as_integer_ratio", (PyCFunction)float_as_integer_ratio, METH_NOARGS, float_as_integer_ratio_doc}, + {"is_integer", (PyCFunction)float_is_integer, METH_NOARGS, + "Returns True if the float is an integer."}, +#if 0 + {"is_inf", (PyCFunction)float_is_inf, METH_NOARGS, + "Returns True if the float is positive or negative infinite."}, + {"is_finite", (PyCFunction)float_is_finite, METH_NOARGS, + "Returns True if the float is finite, neither infinite nor NaN."}, + {"is_nan", (PyCFunction)float_is_nan, METH_NOARGS, + "Returns True if the float is not a number (NaN)."}, +#endif {"__getnewargs__", (PyCFunction)float_getnewargs, METH_NOARGS}, {"__getformat__", (PyCFunction)float_getformat, METH_O|METH_CLASS, float_getformat_doc}, @@ -1534,10 +1491,6 @@ _PyFloat_Init(void) double_format = detected_double_format; float_format = detected_float_format; -#ifdef Py_BROKEN_REPR - /* Initialize floating point repr */ - _PyFloat_DigitsInit(); -#endif /* Init float info */ if (FloatInfoType.tp_name == 0) PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc); diff --git a/Objects/longobject.c b/Objects/longobject.c index 44b040c..d88a13e 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3611,9 +3611,21 @@ long_round(PyObject *self, PyObject *args) #undef UNDEF_NDIGITS } +#if 0 +static PyObject * +long_is_finite(PyObject *v) +{ + Py_RETURN_TRUE; +} +#endif + static PyMethodDef long_methods[] = { {"conjugate", (PyCFunction)long_long, METH_NOARGS, "Returns self, the complex conjugate of any int."}, +#if 0 + {"is_finite", (PyCFunction)long_is_finite, METH_NOARGS, + "Returns always True."}, +#endif {"__trunc__", (PyCFunction)long_long, METH_NOARGS, "Truncating an Integral returns itself."}, {"__floor__", (PyCFunction)long_long, METH_NOARGS, |