
/* 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, *sp;
	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 (*s && isspace(Py_CHARMASK(*s)))
		s++;
	if (*s == '\0') {
		PyErr_SetString(PyExc_ValueError, "empty string for float()");
		goto error;
	}
	sp = s;
	/* We don't care about overflow or underflow.  If the platform supports
	 * them, infinities and signed zeroes (on underflow) are fine.
	 * However, strtod can return 0 for denormalized numbers, where atof
	 * does not.  So (alas!) we special-case a zero result.  Note that
	 * whether strtod sets errno on underflow is not defined, so we can't
	 * key off errno.
         */
	PyFPE_START_PROTECT("strtod", goto error)
	x = PyOS_ascii_strtod(s, (char **)&end);
	PyFPE_END_PROTECT(x)
	errno = 0;
	/* Believe it or not, Solaris 2.6 can move end *beyond* the null
	   byte at the end of the string, when the input is inf(inity). */
	if (end > last)
		end = last;
	/* Check for inf and nan. This is done late because it rarely happens. */
	if (end == s) {
		char *p = (char*)sp;
		int sign = 1;

		if (*p == '-') {
			sign = -1;
			p++;
		}
		if (*p == '+') {
			p++;
		}
		if (PyOS_strnicmp(p, "inf", 4) == 0) {
			if (s_buffer != NULL)
				PyMem_FREE(s_buffer);
			Py_RETURN_INF(sign);
		}
		if (PyOS_strnicmp(p, "infinity", 9) == 0) {
			if (s_buffer != NULL)
				PyMem_FREE(s_buffer);
			Py_RETURN_INF(sign);
		}
#ifdef Py_NAN
		if(PyOS_strnicmp(p, "nan", 4) == 0) {
			if (s_buffer != NULL)
				PyMem_FREE(s_buffer);
			Py_RETURN_NAN;
		}
#endif
		PyOS_snprintf(buffer, sizeof(buffer),
			      "invalid literal for float(): %.200s", s);
		PyErr_SetString(PyExc_ValueError, buffer);
		goto error;
	}
	/* Since end != s, the platform made *some* kind of sense out
	   of the input.  Trust it. */
	while (*end && isspace(Py_CHARMASK(*end)))
		end++;
	if (*end != '\0') {
		PyOS_snprintf(buffer, sizeof(buffer),
			      "invalid literal for float(): %.200s", s);
		PyErr_SetString(PyExc_ValueError, buffer);
		goto error;
	}
	else if (end != last) {
		PyErr_SetString(PyExc_ValueError,
				"null byte in argument for float()");
		goto error;
	}
	if (x == 0.0) {
		/* See above -- may have been strtod being anal
		   about denorms. */
		PyFPE_START_PROTECT("atof", goto error)
		x = PyOS_ascii_atof(s);
		PyFPE_END_PROTECT(x)
		errno = 0;    /* whether atof ever set errno is undefined */
	}
	result = PyFloat_FromDouble(x);
  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;
}

/* Methods */

static void
format_double(char *buf, size_t buflen, double ob_fval, int precision)
{
	register char *cp;
	char format[32];
	int i;

	/* Subroutine for float_repr, float_str and float_print.
	   We want float numbers to be recognizable as such,
	   i.e., they should contain a decimal point or an exponent.
	   However, %g may print the number as an integer;
	   in such cases, we append ".0" to the string. */

	PyOS_snprintf(format, 32, "%%.%ig", precision);
	PyOS_ascii_formatd(buf, buflen, format, ob_fval);
	cp = buf;
	if (*cp == '-')
		cp++;
	for (; *cp != '\0'; cp++) {
		/* Any non-digit means it's not an integer;
		   this takes care of NAN and INF as well. */
		if (!isdigit(Py_CHARMASK(*cp)))
			break;
	}
	if (*cp == '\0') {
		*cp++ = '.';
		*cp++ = '0';
		*cp++ = '\0';
		return;
	}
	/* Checking the next three chars should be more than enough to
	 * detect inf or nan, even on Windows. We check for inf or nan
	 * at last because they are rare cases.
	 */
	for (i=0; *cp != '\0' && i<3; cp++, i++) {
		if (isdigit(Py_CHARMASK(*cp)) || *cp == '.')
			continue;
		/* found something that is neither a digit nor point
		 * it might be a NaN or INF
		 */
#ifdef Py_NAN
		if (Py_IS_NAN(ob_fval)) {
			strcpy(buf, "nan");
		}
                else
#endif
		if (Py_IS_INFINITY(ob_fval)) {
			cp = buf;
			if (*cp == '-')
				cp++;
			strcpy(cp, "inf");
		}
		break;
	}

}

static void
format_float(char *buf, size_t buflen, PyFloatObject *v, int precision)
{
	assert(PyFloat_Check(v));
	format_double(buf, buflen, PyFloat_AS_DOUBLE(v), precision);
}

/* 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;

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;
}

/* Precisions used by repr() and str(), respectively.

   The repr() precision (17 significant decimal digits) is the minimal number
   that is guaranteed to have enough precision so that if the number is read
   back in the exact same binary value is recreated.  This is true for IEEE
   floating point by design, and also happens to work for all other modern
   hardware.

   The str() precision is chosen so that in most cases, the rounding noise
   created by various operations is suppressed, while giving plenty of
   precision for practical use.

*/

#define PREC_REPR	17
#define PREC_STR	12

static PyObject *
float_repr(PyFloatObject *v)
{
	char buf[100];
	format_float(buf, sizeof(buf), v, PREC_REPR);

	return PyUnicode_FromString(buf);
}

static PyObject *
float_str(PyFloatObject *v)
{
	char buf[100];
	format_float(buf, sizeof(buf), v, PREC_STR);
	return PyUnicode_FromString(buf);
}

/* 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);
}

static PyObject *
float_round(PyObject *v, PyObject *args)
{
#define UNDEF_NDIGITS (-0x7fffffff) /* Unlikely ndigits value */
	double x;
	double f = 1.0;
	double flr, cil;
	double rounded;
	int ndigits = UNDEF_NDIGITS;

	if (!PyArg_ParseTuple(args, "|i", &ndigits))
		return NULL;

	x = PyFloat_AsDouble(v);

	if (ndigits != UNDEF_NDIGITS) {
		f = pow(10.0, ndigits);
		x *= f;
	}

	flr = floor(x);
	cil = ceil(x);

	if (x-flr > 0.5)
		rounded = cil;
	else if (x-flr == 0.5)
		rounded = fmod(flr, 2) == 0 ? flr : cil;
	else
		rounded = flr;

	if (ndigits != UNDEF_NDIGITS) {
		rounded /= f;
		return PyFloat_FromDouble(rounded);
	}

	return PyLong_FromDouble(rounded);
#undef UNDEF_NDIGITS
}

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;
	assert(isxdigit(c));
	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, sign=1;
	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 and optional sign */
	while (isspace(*s))
		s++;
	if (*s == '-') {
		s++;
		sign = -1;
	}
	else if (*s == '+')
		s++;

	/* infinities and nans */
	if (PyOS_mystrnicmp(s, "nan", 4) == 0) {
		x = Py_NAN;
		goto finished;
	}
	if (PyOS_mystrnicmp(s, "inf", 4) == 0 ||
	    PyOS_mystrnicmp(s, "infinity", 9) == 0) {
		x = sign*Py_HUGE_VAL;
		goto finished;
	}

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

	/* coefficient: <integer> [. <fraction>] */
	coeff_start = s;
	while (isxdigit(*s))
		s++;
	s_store = s;
	if (*s == '.') {
		s++;
		while (isxdigit(*s))
			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 (tolower(*s) == (int)'p') {
		s++;
		exp_start = s;
		if (*s == '-' || *s == '+')
			s++;
		if (!isdigit(*s))
			goto parse_error;
		s++;
		while (isdigit(*s))
			s++;
		exp = strtol(exp_start, NULL, 10);
	}
	else
		exp = 0;

	/* optional trailing whitespace leading to the end of the string */
	while (isspace(*s))
		s++;
	if (s != s_end)
		goto parse_error;

/* 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 = sign * 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 = sign * 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 = sign * 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 = sign * ldexp(x, (int)(exp+4*key_digit));

  finished:
	result_as_float = Py_BuildValue("(d)", 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;
	}

	/* Returns ints instead of longs where possible */
	INPLACE_UPDATE(numerator, PyNumber_Int(numerator));
	if (numerator == NULL) goto error;
	INPLACE_UPDATE(denominator, PyNumber_Int(denominator));
	if (denominator == NULL) goto error;

	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 (PyUnicode_Check(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*/
	float_trunc,	/*nb_long*/
	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_compare */
	(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 ints 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[100];
					format_float(buf, sizeof(buf), p, PREC_STR);
					/* 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);
				}
			}
			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;
	}
}

/* Should only be used by marshal. */
int
_PyFloat_Repr(double x, char *p, size_t len)
{
	format_double(p, len, x, PREC_REPR);
	return (int)strlen(p);
}

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;
	}
}
