
/* Float object implementation */

/* XXX There should be overflow checks here, but it's hard to check
   for any kind of float exception without losing portability. */

#include "Python.h"
#include "structseq.h"

#include <ctype.h>
#include <float.h>

#undef MAX
#undef MIN
#define MAX(x, y) ((x) < (y) ? (y) : (x))
#define MIN(x, y) ((x) < (y) ? (x) : (y))

#ifdef HAVE_IEEEFP_H
#include <ieeefp.h>
#endif


#ifdef _OSF_SOURCE
/* OSF1 5.1 doesn't make this available with XOPEN_SOURCE_EXTENDED defined */
extern int finite(double);
#endif

/* Special free list -- see comments for same code in intobject.c. */
#define BLOCK_SIZE	1000	/* 1K less typical malloc overhead */
#define BHEAD_SIZE	8	/* Enough for a 64-bit pointer */
#define N_FLOATOBJECTS	((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject))

struct _floatblock {
	struct _floatblock *next;
	PyFloatObject objects[N_FLOATOBJECTS];
};

typedef struct _floatblock PyFloatBlock;

static PyFloatBlock *block_list = NULL;
static PyFloatObject *free_list = NULL;

static PyFloatObject *
fill_free_list(void)
{
	PyFloatObject *p, *q;
	/* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */
	p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatBlock));
	if (p == NULL)
		return (PyFloatObject *) PyErr_NoMemory();
	((PyFloatBlock *)p)->next = block_list;
	block_list = (PyFloatBlock *)p;
	p = &((PyFloatBlock *)p)->objects[0];
	q = p + N_FLOATOBJECTS;
	while (--q > p)
		Py_TYPE(q) = (struct _typeobject *)(q-1);
	Py_TYPE(q) = NULL;
	return p + N_FLOATOBJECTS - 1;
}

double
PyFloat_GetMax(void)
{
	return DBL_MAX;
}

double
PyFloat_GetMin(void)
{
	return DBL_MIN;
}

static PyTypeObject FloatInfoType;

PyDoc_STRVAR(floatinfo__doc__,
"sys.floatinfo\n\
\n\
A structseq holding information about the float type. It contains low level\n\
information about the precision and internal representation. Please study\n\
your system's :file:`float.h` for more information.");

static PyStructSequence_Field floatinfo_fields[] = {
	{"max",		"DBL_MAX -- maximum representable finite float"},
	{"max_exp",	"DBL_MAX_EXP -- maximum int e such that radix**(e-1) "
			"is representable"},
	{"max_10_exp",	"DBL_MAX_10_EXP -- maximum int e such that 10**e "
			"is representable"},
	{"min",		"DBL_MIN -- Minimum positive normalizer float"},
	{"min_exp",	"DBL_MIN_EXP -- minimum int e such that radix**(e-1) "
			"is a normalized float"},
	{"min_10_exp",	"DBL_MIN_10_EXP -- minimum int e such that 10**e is "
			"a normalized"},
	{"dig",		"DBL_DIG -- digits"},
	{"mant_dig",	"DBL_MANT_DIG -- mantissa digits"},
	{"epsilon",	"DBL_EPSILON -- Difference between 1 and the next "
			"representable float"},
	{"radix",	"FLT_RADIX -- radix of exponent"},
	{"rounds",	"FLT_ROUNDS -- addition rounds"},
	{0}
};

static PyStructSequence_Desc floatinfo_desc = {
	"sys.floatinfo",	/* name */
	floatinfo__doc__,	/* doc */
	floatinfo_fields,	/* fields */
	11
};

PyObject *
PyFloat_GetInfo(void)
{
	PyObject* floatinfo;
	int pos = 0;

	floatinfo = PyStructSequence_New(&FloatInfoType);
	if (floatinfo == NULL) {
		return NULL;
	}

#define SetIntFlag(flag) \
	PyStructSequence_SET_ITEM(floatinfo, pos++, PyLong_FromLong(flag))
#define SetDblFlag(flag) \
	PyStructSequence_SET_ITEM(floatinfo, pos++, PyFloat_FromDouble(flag))

	SetDblFlag(DBL_MAX);
	SetIntFlag(DBL_MAX_EXP);
	SetIntFlag(DBL_MAX_10_EXP);
	SetDblFlag(DBL_MIN);
	SetIntFlag(DBL_MIN_EXP);
	SetIntFlag(DBL_MIN_10_EXP);
	SetIntFlag(DBL_DIG);
	SetIntFlag(DBL_MANT_DIG);
	SetDblFlag(DBL_EPSILON);
	SetIntFlag(FLT_RADIX);
	SetIntFlag(FLT_ROUNDS);
#undef SetIntFlag
#undef SetDblFlag
	
	if (PyErr_Occurred()) {
		Py_CLEAR(floatinfo);
		return NULL;
	}
	return floatinfo;
}

PyObject *
PyFloat_FromDouble(double fval)
{
	register PyFloatObject *op;
	if (free_list == NULL) {
		if ((free_list = fill_free_list()) == NULL)
			return NULL;
	}
	/* Inline PyObject_New */
	op = free_list;
	free_list = (PyFloatObject *)Py_TYPE(op);
	PyObject_INIT(op, &PyFloat_Type);
	op->ob_fval = fval;
	return (PyObject *) op;
}

PyObject *
PyFloat_FromString(PyObject *v)
{
	const char *s, *last, *end;
	double x;
	char buffer[256]; /* for errors */
	char *s_buffer = NULL;
	Py_ssize_t len;
	PyObject *result = NULL;

	if (PyUnicode_Check(v)) {
		s_buffer = (char *)PyMem_MALLOC(PyUnicode_GET_SIZE(v)+1);
		if (s_buffer == NULL)
			return PyErr_NoMemory();
		if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v),
					    PyUnicode_GET_SIZE(v),
					    s_buffer,
					    NULL))
			goto error;
		s = s_buffer;
		len = strlen(s);
	}
	else if (PyObject_AsCharBuffer(v, &s, &len)) {
		PyErr_SetString(PyExc_TypeError,
				"float() argument must be a string or a number");
		return NULL;
	}
	last = s + len;

	while (Py_ISSPACE(*s))
		s++;
	/* We don't care about overflow or underflow.  If the platform
	 * supports them, infinities and signed zeroes (on underflow) are
	 * fine. */
	x = PyOS_string_to_double(s, (char **)&end, NULL);
	if (x == -1.0 && PyErr_Occurred())
		goto error;
	while (Py_ISSPACE(*end))
		end++;
	if (end == last)
		result = PyFloat_FromDouble(x);
	else {
		PyOS_snprintf(buffer, sizeof(buffer),
			      "invalid literal for float(): %.200s", s);
		PyErr_SetString(PyExc_ValueError, buffer);
		result = NULL;
	}

  error:
	if (s_buffer)
		PyMem_FREE(s_buffer);
	return result;
}

static void
float_dealloc(PyFloatObject *op)
{
	if (PyFloat_CheckExact(op)) {
		Py_TYPE(op) = (struct _typeobject *)free_list;
		free_list = op;
	}
	else
		Py_TYPE(op)->tp_free((PyObject *)op);
}

double
PyFloat_AsDouble(PyObject *op)
{
	PyNumberMethods *nb;
	PyFloatObject *fo;
	double val;

	if (op && PyFloat_Check(op))
		return PyFloat_AS_DOUBLE((PyFloatObject*) op);

	if (op == NULL) {
		PyErr_BadArgument();
		return -1;
	}

	if ((nb = Py_TYPE(op)->tp_as_number) == NULL || nb->nb_float == NULL) {
		PyErr_SetString(PyExc_TypeError, "a float is required");
		return -1;
	}

	fo = (PyFloatObject*) (*nb->nb_float) (op);
	if (fo == NULL)
		return -1;
	if (!PyFloat_Check(fo)) {
		PyErr_SetString(PyExc_TypeError,
				"nb_float should return float object");
		return -1;
	}

	val = PyFloat_AS_DOUBLE(fo);
	Py_DECREF(fo);

	return val;
}

/* 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
   obj is not of float, int or long type, Py_NotImplemented is incref'ed,
   stored in obj, and returned from the function invoking this macro.
*/
#define CONVERT_TO_DOUBLE(obj, dbl)			\
	if (PyFloat_Check(obj))				\
		dbl = PyFloat_AS_DOUBLE(obj);		\
	else if (convert_to_double(&(obj), &(dbl)) < 0)	\
		return obj;

/* Methods */

static int
convert_to_double(PyObject **v, double *dbl)
{
	register PyObject *obj = *v;

	if (PyLong_Check(obj)) {
		*dbl = PyLong_AsDouble(obj);
		if (*dbl == -1.0 && PyErr_Occurred()) {
			*v = NULL;
			return -1;
		}
	}
	else {
		Py_INCREF(Py_NotImplemented);
		*v = Py_NotImplemented;
		return -1;
	}
	return 0;
}

static PyObject *
float_str_or_repr(PyFloatObject *v, int precision, char format_code)
{
    PyObject *result;
    char *buf = PyOS_double_to_string(PyFloat_AS_DOUBLE(v),
                                      format_code, precision,
                                      Py_DTSF_ADD_DOT_0,
                                      NULL);
    if (!buf)
        return PyErr_NoMemory();
    result = PyUnicode_FromString(buf);
    PyMem_Free(buf);
    return result;
}

static PyObject *
float_repr(PyFloatObject *v)
{
    return float_str_or_repr(v, 0, 'r');
}

static PyObject *
float_str(PyFloatObject *v)
{
    return float_str_or_repr(v, PyFloat_STR_PRECISION, 'g');
}

/* Comparison is pretty much a nightmare.  When comparing float to float,
 * we do it as straightforwardly (and long-windedly) as conceivable, so
 * that, e.g., Python x == y delivers the same result as the platform
 * C x == y when x and/or y is a NaN.
 * When mixing float with an integer type, there's no good *uniform* approach.
 * Converting the double to an integer obviously doesn't work, since we
 * may lose info from fractional bits.  Converting the integer to a double
 * also has two failure modes:  (1) a long int may trigger overflow (too
 * large to fit in the dynamic range of a C double); (2) even a C long may have
 * more bits than fit in a C double (e.g., on a a 64-bit box long may have
 * 63 bits of precision, but a C double probably has only 53), and then
 * we can falsely claim equality when low-order integer bits are lost by
 * coercion to double.  So this part is painful too.
 */

static PyObject*
float_richcompare(PyObject *v, PyObject *w, int op)
{
	double i, j;
	int r = 0;

	assert(PyFloat_Check(v));
	i = PyFloat_AS_DOUBLE(v);

	/* Switch on the type of w.  Set i and j to doubles to be compared,
	 * and op to the richcomp to use.
	 */
	if (PyFloat_Check(w))
		j = PyFloat_AS_DOUBLE(w);

	else if (!Py_IS_FINITE(i)) {
		if (PyLong_Check(w))
			/* If i is an infinity, its magnitude exceeds any
			 * finite integer, so it doesn't matter which int we
			 * compare i with.  If i is a NaN, similarly.
			 */
			j = 0.0;
		else
			goto Unimplemented;
	}

	else if (PyLong_Check(w)) {
		int vsign = i == 0.0 ? 0 : i < 0.0 ? -1 : 1;
		int wsign = _PyLong_Sign(w);
		size_t nbits;
		int exponent;

		if (vsign != wsign) {
			/* Magnitudes are irrelevant -- the signs alone
			 * determine the outcome.
			 */
			i = (double)vsign;
			j = (double)wsign;
			goto Compare;
		}
		/* The signs are the same. */
		/* Convert w to a double if it fits.  In particular, 0 fits. */
		nbits = _PyLong_NumBits(w);
		if (nbits == (size_t)-1 && PyErr_Occurred()) {
			/* This long is so large that size_t isn't big enough
			 * to hold the # of bits.  Replace with little doubles
			 * that give the same outcome -- w is so large that
			 * its magnitude must exceed the magnitude of any
			 * finite float.
			 */
			PyErr_Clear();
			i = (double)vsign;
			assert(wsign != 0);
			j = wsign * 2.0;
			goto Compare;
		}
		if (nbits <= 48) {
			j = PyLong_AsDouble(w);
			/* It's impossible that <= 48 bits overflowed. */
			assert(j != -1.0 || ! PyErr_Occurred());
			goto Compare;
		}
		assert(wsign != 0); /* else nbits was 0 */
		assert(vsign != 0); /* if vsign were 0, then since wsign is
		                     * not 0, we would have taken the
		                     * vsign != wsign branch at the start */
		/* We want to work with non-negative numbers. */
		if (vsign < 0) {
			/* "Multiply both sides" by -1; this also swaps the
			 * comparator.
			 */
			i = -i;
			op = _Py_SwappedOp[op];
		}
		assert(i > 0.0);
		(void) frexp(i, &exponent);
		/* exponent is the # of bits in v before the radix point;
		 * we know that nbits (the # of bits in w) > 48 at this point
		 */
		if (exponent < 0 || (size_t)exponent < nbits) {
			i = 1.0;
			j = 2.0;
			goto Compare;
		}
		if ((size_t)exponent > nbits) {
			i = 2.0;
			j = 1.0;
			goto Compare;
		}
		/* v and w have the same number of bits before the radix
		 * point.  Construct two longs that have the same comparison
		 * outcome.
		 */
		{
			double fracpart;
			double intpart;
			PyObject *result = NULL;
			PyObject *one = NULL;
			PyObject *vv = NULL;
			PyObject *ww = w;

			if (wsign < 0) {
				ww = PyNumber_Negative(w);
				if (ww == NULL)
					goto Error;
			}
			else
				Py_INCREF(ww);

			fracpart = modf(i, &intpart);
			vv = PyLong_FromDouble(intpart);
			if (vv == NULL)
				goto Error;

			if (fracpart != 0.0) {
				/* Shift left, and or a 1 bit into vv
				 * to represent the lost fraction.
				 */
				PyObject *temp;

				one = PyLong_FromLong(1);
				if (one == NULL)
					goto Error;

				temp = PyNumber_Lshift(ww, one);
				if (temp == NULL)
					goto Error;
				Py_DECREF(ww);
				ww = temp;

				temp = PyNumber_Lshift(vv, one);
				if (temp == NULL)
					goto Error;
				Py_DECREF(vv);
				vv = temp;

				temp = PyNumber_Or(vv, one);
				if (temp == NULL)
					goto Error;
				Py_DECREF(vv);
				vv = temp;
			}

			r = PyObject_RichCompareBool(vv, ww, op);
			if (r < 0)
				goto Error;
			result = PyBool_FromLong(r);
 		 Error:
 		 	Py_XDECREF(vv);
 		 	Py_XDECREF(ww);
 		 	Py_XDECREF(one);
 		 	return result;
		}
	} /* else if (PyLong_Check(w)) */

	else	/* w isn't float, int, or long */
		goto Unimplemented;

 Compare:
	PyFPE_START_PROTECT("richcompare", return NULL)
	switch (op) {
	case Py_EQ:
		r = i == j;
		break;
	case Py_NE:
		r = i != j;
		break;
	case Py_LE:
		r = i <= j;
		break;
	case Py_GE:
		r = i >= j;
		break;
	case Py_LT:
		r = i < j;
		break;
	case Py_GT:
		r = i > j;
		break;
	}
	PyFPE_END_PROTECT(r)
	return PyBool_FromLong(r);

 Unimplemented:
	Py_INCREF(Py_NotImplemented);
	return Py_NotImplemented;
}

static long
float_hash(PyFloatObject *v)
{
	return _Py_HashDouble(v->ob_fval);
}

static PyObject *
float_add(PyObject *v, PyObject *w)
{
	double a,b;
	CONVERT_TO_DOUBLE(v, a);
	CONVERT_TO_DOUBLE(w, b);
	PyFPE_START_PROTECT("add", return 0)
	a = a + b;
	PyFPE_END_PROTECT(a)
	return PyFloat_FromDouble(a);
}

static PyObject *
float_sub(PyObject *v, PyObject *w)
{
	double a,b;
	CONVERT_TO_DOUBLE(v, a);
	CONVERT_TO_DOUBLE(w, b);
	PyFPE_START_PROTECT("subtract", return 0)
	a = a - b;
	PyFPE_END_PROTECT(a)
	return PyFloat_FromDouble(a);
}

static PyObject *
float_mul(PyObject *v, PyObject *w)
{
	double a,b;
	CONVERT_TO_DOUBLE(v, a);
	CONVERT_TO_DOUBLE(w, b);
	PyFPE_START_PROTECT("multiply", return 0)
	a = a * b;
	PyFPE_END_PROTECT(a)
	return PyFloat_FromDouble(a);
}

static PyObject *
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");
		return NULL;
	}
#endif
	PyFPE_START_PROTECT("divide", return 0)
	a = a / b;
	PyFPE_END_PROTECT(a)
	return PyFloat_FromDouble(a);
}

static PyObject *
float_rem(PyObject *v, PyObject *w)
{
	double vx, wx;
	double mod;
	CONVERT_TO_DOUBLE(v, vx);
	CONVERT_TO_DOUBLE(w, wx);
#ifdef Py_NAN
	if (wx == 0.0) {
		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
	   0 if wx < sqrt(smallest nonzero double) */
	if (mod && ((wx < 0) != (mod < 0))) {
		mod += wx;
	}
	PyFPE_END_PROTECT(mod)
	return PyFloat_FromDouble(mod);
}

static PyObject *
float_divmod(PyObject *v, PyObject *w)
{
	double vx, wx;
	double div, mod, floordiv;
 	CONVERT_TO_DOUBLE(v, vx);
 	CONVERT_TO_DOUBLE(w, wx);
	if (wx == 0.0) {
		PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()");
		return NULL;
	}
	PyFPE_START_PROTECT("divmod", return 0)
	mod = fmod(vx, wx);
	/* fmod is typically exact, so vx-mod is *mathematically* an
	   exact multiple of wx.  But this is fp arithmetic, and fp
	   vx - mod is an approximation; the result is that div may
	   not be an exact integral value after the division, although
	   it will always be very close to one.
	*/
	div = (vx - mod) / wx;
	if (mod) {
		/* ensure the remainder has the same sign as the denominator */
		if ((wx < 0) != (mod < 0)) {
			mod += wx;
			div -= 1.0;
		}
	}
	else {
		/* the remainder is zero, and in the presence of signed zeroes
		   fmod returns different results across platforms; ensure
		   it has the same sign as the denominator; we'd like to do
		   "mod = wx * 0.0", but that may get optimized away */
		mod *= mod;  /* hide "mod = +0" from optimizer */
		if (wx < 0.0)
			mod = -mod;
	}
	/* snap quotient to nearest integral value */
	if (div) {
		floordiv = floor(div);
		if (div - floordiv > 0.5)
			floordiv += 1.0;
	}
	else {
		/* div is zero - get the same sign as the true quotient */
		div *= div;	/* hide "div = +0" from optimizers */
		floordiv = div * vx / wx; /* zero w/ sign of vx/wx */
	}
	PyFPE_END_PROTECT(floordiv)
	return Py_BuildValue("(dd)", floordiv, mod);
}

static PyObject *
float_floor_div(PyObject *v, PyObject *w)
{
	PyObject *t, *r;

	t = float_divmod(v, w);
	if (t == NULL || t == Py_NotImplemented)
		return t;
	assert(PyTuple_CheckExact(t));
	r = PyTuple_GET_ITEM(t, 0);
	Py_INCREF(r);
	Py_DECREF(t);
	return r;
}

static PyObject *
float_pow(PyObject *v, PyObject *w, PyObject *z)
{
	double iv, iw, ix;

	if ((PyObject *)z != Py_None) {
		PyErr_SetString(PyExc_TypeError, "pow() 3rd argument not "
			"allowed unless all arguments are integers");
		return NULL;
	}

	CONVERT_TO_DOUBLE(v, iv);
	CONVERT_TO_DOUBLE(w, iw);

	/* Sort out special cases here instead of relying on pow() */
	if (iw == 0) { 		/* v**0 is 1, even 0**0 */
		return PyFloat_FromDouble(1.0);
	}
	if (iv == 0.0) {  /* 0**w is error if w<0, else 1 */
		if (iw < 0.0) {
			PyErr_SetString(PyExc_ZeroDivisionError,
					"0.0 cannot be raised to a negative power");
			return NULL;
		}
		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.
		 */
		if (iw != floor(iw)) {
			/* Negative numbers raised to fractional powers
			 * become complex.
			 */
			return PyComplex_Type.tp_as_number->nb_power(v, w, z);
		}
		/* iw is an exact integer, albeit perhaps a very large one.
		 * -1 raised to an exact integer should never be exceptional.
		 * Alas, some libms (chiefly glibc as of early 2003) return
		 * NaN and set EDOM on pow(-1, large_int) if the int doesn't
		 * happen to be representable in a *C* integer.  That's a
		 * bug; we let that slide in math.pow() (which currently
		 * reflects all platform accidents), but not for Python's **.
		 */
		 if (iv == -1.0 && Py_IS_FINITE(iw)) {
		 	/* Return 1 if iw is even, -1 if iw is odd; there's
		 	 * no guarantee that any C integral type is big
		 	 * enough to hold iw, so we have to check this
		 	 * indirectly.
		 	 */
		 	ix = floor(iw * 0.5) * 2.0;
			return PyFloat_FromDouble(ix == iw ? 1.0 : -1.0);
		}
		/* Else iv != -1.0, and overflow or underflow are possible.
		 * Unless we're to write pow() ourselves, we have to trust
		 * the platform to do this correctly.
		 */
	}
	errno = 0;
	PyFPE_START_PROTECT("pow", return NULL)
	ix = pow(iv, iw);
	PyFPE_END_PROTECT(ix)
	Py_ADJUST_ERANGE1(ix);
	if (errno != 0) {
		/* We don't expect any errno value other than ERANGE, but
		 * the range of libm bugs appears unbounded.
		 */
		PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError :
						     PyExc_ValueError);
		return NULL;
	}
	return PyFloat_FromDouble(ix);
}

static PyObject *
float_neg(PyFloatObject *v)
{
	return PyFloat_FromDouble(-v->ob_fval);
}

static PyObject *
float_abs(PyFloatObject *v)
{
	return PyFloat_FromDouble(fabs(v->ob_fval));
}

static int
float_bool(PyFloatObject *v)
{
	return v->ob_fval != 0.0;
}

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;
	errno = 0;
	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);
	double wholepart;	/* integral portion of x, rounded toward 0 */

	(void)modf(x, &wholepart);
	/* Try to get out cheap if this fits in a Python int.  The attempt
	 * to cast to long must be protected, as C doesn't define what
	 * happens if the double is too big to fit in a long.  Some rare
	 * systems raise an exception then (RISCOS was mentioned as one,
	 * and someone using a non-default option on Sun also bumped into
	 * that).  Note that checking for >= and <= LONG_{MIN,MAX} would
	 * still be vulnerable:  if a long has more bits of precision than
	 * a double, casting MIN/MAX to double may yield an approximation,
	 * and if that's rounded up, then, e.g., wholepart=LONG_MAX+1 would
	 * yield true from the C expression wholepart<=LONG_MAX, despite
	 * that wholepart is actually greater than LONG_MAX.
	 */
	if (LONG_MIN < wholepart && wholepart < LONG_MAX) {
		const long aslong = (long)wholepart;
		return PyLong_FromLong(aslong);
	}
	return PyLong_FromDouble(wholepart);
}

/* double_round: rounds a finite double to the closest multiple of
   10**-ndigits; here ndigits is within reasonable bounds (typically, -308 <=
   ndigits <= 323).  Returns a Python float, or sets a Python error and
   returns NULL on failure (OverflowError and memory errors are possible). */

#ifndef PY_NO_SHORT_FLOAT_REPR
/* version of double_round that uses the correctly-rounded string<->double
   conversions from Python/dtoa.c */

static PyObject *
double_round(double x, int ndigits) {

	double rounded;
	Py_ssize_t buflen, mybuflen=100;
	char *buf, *buf_end, shortbuf[100], *mybuf=shortbuf;
	int decpt, sign;
	PyObject *result = NULL;

	/* round to a decimal string */
	buf = _Py_dg_dtoa(x, 3, ndigits, &decpt, &sign, &buf_end);
	if (buf == NULL) {
		PyErr_NoMemory();
		return NULL;
	}

	/* Get new buffer if shortbuf is too small.  Space needed <= buf_end -
	buf + 8: (1 extra for '0', 1 for sign, 5 for exp, 1 for '\0').  */
	buflen = buf_end - buf;
	if (buflen + 8 > mybuflen) {
		mybuflen = buflen+8;
		mybuf = (char *)PyMem_Malloc(mybuflen);
		if (mybuf == NULL) {
			PyErr_NoMemory();
			goto exit;
		}
	}
	/* copy buf to mybuf, adding exponent, sign and leading 0 */
	PyOS_snprintf(mybuf, mybuflen, "%s0%se%d", (sign ? "-" : ""),
		      buf, decpt - (int)buflen);

	/* and convert the resulting string back to a double */
	errno = 0;
	rounded = _Py_dg_strtod(mybuf, NULL);
	if (errno == ERANGE && fabs(rounded) >= 1.)
		PyErr_SetString(PyExc_OverflowError,
				"rounded value too large to represent");
	else
		result = PyFloat_FromDouble(rounded);

	/* done computing value;  now clean up */
	if (mybuf != shortbuf)
		PyMem_Free(mybuf);
  exit:
	_Py_dg_freedtoa(buf);
	return result;
}

#else /* PY_NO_SHORT_FLOAT_REPR */

/* fallback version, to be used when correctly rounded binary<->decimal
   conversions aren't available */

static PyObject *
double_round(double x, int ndigits) {
	double pow1, pow2, y, z;
	if (ndigits >= 0) {
		if (ndigits > 22) {
			/* pow1 and pow2 are each safe from overflow, but
			   pow1*pow2 ~= pow(10.0, ndigits) might overflow */
			pow1 = pow(10.0, (double)(ndigits-22));
			pow2 = 1e22;
		}
		else {
			pow1 = pow(10.0, (double)ndigits);
			pow2 = 1.0;
		}
		y = (x*pow1)*pow2;
		/* if y overflows, then rounded value is exactly x */
		if (!Py_IS_FINITE(y))
			return PyFloat_FromDouble(x);
	}
	else {
		pow1 = pow(10.0, (double)-ndigits);
		pow2 = 1.0; /* unused; silences a gcc compiler warning */
		y = x / pow1;
	}

	z = round(y);
	if (fabs(y-z) == 0.5)
		/* halfway between two integers; use round-half-even */
		z = 2.0*round(y/2.0);

	if (ndigits >= 0)
		z = (z / pow2) / pow1;
	else
		z *= pow1;

	/* if computation resulted in overflow, raise OverflowError */
	if (!Py_IS_FINITE(z)) {
		PyErr_SetString(PyExc_OverflowError,
				"overflow occurred during round");
		return NULL;
	}

	return PyFloat_FromDouble(z);
}

#endif /* PY_NO_SHORT_FLOAT_REPR */

/* round a Python float v to the closest multiple of 10**-ndigits */

static PyObject *
float_round(PyObject *v, PyObject *args)
{
	double x, rounded;
	PyObject *o_ndigits = NULL;
	Py_ssize_t ndigits;

	x = PyFloat_AsDouble(v);
	if (!PyArg_ParseTuple(args, "|O", &o_ndigits))
		return NULL;
	if (o_ndigits == NULL) {
		/* single-argument round: round to nearest integer */
		rounded = round(x);
		if (fabs(x-rounded) == 0.5)
			/* halfway case: round to even */
			rounded = 2.0*round(x/2.0);
		return PyLong_FromDouble(rounded);
	}

	/* interpret second argument as a Py_ssize_t; clips on overflow */
	ndigits = PyNumber_AsSsize_t(o_ndigits, NULL);
	if (ndigits == -1 && PyErr_Occurred())
		return NULL;

	/* nans and infinities round to themselves */
	if (!Py_IS_FINITE(x))
		return PyFloat_FromDouble(x);

	/* Deal with extreme values for ndigits. For ndigits > NDIGITS_MAX, x
	   always rounds to itself.  For ndigits < NDIGITS_MIN, x always
	   rounds to +-0.0.  Here 0.30103 is an upper bound for log10(2). */
#define NDIGITS_MAX ((int)((DBL_MANT_DIG-DBL_MIN_EXP) * 0.30103))
#define NDIGITS_MIN (-(int)((DBL_MAX_EXP + 1) * 0.30103))
	if (ndigits > NDIGITS_MAX)
		/* return x */
		return PyFloat_FromDouble(x);
	else if (ndigits < NDIGITS_MIN)
		/* return 0.0, but with sign of x */
		return PyFloat_FromDouble(0.0*x);
	else
		/* finite x, and ndigits is not unreasonably large */
		return double_round(x, (int)ndigits);
#undef NDIGITS_MAX
#undef NDIGITS_MIN
}

static PyObject *
float_float(PyObject *v)
{
	if (PyFloat_CheckExact(v))
		Py_INCREF(v);
	else
		v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval);
	return v;
}

/* turn ASCII hex characters into integer values and vice versa */

static char
char_from_hex(int x)
{
	assert(0 <= x && x < 16);
	return "0123456789abcdef"[x];
}

static int
hex_from_char(char c) {
	int x;
	switch(c) {
	case '0':
		x = 0;
		break;
	case '1':
		x = 1;
		break;
	case '2':
		x = 2;
		break;
	case '3':
		x = 3;
		break;
	case '4':
		x = 4;
		break;
	case '5':
		x = 5;
		break;
	case '6':
		x = 6;
		break;
	case '7':
		x = 7;
		break;
	case '8':
		x = 8;
		break;
	case '9':
		x = 9;
		break;
	case 'a':
	case 'A':
		x = 10;
		break;
	case 'b':
	case 'B':
		x = 11;
		break;
	case 'c':
	case 'C':
		x = 12;
		break;
	case 'd':
	case 'D':
		x = 13;
		break;
	case 'e':
	case 'E':
		x = 14;
		break;
	case 'f':
	case 'F':
		x = 15;
		break;
	default:
		x = -1;
		break;
	}
	return x;
}

/* convert a float to a hexadecimal string */

/* TOHEX_NBITS is DBL_MANT_DIG rounded up to the next integer
   of the form 4k+1. */
#define TOHEX_NBITS DBL_MANT_DIG + 3 - (DBL_MANT_DIG+2)%4

static PyObject *
float_hex(PyObject *v)
{
	double x, m;
	int e, shift, i, si, esign;
	/* Space for 1+(TOHEX_NBITS-1)/4 digits, a decimal point, and the
	   trailing NUL byte. */
	char s[(TOHEX_NBITS-1)/4+3];

	CONVERT_TO_DOUBLE(v, x);

	if (Py_IS_NAN(x) || Py_IS_INFINITY(x))
		return float_str((PyFloatObject *)v);

	if (x == 0.0) {
		if(copysign(1.0, x) == -1.0)
			return PyUnicode_FromString("-0x0.0p+0");
		else
			return PyUnicode_FromString("0x0.0p+0");
	}

	m = frexp(fabs(x), &e);
	shift = 1 - MAX(DBL_MIN_EXP - e, 0);
	m = ldexp(m, shift);
	e -= shift;

	si = 0;
	s[si] = char_from_hex((int)m);
	si++;
	m -= (int)m;
	s[si] = '.';
	si++;
	for (i=0; i < (TOHEX_NBITS-1)/4; i++) {
		m *= 16.0;
		s[si] = char_from_hex((int)m);
		si++;
		m -= (int)m;
	}
	s[si] = '\0';

	if (e < 0) {
		esign = (int)'-';
		e = -e;
	}
	else
		esign = (int)'+';

	if (x < 0.0)
		return PyUnicode_FromFormat("-0x%sp%c%d", s, esign, e);
	else
		return PyUnicode_FromFormat("0x%sp%c%d", s, esign, e);
}

PyDoc_STRVAR(float_hex_doc,
"float.hex() -> string\n\
\n\
Return a hexadecimal representation of a floating-point number.\n\
>>> (-0.1).hex()\n\
'-0x1.999999999999ap-4'\n\
>>> 3.14159.hex()\n\
'0x1.921f9f01b866ep+1'");

/* Convert a hexadecimal string to a float. */

static PyObject *
float_fromhex(PyObject *cls, PyObject *arg)
{
	PyObject *result_as_float, *result;
	double x;
	long exp, top_exp, lsb, key_digit;
	char *s, *coeff_start, *s_store, *coeff_end, *exp_start, *s_end;
	int half_eps, digit, round_up, negate=0;
	Py_ssize_t length, ndigits, fdigits, i;

	/*
	 * For the sake of simplicity and correctness, we impose an artificial
	 * limit on ndigits, the total number of hex digits in the coefficient
	 * The limit is chosen to ensure that, writing exp for the exponent,
	 *
	 *   (1) if exp > LONG_MAX/2 then the value of the hex string is
	 *   guaranteed to overflow (provided it's nonzero)
	 *
	 *   (2) if exp < LONG_MIN/2 then the value of the hex string is
	 *   guaranteed to underflow to 0.
	 *
	 *   (3) if LONG_MIN/2 <= exp <= LONG_MAX/2 then there's no danger of
	 *   overflow in the calculation of exp and top_exp below.
	 *
	 * More specifically, ndigits is assumed to satisfy the following
	 * inequalities:
	 *
	 *   4*ndigits <= DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2
	 *   4*ndigits <= LONG_MAX/2 + 1 - DBL_MAX_EXP
	 *
	 * If either of these inequalities is not satisfied, a ValueError is
	 * raised.  Otherwise, write x for the value of the hex string, and
	 * assume x is nonzero.  Then
	 *
	 *   2**(exp-4*ndigits) <= |x| < 2**(exp+4*ndigits).
	 *
	 * Now if exp > LONG_MAX/2 then:
	 *
	 *   exp - 4*ndigits >= LONG_MAX/2 + 1 - (LONG_MAX/2 + 1 - DBL_MAX_EXP)
	 *                    = DBL_MAX_EXP
	 *
	 * so |x| >= 2**DBL_MAX_EXP, which is too large to be stored in C
	 * double, so overflows.  If exp < LONG_MIN/2, then
	 *
	 *   exp + 4*ndigits <= LONG_MIN/2 - 1 + (
	 *                      DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2)
	 *                    = DBL_MIN_EXP - DBL_MANT_DIG - 1
	 *
	 * and so |x| < 2**(DBL_MIN_EXP-DBL_MANT_DIG-1), hence underflows to 0
	 * when converted to a C double.
	 *
	 * It's easy to show that if LONG_MIN/2 <= exp <= LONG_MAX/2 then both
	 * exp+4*ndigits and exp-4*ndigits are within the range of a long.
	 */

	s = _PyUnicode_AsStringAndSize(arg, &length);
	if (s == NULL)
		return NULL;
	s_end = s + length;

	/********************
	 * Parse the string *
	 ********************/

	/* leading whitespace */
	while (Py_ISSPACE(*s))
		s++;

	/* infinities and nans */
	x = _Py_parse_inf_or_nan(s, &coeff_end);
	if (coeff_end != s) {
		s = coeff_end;
		goto finished;
	}

	/* optional sign */
	if (*s == '-') {
		s++;
		negate = 1;
	}
	else if (*s == '+')
		s++;

	/* [0x] */
	s_store = s;
	if (*s == '0') {
		s++;
		if (*s == 'x' || *s == 'X')
			s++;
		else
			s = s_store;
	}

	/* coefficient: <integer> [. <fraction>] */
	coeff_start = s;
	while (hex_from_char(*s) >= 0)
		s++;
	s_store = s;
	if (*s == '.') {
		s++;
		while (hex_from_char(*s) >= 0)
			s++;
		coeff_end = s-1;
	}
	else
		coeff_end = s;

	/* ndigits = total # of hex digits; fdigits = # after point */
	ndigits = coeff_end - coeff_start;
	fdigits = coeff_end - s_store;
	if (ndigits == 0)
		goto parse_error;
	if (ndigits > MIN(DBL_MIN_EXP - DBL_MANT_DIG - LONG_MIN/2,
			  LONG_MAX/2 + 1 - DBL_MAX_EXP)/4)
		goto insane_length_error;

	/* [p <exponent>] */
	if (*s == 'p' || *s == 'P') {
		s++;
		exp_start = s;
		if (*s == '-' || *s == '+')
			s++;
		if (!('0' <= *s && *s <= '9'))
			goto parse_error;
		s++;
		while ('0' <= *s && *s <= '9')
			s++;
		exp = strtol(exp_start, NULL, 10);
	}
	else
		exp = 0;

/* for 0 <= j < ndigits, HEX_DIGIT(j) gives the jth most significant digit */
#define HEX_DIGIT(j) hex_from_char(*((j) < fdigits ?		\
				     coeff_end-(j) :			\
				     coeff_end-1-(j)))

	/*******************************************
	 * Compute rounded value of the hex string *
	 *******************************************/

	/* Discard leading zeros, and catch extreme overflow and underflow */
	while (ndigits > 0 && HEX_DIGIT(ndigits-1) == 0)
		ndigits--;
	if (ndigits == 0 || exp < LONG_MIN/2) {
		x = 0.0;
		goto finished;
	}
	if (exp > LONG_MAX/2)
		goto overflow_error;

	/* Adjust exponent for fractional part. */
	exp = exp - 4*((long)fdigits);

	/* top_exp = 1 more than exponent of most sig. bit of coefficient */
	top_exp = exp + 4*((long)ndigits - 1);
	for (digit = HEX_DIGIT(ndigits-1); digit != 0; digit /= 2)
		top_exp++;

	/* catch almost all nonextreme cases of overflow and underflow here */
	if (top_exp < DBL_MIN_EXP - DBL_MANT_DIG) {
		x = 0.0;
		goto finished;
	}
	if (top_exp > DBL_MAX_EXP)
		goto overflow_error;

	/* lsb = exponent of least significant bit of the *rounded* value.
	   This is top_exp - DBL_MANT_DIG unless result is subnormal. */
	lsb = MAX(top_exp, (long)DBL_MIN_EXP) - DBL_MANT_DIG;

	x = 0.0;
	if (exp >= lsb) {
		/* no rounding required */
		for (i = ndigits-1; i >= 0; i--)
			x = 16.0*x + HEX_DIGIT(i);
		x = ldexp(x, (int)(exp));
		goto finished;
	}
	/* rounding required.  key_digit is the index of the hex digit
	   containing the first bit to be rounded away. */
	half_eps = 1 << (int)((lsb - exp - 1) % 4);
	key_digit = (lsb - exp - 1) / 4;
	for (i = ndigits-1; i > key_digit; i--)
		x = 16.0*x + HEX_DIGIT(i);
	digit = HEX_DIGIT(key_digit);
	x = 16.0*x + (double)(digit & (16-2*half_eps));

	/* round-half-even: round up if bit lsb-1 is 1 and at least one of
	   bits lsb, lsb-2, lsb-3, lsb-4, ... is 1. */
	if ((digit & half_eps) != 0) {
		round_up = 0;
		if ((digit & (3*half_eps-1)) != 0 ||
		    (half_eps == 8 && (HEX_DIGIT(key_digit+1) & 1) != 0))
			round_up = 1;
		else
			for (i = key_digit-1; i >= 0; i--)
				if (HEX_DIGIT(i) != 0) {
					round_up = 1;
					break;
				}
		if (round_up == 1) {
			x += 2*half_eps;
			if (top_exp == DBL_MAX_EXP &&
			    x == ldexp((double)(2*half_eps), DBL_MANT_DIG))
				/* overflow corner case: pre-rounded value <
				   2**DBL_MAX_EXP; rounded=2**DBL_MAX_EXP. */
				goto overflow_error;
		}
	}
	x = ldexp(x, (int)(exp+4*key_digit));

  finished:
	/* optional trailing whitespace leading to the end of the string */
	while (Py_ISSPACE(*s))
		s++;
	if (s != s_end)
		goto parse_error;
	result_as_float = Py_BuildValue("(d)", negate ? -x : x);
	if (result_as_float == NULL)
		return NULL;
	result = PyObject_CallObject(cls, result_as_float);
	Py_DECREF(result_as_float);
	return result;

  overflow_error:
	PyErr_SetString(PyExc_OverflowError,
			"hexadecimal value too large to represent as a float");
	return NULL;

  parse_error:
	PyErr_SetString(PyExc_ValueError,
			"invalid hexadecimal floating-point string");
	return NULL;

  insane_length_error:
	PyErr_SetString(PyExc_ValueError,
			"hexadecimal string too long to convert");
	return NULL;
}

PyDoc_STRVAR(float_fromhex_doc,
"float.fromhex(string) -> float\n\
\n\
Create a floating-point number from a hexadecimal string.\n\
>>> float.fromhex('0x1.ffffp10')\n\
2047.984375\n\
>>> float.fromhex('-0x1p-1074')\n\
-4.9406564584124654e-324");


static PyObject *
float_as_integer_ratio(PyObject *v, PyObject *unused)
{
	double self;
	double float_part;
	int exponent;
	int i;

	PyObject *prev;
	PyObject *py_exponent = NULL;
	PyObject *numerator = NULL;
	PyObject *denominator = NULL;
	PyObject *result_pair = NULL;
	PyNumberMethods *long_methods = PyLong_Type.tp_as_number;

#define INPLACE_UPDATE(obj, call) \
	prev = obj; \
	obj = call; \
	Py_DECREF(prev); \

	CONVERT_TO_DOUBLE(v, self);

	if (Py_IS_INFINITY(self)) {
	  PyErr_SetString(PyExc_OverflowError,
			  "Cannot pass infinity to float.as_integer_ratio.");
	  return NULL;
	}
#ifdef Py_NAN
	if (Py_IS_NAN(self)) {
	  PyErr_SetString(PyExc_ValueError,
			  "Cannot pass NaN to float.as_integer_ratio.");
	  return NULL;
	}
#endif

	PyFPE_START_PROTECT("as_integer_ratio", goto error);
	float_part = frexp(self, &exponent);  	/* self == float_part * 2**exponent exactly */
	PyFPE_END_PROTECT(float_part);
	
	for (i=0; i<300 && float_part != floor(float_part) ; i++) {
		float_part *= 2.0;
		exponent--;
	}	
	/* self == float_part * 2**exponent exactly and float_part is integral.
           If FLT_RADIX != 2, the 300 steps may leave a tiny fractional part
           to be truncated by PyLong_FromDouble(). */

	numerator = PyLong_FromDouble(float_part);
	if (numerator == NULL) goto error;

	/* fold in 2**exponent */
	denominator = PyLong_FromLong(1);
	py_exponent = PyLong_FromLong(labs((long)exponent));
	if (py_exponent == NULL) goto error;
	INPLACE_UPDATE(py_exponent,
		       long_methods->nb_lshift(denominator, py_exponent));
	if (py_exponent == NULL) goto error;
	if (exponent > 0) {
		INPLACE_UPDATE(numerator,
			       long_methods->nb_multiply(numerator, py_exponent));
		if (numerator == NULL) goto error;
	}
	else {
		Py_DECREF(denominator);
		denominator = py_exponent;
		py_exponent = NULL;
	}

	result_pair = PyTuple_Pack(2, numerator, denominator);

#undef INPLACE_UPDATE
error:
	Py_XDECREF(py_exponent);
	Py_XDECREF(denominator);
	Py_XDECREF(numerator);
	return result_pair;
}

PyDoc_STRVAR(float_as_integer_ratio_doc,
"float.as_integer_ratio() -> (int, int)\n"
"\n"
"Returns a pair of integers, whose ratio is exactly equal to the original\n"
"float and with a positive denominator.\n"
"Raises OverflowError on infinities and a ValueError on NaNs.\n"
"\n"
">>> (10.0).as_integer_ratio()\n"
"(10, 1)\n"
">>> (0.0).as_integer_ratio()\n"
"(0, 1)\n"
">>> (-.25).as_integer_ratio()\n"
"(-1, 4)");


static PyObject *
float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);

static PyObject *
float_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	PyObject *x = Py_False; /* Integer zero */
	static char *kwlist[] = {"x", 0};

	if (type != &PyFloat_Type)
		return float_subtype_new(type, args, kwds); /* Wimp out */
	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x))
		return NULL;
	/* If it's a string, but not a string subclass, use
	   PyFloat_FromString. */
	if (PyUnicode_CheckExact(x))
		return PyFloat_FromString(x);
	return PyNumber_Float(x);
}

/* Wimpy, slow approach to tp_new calls for subtypes of float:
   first create a regular float from whatever arguments we got,
   then allocate a subtype instance and initialize its ob_fval
   from the regular float.  The regular float is then thrown away.
*/
static PyObject *
float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
	PyObject *tmp, *newobj;

	assert(PyType_IsSubtype(type, &PyFloat_Type));
	tmp = float_new(&PyFloat_Type, args, kwds);
	if (tmp == NULL)
		return NULL;
	assert(PyFloat_CheckExact(tmp));
	newobj = type->tp_alloc(type, 0);
	if (newobj == NULL) {
		Py_DECREF(tmp);
		return NULL;
	}
	((PyFloatObject *)newobj)->ob_fval = ((PyFloatObject *)tmp)->ob_fval;
	Py_DECREF(tmp);
	return newobj;
}

static PyObject *
float_getnewargs(PyFloatObject *v)
{
	return Py_BuildValue("(d)", v->ob_fval);
}

/* this is for the benefit of the pack/unpack routines below */

typedef enum {
	unknown_format, ieee_big_endian_format, ieee_little_endian_format
} float_format_type;

static float_format_type double_format, float_format;
static float_format_type detected_double_format, detected_float_format;

static PyObject *
float_getformat(PyTypeObject *v, PyObject* arg)
{
	char* s;
	float_format_type r;

	if (!PyUnicode_Check(arg)) {
		PyErr_Format(PyExc_TypeError,
	     "__getformat__() argument must be string, not %.500s",
			     Py_TYPE(arg)->tp_name);
		return NULL;
	}
	s = _PyUnicode_AsString(arg);
	if (s == NULL)
		return NULL;
	if (strcmp(s, "double") == 0) {
		r = double_format;
	}
	else if (strcmp(s, "float") == 0) {
		r = float_format;
	}
	else {
		PyErr_SetString(PyExc_ValueError,
				"__getformat__() argument 1 must be "
				"'double' or 'float'");
		return NULL;
	}
	
	switch (r) {
	case unknown_format:
		return PyUnicode_FromString("unknown");
	case ieee_little_endian_format:
		return PyUnicode_FromString("IEEE, little-endian");
	case ieee_big_endian_format:
		return PyUnicode_FromString("IEEE, big-endian");
	default:
		Py_FatalError("insane float_format or double_format");
		return NULL;
	}
}

PyDoc_STRVAR(float_getformat_doc,
"float.__getformat__(typestr) -> string\n"
"\n"
"You probably don't want to use this function.  It exists mainly to be\n"
"used in Python's test suite.\n"
"\n"
"typestr must be 'double' or 'float'.  This function returns whichever of\n"
"'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the\n"
"format of floating point numbers used by the C type named by typestr.");

static PyObject *
float_setformat(PyTypeObject *v, PyObject* args)
{
	char* typestr;
	char* format;
	float_format_type f;
	float_format_type detected;
	float_format_type *p;

	if (!PyArg_ParseTuple(args, "ss:__setformat__", &typestr, &format))
		return NULL;

	if (strcmp(typestr, "double") == 0) {
		p = &double_format;
		detected = detected_double_format;
	}
	else if (strcmp(typestr, "float") == 0) {
		p = &float_format;
		detected = detected_float_format;
	}
	else {
		PyErr_SetString(PyExc_ValueError,
				"__setformat__() argument 1 must "
				"be 'double' or 'float'");
		return NULL;
	}
	
	if (strcmp(format, "unknown") == 0) {
		f = unknown_format;
	}
	else if (strcmp(format, "IEEE, little-endian") == 0) {
		f = ieee_little_endian_format;
	}
	else if (strcmp(format, "IEEE, big-endian") == 0) {
		f = ieee_big_endian_format;
	}
	else {
		PyErr_SetString(PyExc_ValueError,
				"__setformat__() argument 2 must be "
				"'unknown', 'IEEE, little-endian' or "
				"'IEEE, big-endian'");
		return NULL;

	}

	if (f != unknown_format && f != detected) {
		PyErr_Format(PyExc_ValueError,
			     "can only set %s format to 'unknown' or the "
			     "detected platform value", typestr);
		return NULL;
	}

	*p = f;
	Py_RETURN_NONE;
}

PyDoc_STRVAR(float_setformat_doc,
"float.__setformat__(typestr, fmt) -> None\n"
"\n"
"You probably don't want to use this function.  It exists mainly to be\n"
"used in Python's test suite.\n"
"\n"
"typestr must be 'double' or 'float'.  fmt must be one of 'unknown',\n"
"'IEEE, big-endian' or 'IEEE, little-endian', and in addition can only be\n"
"one of the latter two if it appears to match the underlying C reality.\n"
"\n"
"Overrides the automatic determination of C-level floating point type.\n"
"This affects how floats are converted to and from binary strings.");

static PyObject *
float_getzero(PyObject *v, void *closure)
{
	return PyFloat_FromDouble(0.0);
}

static PyObject *
float__format__(PyObject *self, PyObject *args)
{
	PyObject *format_spec;

	if (!PyArg_ParseTuple(args, "U:__format__", &format_spec))
		return NULL;
	return _PyFloat_FormatAdvanced(self,
				       PyUnicode_AS_UNICODE(format_spec),
				       PyUnicode_GET_SIZE(format_spec));
}

PyDoc_STRVAR(float__format__doc,
"float.__format__(format_spec) -> string\n"
"\n"
"Formats the float according to format_spec.");


static PyMethodDef float_methods[] = {
	{"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."},
	{"__round__",	(PyCFunction)float_round, METH_VARARGS,
         "Returns the Integral closest to x, rounding half toward even.\n"
         "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},
	{"fromhex", (PyCFunction)float_fromhex,
	 METH_O|METH_CLASS, float_fromhex_doc},
	{"hex", (PyCFunction)float_hex,
	 METH_NOARGS, float_hex_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},
	{"__setformat__",	(PyCFunction)float_setformat,	
	 METH_VARARGS|METH_CLASS,	float_setformat_doc},
        {"__format__",          (PyCFunction)float__format__,
         METH_VARARGS,                  float__format__doc},
	{NULL,		NULL}		/* sentinel */
};

static PyGetSetDef float_getset[] = {
    {"real", 
     (getter)float_float, (setter)NULL,
     "the real part of a complex number",
     NULL},
    {"imag", 
     (getter)float_getzero, (setter)NULL,
     "the imaginary part of a complex number",
     NULL},
    {NULL}  /* Sentinel */
};

PyDoc_STRVAR(float_doc,
"float(x) -> floating point number\n\
\n\
Convert a string or number to a floating point number, if possible.");


static PyNumberMethods float_as_number = {
	float_add, 	/*nb_add*/
	float_sub, 	/*nb_subtract*/
	float_mul, 	/*nb_multiply*/
	float_rem, 	/*nb_remainder*/
	float_divmod, 	/*nb_divmod*/
	float_pow, 	/*nb_power*/
	(unaryfunc)float_neg, /*nb_negative*/
	(unaryfunc)float_float, /*nb_positive*/
	(unaryfunc)float_abs, /*nb_absolute*/
	(inquiry)float_bool, /*nb_bool*/
	0,		/*nb_invert*/
	0,		/*nb_lshift*/
	0,		/*nb_rshift*/
	0,		/*nb_and*/
	0,		/*nb_xor*/
	0,		/*nb_or*/
	float_trunc,	/*nb_int*/
	0,		/*nb_reserved*/
	float_float,	/*nb_float*/
	0,		/* nb_inplace_add */
	0,		/* nb_inplace_subtract */
	0,		/* nb_inplace_multiply */
	0,		/* nb_inplace_remainder */
	0, 		/* nb_inplace_power */
	0,		/* nb_inplace_lshift */
	0,		/* nb_inplace_rshift */
	0,		/* nb_inplace_and */
	0,		/* nb_inplace_xor */
	0,		/* nb_inplace_or */
	float_floor_div, /* nb_floor_divide */
	float_div,	/* nb_true_divide */
	0,		/* nb_inplace_floor_divide */
	0,		/* nb_inplace_true_divide */
};

PyTypeObject PyFloat_Type = {
	PyVarObject_HEAD_INIT(&PyType_Type, 0)
	"float",
	sizeof(PyFloatObject),
	0,
	(destructor)float_dealloc,		/* tp_dealloc */
	0,			 		/* tp_print */
	0,					/* tp_getattr */
	0,					/* tp_setattr */
	0,			 		/* tp_reserved */
	(reprfunc)float_repr,			/* tp_repr */
	&float_as_number,			/* tp_as_number */
	0,					/* tp_as_sequence */
	0,					/* tp_as_mapping */
	(hashfunc)float_hash,			/* tp_hash */
	0,					/* tp_call */
	(reprfunc)float_str,			/* tp_str */
	PyObject_GenericGetAttr,		/* tp_getattro */
	0,					/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
	float_doc,				/* tp_doc */
 	0,					/* tp_traverse */
	0,					/* tp_clear */
	float_richcompare,			/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	0,					/* tp_iter */
	0,					/* tp_iternext */
	float_methods,				/* tp_methods */
	0,					/* tp_members */
	float_getset,				/* tp_getset */
	0,					/* tp_base */
	0,					/* tp_dict */
	0,					/* tp_descr_get */
	0,					/* tp_descr_set */
	0,					/* tp_dictoffset */
	0,					/* tp_init */
	0,					/* tp_alloc */
	float_new,				/* tp_new */
};

void
_PyFloat_Init(void)
{
	/* We attempt to determine if this machine is using IEEE
	   floating point formats by peering at the bits of some
	   carefully chosen values.  If it looks like we are on an
	   IEEE platform, the float packing/unpacking routines can
	   just copy bits, if not they resort to arithmetic & shifts
	   and masks.  The shifts & masks approach works on all finite
	   values, but what happens to infinities, NaNs and signed
	   zeroes on packing is an accident, and attempting to unpack
	   a NaN or an infinity will raise an exception.

	   Note that if we're on some whacked-out platform which uses
	   IEEE formats but isn't strictly little-endian or big-
	   endian, we will fall back to the portable shifts & masks
	   method. */

#if SIZEOF_DOUBLE == 8
	{
		double x = 9006104071832581.0;
		if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0)
			detected_double_format = ieee_big_endian_format;
		else if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0)
			detected_double_format = ieee_little_endian_format;
		else 
			detected_double_format = unknown_format;
	}
#else
	detected_double_format = unknown_format;
#endif

#if SIZEOF_FLOAT == 4
	{
		float y = 16711938.0;
		if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0)
			detected_float_format = ieee_big_endian_format;
		else if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0)
			detected_float_format = ieee_little_endian_format;
		else 
			detected_float_format = unknown_format;
	}
#else
	detected_float_format = unknown_format;
#endif

	double_format = detected_double_format;
	float_format = detected_float_format;

	/* Init float info */
	if (FloatInfoType.tp_name == 0)
		PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc);
}

int
PyFloat_ClearFreeList(void)
{
	PyFloatObject *p;
	PyFloatBlock *list, *next;
	int i;
	int u;			/* remaining unfreed floats per block */
	int freelist_size = 0;

	list = block_list;
	block_list = NULL;
	free_list = NULL;
	while (list != NULL) {
		u = 0;
		for (i = 0, p = &list->objects[0];
		     i < N_FLOATOBJECTS;
		     i++, p++) {
			if (PyFloat_CheckExact(p) && Py_REFCNT(p) != 0)
				u++;
		}
		next = list->next;
		if (u) {
			list->next = block_list;
			block_list = list;
			for (i = 0, p = &list->objects[0];
			     i < N_FLOATOBJECTS;
			     i++, p++) {
				if (!PyFloat_CheckExact(p) ||
				    Py_REFCNT(p) == 0) {
					Py_TYPE(p) = (struct _typeobject *)
						free_list;
					free_list = p;
				}
			}
		}
		else {
			PyMem_FREE(list);
		}
		freelist_size += u;
		list = next;
	}
	return freelist_size;
}

void
PyFloat_Fini(void)
{
	PyFloatObject *p;
	PyFloatBlock *list;
	int i;
	int u;			/* total unfreed floats per block */

	u = PyFloat_ClearFreeList();

	if (!Py_VerboseFlag)
		return;
	fprintf(stderr, "# cleanup floats");
	if (!u) {
		fprintf(stderr, "\n");
	}
	else {
		fprintf(stderr,
			": %d unfreed float%s\n",
			u, u == 1 ? "" : "s");
	}
	if (Py_VerboseFlag > 1) {
		list = block_list;
		while (list != NULL) {
			for (i = 0, p = &list->objects[0];
			     i < N_FLOATOBJECTS;
			     i++, p++) {
				if (PyFloat_CheckExact(p) &&
				    Py_REFCNT(p) != 0) {
					char *buf = PyOS_double_to_string(
						PyFloat_AS_DOUBLE(p), 'r',
						0, 0, NULL);
					if (buf) {
						/* XXX(twouters) cast
						   refcount to long
						   until %zd is
						   universally
						   available
						*/
						fprintf(stderr,
			     "#   <float at %p, refcnt=%ld, val=%s>\n",
						p, (long)Py_REFCNT(p), buf);
						PyMem_Free(buf);
					}
				}
			}
			list = list->next;
		}
	}
}

/*----------------------------------------------------------------------------
 * _PyFloat_{Pack,Unpack}{4,8}.  See floatobject.h.
 */
int
_PyFloat_Pack4(double x, unsigned char *p, int le)
{
	if (float_format == unknown_format) {
		unsigned char sign;
		int e;
		double f;
		unsigned int fbits;
		int incr = 1;

		if (le) {
			p += 3;
			incr = -1;
		}

		if (x < 0) {
			sign = 1;
			x = -x;
		}
		else
			sign = 0;

		f = frexp(x, &e);

		/* Normalize f to be in the range [1.0, 2.0) */
		if (0.5 <= f && f < 1.0) {
			f *= 2.0;
			e--;
		}
		else if (f == 0.0)
			e = 0;
		else {
			PyErr_SetString(PyExc_SystemError,
					"frexp() result out of range");
			return -1;
		}

		if (e >= 128)
			goto Overflow;
		else if (e < -126) {
			/* Gradual underflow */
			f = ldexp(f, 126 + e);
			e = 0;
		}
		else if (!(e == 0 && f == 0.0)) {
			e += 127;
			f -= 1.0; /* Get rid of leading 1 */
		}

		f *= 8388608.0; /* 2**23 */
		fbits = (unsigned int)(f + 0.5); /* Round */
		assert(fbits <= 8388608);
		if (fbits >> 23) {
			/* The carry propagated out of a string of 23 1 bits. */
			fbits = 0;
			++e;
			if (e >= 255)
				goto Overflow;
		}

		/* First byte */
		*p = (sign << 7) | (e >> 1);
		p += incr;

		/* Second byte */
		*p = (char) (((e & 1) << 7) | (fbits >> 16));
		p += incr;

		/* Third byte */
		*p = (fbits >> 8) & 0xFF;
		p += incr;

		/* Fourth byte */
		*p = fbits & 0xFF;

		/* Done */
		return 0;

	}
	else {
		float y = (float)x;
		const char *s = (char*)&y;
		int i, incr = 1;

		if (Py_IS_INFINITY(y) && !Py_IS_INFINITY(x))
			goto Overflow;

		if ((float_format == ieee_little_endian_format && !le)
		    || (float_format == ieee_big_endian_format && le)) {
			p += 3;
			incr = -1;
		}

		for (i = 0; i < 4; i++) {
			*p = *s++;
			p += incr;
		}
		return 0;
	}
  Overflow:
	PyErr_SetString(PyExc_OverflowError,
			"float too large to pack with f format");
	return -1;
}

int
_PyFloat_Pack8(double x, unsigned char *p, int le)
{
	if (double_format == unknown_format) {
		unsigned char sign;
		int e;
		double f;
		unsigned int fhi, flo;
		int incr = 1;

		if (le) {
			p += 7;
			incr = -1;
		}

		if (x < 0) {
			sign = 1;
			x = -x;
		}
		else
			sign = 0;

		f = frexp(x, &e);

		/* Normalize f to be in the range [1.0, 2.0) */
		if (0.5 <= f && f < 1.0) {
			f *= 2.0;
			e--;
		}
		else if (f == 0.0)
			e = 0;
		else {
			PyErr_SetString(PyExc_SystemError,
					"frexp() result out of range");
			return -1;
		}

		if (e >= 1024)
			goto Overflow;
		else if (e < -1022) {
			/* Gradual underflow */
			f = ldexp(f, 1022 + e);
			e = 0;
		}
		else if (!(e == 0 && f == 0.0)) {
			e += 1023;
			f -= 1.0; /* Get rid of leading 1 */
		}

		/* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
		f *= 268435456.0; /* 2**28 */
		fhi = (unsigned int)f; /* Truncate */
		assert(fhi < 268435456);

		f -= (double)fhi;
		f *= 16777216.0; /* 2**24 */
		flo = (unsigned int)(f + 0.5); /* Round */
		assert(flo <= 16777216);
		if (flo >> 24) {
			/* The carry propagated out of a string of 24 1 bits. */
			flo = 0;
			++fhi;
			if (fhi >> 28) {
				/* And it also progagated out of the next 28 bits. */
				fhi = 0;
				++e;
				if (e >= 2047)
					goto Overflow;
			}
		}

		/* First byte */
		*p = (sign << 7) | (e >> 4);
		p += incr;

		/* Second byte */
		*p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24));
		p += incr;

		/* Third byte */
		*p = (fhi >> 16) & 0xFF;
		p += incr;

		/* Fourth byte */
		*p = (fhi >> 8) & 0xFF;
		p += incr;

		/* Fifth byte */
		*p = fhi & 0xFF;
		p += incr;

		/* Sixth byte */
		*p = (flo >> 16) & 0xFF;
		p += incr;

		/* Seventh byte */
		*p = (flo >> 8) & 0xFF;
		p += incr;

		/* Eighth byte */
		*p = flo & 0xFF;
		p += incr;

		/* Done */
		return 0;

	  Overflow:
		PyErr_SetString(PyExc_OverflowError,
				"float too large to pack with d format");
		return -1;
	}
	else {
		const char *s = (char*)&x;
		int i, incr = 1;

		if ((double_format == ieee_little_endian_format && !le)
		    || (double_format == ieee_big_endian_format && le)) {
			p += 7;
			incr = -1;
		}
		
		for (i = 0; i < 8; i++) {
			*p = *s++;
			p += incr;
		}
		return 0;
	}
}

double
_PyFloat_Unpack4(const unsigned char *p, int le)
{
	if (float_format == unknown_format) {
		unsigned char sign;
		int e;
		unsigned int f;
		double x;
		int incr = 1;

		if (le) {
			p += 3;
			incr = -1;
		}

		/* First byte */
		sign = (*p >> 7) & 1;
		e = (*p & 0x7F) << 1;
		p += incr;

		/* Second byte */
		e |= (*p >> 7) & 1;
		f = (*p & 0x7F) << 16;
		p += incr;

		if (e == 255) {
			PyErr_SetString(
				PyExc_ValueError,
				"can't unpack IEEE 754 special value "
				"on non-IEEE platform");
			return -1;
		}

		/* Third byte */
		f |= *p << 8;
		p += incr;

		/* Fourth byte */
		f |= *p;

		x = (double)f / 8388608.0;

		/* XXX This sadly ignores Inf/NaN issues */
		if (e == 0)
			e = -126;
		else {
			x += 1.0;
			e -= 127;
		}
		x = ldexp(x, e);

		if (sign)
			x = -x;

		return x;
	}
	else {
		float x;

		if ((float_format == ieee_little_endian_format && !le)
		    || (float_format == ieee_big_endian_format && le)) {
			char buf[4];
			char *d = &buf[3];
			int i;

			for (i = 0; i < 4; i++) {
				*d-- = *p++;
			}
			memcpy(&x, buf, 4);
		}
		else {
			memcpy(&x, p, 4);
		}

		return x;
	}		
}

double
_PyFloat_Unpack8(const unsigned char *p, int le)
{
	if (double_format == unknown_format) {
		unsigned char sign;
		int e;
		unsigned int fhi, flo;
		double x;
		int incr = 1;

		if (le) {
			p += 7;
			incr = -1;
		}

		/* First byte */
		sign = (*p >> 7) & 1;
		e = (*p & 0x7F) << 4;
		
		p += incr;

		/* Second byte */
		e |= (*p >> 4) & 0xF;
		fhi = (*p & 0xF) << 24;
		p += incr;

		if (e == 2047) {
			PyErr_SetString(
				PyExc_ValueError,
				"can't unpack IEEE 754 special value "
				"on non-IEEE platform");
			return -1.0;
		}

		/* Third byte */
		fhi |= *p << 16;
		p += incr;

		/* Fourth byte */
		fhi |= *p  << 8;
		p += incr;

		/* Fifth byte */
		fhi |= *p;
		p += incr;

		/* Sixth byte */
		flo = *p << 16;
		p += incr;

		/* Seventh byte */
		flo |= *p << 8;
		p += incr;

		/* Eighth byte */
		flo |= *p;

		x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
		x /= 268435456.0; /* 2**28 */

		if (e == 0)
			e = -1022;
		else {
			x += 1.0;
			e -= 1023;
		}
		x = ldexp(x, e);

		if (sign)
			x = -x;

		return x;
	}
	else {
		double x;

		if ((double_format == ieee_little_endian_format && !le)
		    || (double_format == ieee_big_endian_format && le)) {
			char buf[8];
			char *d = &buf[7];
			int i;
			
			for (i = 0; i < 8; i++) {
				*d-- = *p++;
			}
			memcpy(&x, buf, 8);
		}
		else {
			memcpy(&x, p, 8);
		}

		return x;
	}
}
