| Guido van Rossum | f70e43a | 1991-02-19 12:39:46 +0000 | [diff] [blame] | 1 |  | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 2 | /* Float object implementation */ | 
 | 3 |  | 
| Guido van Rossum | 2a9096b | 1990-10-21 22:15:08 +0000 | [diff] [blame] | 4 | /* XXX There should be overflow checks here, but it's hard to check | 
 | 5 |    for any kind of float exception without losing portability. */ | 
 | 6 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 7 | #include "Python.h" | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 8 |  | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 9 | #include <ctype.h> | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 10 |  | 
| Jack Jansen | eddc144 | 2003-11-20 01:44:59 +0000 | [diff] [blame] | 11 | #if !defined(__STDC__) | 
| Tim Peters | dbd9ba6 | 2000-07-09 03:09:57 +0000 | [diff] [blame] | 12 | extern double fmod(double, double); | 
 | 13 | extern double pow(double, double); | 
| Guido van Rossum | 6923e13 | 1990-11-02 17:50:43 +0000 | [diff] [blame] | 14 | #endif | 
 | 15 |  | 
| Guido van Rossum | 93ad0df | 1997-05-13 21:00:42 +0000 | [diff] [blame] | 16 | /* Special free list -- see comments for same code in intobject.c. */ | 
| Guido van Rossum | 93ad0df | 1997-05-13 21:00:42 +0000 | [diff] [blame] | 17 | #define BLOCK_SIZE	1000	/* 1K less typical malloc overhead */ | 
| Guido van Rossum | 3fce883 | 1999-03-12 19:43:17 +0000 | [diff] [blame] | 18 | #define BHEAD_SIZE	8	/* Enough for a 64-bit pointer */ | 
| Guido van Rossum | f61bbc8 | 1999-03-12 00:12:21 +0000 | [diff] [blame] | 19 | #define N_FLOATOBJECTS	((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyFloatObject)) | 
| Guido van Rossum | 3fce883 | 1999-03-12 19:43:17 +0000 | [diff] [blame] | 20 |  | 
| Guido van Rossum | 3fce883 | 1999-03-12 19:43:17 +0000 | [diff] [blame] | 21 | struct _floatblock { | 
 | 22 | 	struct _floatblock *next; | 
 | 23 | 	PyFloatObject objects[N_FLOATOBJECTS]; | 
 | 24 | }; | 
 | 25 |  | 
 | 26 | typedef struct _floatblock PyFloatBlock; | 
 | 27 |  | 
 | 28 | static PyFloatBlock *block_list = NULL; | 
 | 29 | static PyFloatObject *free_list = NULL; | 
 | 30 |  | 
| Guido van Rossum | 93ad0df | 1997-05-13 21:00:42 +0000 | [diff] [blame] | 31 | static PyFloatObject * | 
| Fred Drake | fd99de6 | 2000-07-09 05:02:18 +0000 | [diff] [blame] | 32 | fill_free_list(void) | 
| Guido van Rossum | 93ad0df | 1997-05-13 21:00:42 +0000 | [diff] [blame] | 33 | { | 
 | 34 | 	PyFloatObject *p, *q; | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 35 | 	/* XXX Float blocks escape the object heap. Use PyObject_MALLOC ??? */ | 
 | 36 | 	p = (PyFloatObject *) PyMem_MALLOC(sizeof(PyFloatBlock)); | 
| Guido van Rossum | 93ad0df | 1997-05-13 21:00:42 +0000 | [diff] [blame] | 37 | 	if (p == NULL) | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 38 | 		return (PyFloatObject *) PyErr_NoMemory(); | 
| Guido van Rossum | 3fce883 | 1999-03-12 19:43:17 +0000 | [diff] [blame] | 39 | 	((PyFloatBlock *)p)->next = block_list; | 
 | 40 | 	block_list = (PyFloatBlock *)p; | 
 | 41 | 	p = &((PyFloatBlock *)p)->objects[0]; | 
| Guido van Rossum | 93ad0df | 1997-05-13 21:00:42 +0000 | [diff] [blame] | 42 | 	q = p + N_FLOATOBJECTS; | 
 | 43 | 	while (--q > p) | 
| Guido van Rossum | f61bbc8 | 1999-03-12 00:12:21 +0000 | [diff] [blame] | 44 | 		q->ob_type = (struct _typeobject *)(q-1); | 
 | 45 | 	q->ob_type = NULL; | 
| Guido van Rossum | 93ad0df | 1997-05-13 21:00:42 +0000 | [diff] [blame] | 46 | 	return p + N_FLOATOBJECTS - 1; | 
 | 47 | } | 
 | 48 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 49 | PyObject * | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 50 | PyFloat_FromDouble(double fval) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 51 | { | 
| Guido van Rossum | 93ad0df | 1997-05-13 21:00:42 +0000 | [diff] [blame] | 52 | 	register PyFloatObject *op; | 
 | 53 | 	if (free_list == NULL) { | 
 | 54 | 		if ((free_list = fill_free_list()) == NULL) | 
 | 55 | 			return NULL; | 
 | 56 | 	} | 
| Guido van Rossum | e3a8e7e | 2002-08-19 19:26:42 +0000 | [diff] [blame] | 57 | 	/* Inline PyObject_New */ | 
| Guido van Rossum | 93ad0df | 1997-05-13 21:00:42 +0000 | [diff] [blame] | 58 | 	op = free_list; | 
| Guido van Rossum | f61bbc8 | 1999-03-12 00:12:21 +0000 | [diff] [blame] | 59 | 	free_list = (PyFloatObject *)op->ob_type; | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 60 | 	PyObject_INIT(op, &PyFloat_Type); | 
| Guido van Rossum | 2a9096b | 1990-10-21 22:15:08 +0000 | [diff] [blame] | 61 | 	op->ob_fval = fval; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 62 | 	return (PyObject *) op; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 63 | } | 
 | 64 |  | 
| Tim Peters | ef14d73 | 2000-09-23 03:39:17 +0000 | [diff] [blame] | 65 | /************************************************************************** | 
 | 66 | RED_FLAG 22-Sep-2000 tim | 
 | 67 | PyFloat_FromString's pend argument is braindead.  Prior to this RED_FLAG, | 
 | 68 |  | 
 | 69 | 1.  If v was a regular string, *pend was set to point to its terminating | 
 | 70 |     null byte.  That's useless (the caller can find that without any | 
 | 71 |     help from this function!). | 
 | 72 |  | 
 | 73 | 2.  If v was a Unicode string, or an object convertible to a character | 
 | 74 |     buffer, *pend was set to point into stack trash (the auto temp | 
 | 75 |     vector holding the character buffer).  That was downright dangerous. | 
 | 76 |  | 
 | 77 | Since we can't change the interface of a public API function, pend is | 
 | 78 | still supported but now *officially* useless:  if pend is not NULL, | 
 | 79 | *pend is set to NULL. | 
 | 80 | **************************************************************************/ | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 81 | PyObject * | 
| Fred Drake | fd99de6 | 2000-07-09 05:02:18 +0000 | [diff] [blame] | 82 | PyFloat_FromString(PyObject *v, char **pend) | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 83 | { | 
| Guido van Rossum | 4c08d55 | 2000-03-10 22:55:18 +0000 | [diff] [blame] | 84 | 	const char *s, *last, *end; | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 85 | 	double x; | 
| Tim Peters | ef14d73 | 2000-09-23 03:39:17 +0000 | [diff] [blame] | 86 | 	char buffer[256]; /* for errors */ | 
| Martin v. Löwis | 339d0f7 | 2001-08-17 18:39:25 +0000 | [diff] [blame] | 87 | #ifdef Py_USING_UNICODE | 
| Tim Peters | ef14d73 | 2000-09-23 03:39:17 +0000 | [diff] [blame] | 88 | 	char s_buffer[256]; /* for objects convertible to a char buffer */ | 
| Martin v. Löwis | 339d0f7 | 2001-08-17 18:39:25 +0000 | [diff] [blame] | 89 | #endif | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 90 | 	Py_ssize_t len; | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 91 |  | 
| Tim Peters | ef14d73 | 2000-09-23 03:39:17 +0000 | [diff] [blame] | 92 | 	if (pend) | 
 | 93 | 		*pend = NULL; | 
| Guido van Rossum | 4c08d55 | 2000-03-10 22:55:18 +0000 | [diff] [blame] | 94 | 	if (PyString_Check(v)) { | 
 | 95 | 		s = PyString_AS_STRING(v); | 
 | 96 | 		len = PyString_GET_SIZE(v); | 
 | 97 | 	} | 
| Martin v. Löwis | 339d0f7 | 2001-08-17 18:39:25 +0000 | [diff] [blame] | 98 | #ifdef Py_USING_UNICODE | 
| Guido van Rossum | 9e896b3 | 2000-04-05 20:11:21 +0000 | [diff] [blame] | 99 | 	else if (PyUnicode_Check(v)) { | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 100 | 		if (PyUnicode_GET_SIZE(v) >= (Py_ssize_t)sizeof(s_buffer)) { | 
| Guido van Rossum | 9e896b3 | 2000-04-05 20:11:21 +0000 | [diff] [blame] | 101 | 			PyErr_SetString(PyExc_ValueError, | 
| Tim Peters | ef14d73 | 2000-09-23 03:39:17 +0000 | [diff] [blame] | 102 | 				"Unicode float() literal too long to convert"); | 
| Guido van Rossum | 9e896b3 | 2000-04-05 20:11:21 +0000 | [diff] [blame] | 103 | 			return NULL; | 
 | 104 | 		} | 
| Tim Peters | ef14d73 | 2000-09-23 03:39:17 +0000 | [diff] [blame] | 105 | 		if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), | 
| Guido van Rossum | 9e896b3 | 2000-04-05 20:11:21 +0000 | [diff] [blame] | 106 | 					    PyUnicode_GET_SIZE(v), | 
| Tim Peters | d2364e8 | 2001-11-01 20:09:42 +0000 | [diff] [blame] | 107 | 					    s_buffer, | 
| Guido van Rossum | 9e896b3 | 2000-04-05 20:11:21 +0000 | [diff] [blame] | 108 | 					    NULL)) | 
 | 109 | 			return NULL; | 
 | 110 | 		s = s_buffer; | 
| Martin v. Löwis | 18e1655 | 2006-02-15 17:27:45 +0000 | [diff] [blame] | 111 | 		len = strlen(s); | 
| Guido van Rossum | 9e896b3 | 2000-04-05 20:11:21 +0000 | [diff] [blame] | 112 | 	} | 
| Martin v. Löwis | 339d0f7 | 2001-08-17 18:39:25 +0000 | [diff] [blame] | 113 | #endif | 
| Guido van Rossum | 4c08d55 | 2000-03-10 22:55:18 +0000 | [diff] [blame] | 114 | 	else if (PyObject_AsCharBuffer(v, &s, &len)) { | 
 | 115 | 		PyErr_SetString(PyExc_TypeError, | 
| Skip Montanaro | 71390a9 | 2002-05-02 13:03:22 +0000 | [diff] [blame] | 116 | 				"float() argument must be a string or a number"); | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 117 | 		return NULL; | 
| Guido van Rossum | 4c08d55 | 2000-03-10 22:55:18 +0000 | [diff] [blame] | 118 | 	} | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 119 |  | 
| Guido van Rossum | 4c08d55 | 2000-03-10 22:55:18 +0000 | [diff] [blame] | 120 | 	last = s + len; | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 121 | 	while (*s && isspace(Py_CHARMASK(*s))) | 
 | 122 | 		s++; | 
| Tim Peters | ef14d73 | 2000-09-23 03:39:17 +0000 | [diff] [blame] | 123 | 	if (*s == '\0') { | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 124 | 		PyErr_SetString(PyExc_ValueError, "empty string for float()"); | 
 | 125 | 		return NULL; | 
 | 126 | 	} | 
| Tim Peters | ef14d73 | 2000-09-23 03:39:17 +0000 | [diff] [blame] | 127 | 	/* We don't care about overflow or underflow.  If the platform supports | 
 | 128 | 	 * them, infinities and signed zeroes (on underflow) are fine. | 
 | 129 | 	 * However, strtod can return 0 for denormalized numbers, where atof | 
 | 130 | 	 * does not.  So (alas!) we special-case a zero result.  Note that | 
 | 131 | 	 * whether strtod sets errno on underflow is not defined, so we can't | 
 | 132 | 	 * key off errno. | 
 | 133 |          */ | 
| Tim Peters | 858346e | 2000-09-25 21:01:28 +0000 | [diff] [blame] | 134 | 	PyFPE_START_PROTECT("strtod", return NULL) | 
| Martin v. Löwis | 737ea82 | 2004-06-08 18:52:54 +0000 | [diff] [blame] | 135 | 	x = PyOS_ascii_strtod(s, (char **)&end); | 
| Tim Peters | 858346e | 2000-09-25 21:01:28 +0000 | [diff] [blame] | 136 | 	PyFPE_END_PROTECT(x) | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 137 | 	errno = 0; | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 138 | 	/* Believe it or not, Solaris 2.6 can move end *beyond* the null | 
| Tim Peters | ef14d73 | 2000-09-23 03:39:17 +0000 | [diff] [blame] | 139 | 	   byte at the end of the string, when the input is inf(inity). */ | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 140 | 	if (end > last) | 
 | 141 | 		end = last; | 
| Tim Peters | ef14d73 | 2000-09-23 03:39:17 +0000 | [diff] [blame] | 142 | 	if (end == s) { | 
| Barry Warsaw | af8aef9 | 2001-11-28 20:52:21 +0000 | [diff] [blame] | 143 | 		PyOS_snprintf(buffer, sizeof(buffer), | 
 | 144 | 			      "invalid literal for float(): %.200s", s); | 
| Tim Peters | ef14d73 | 2000-09-23 03:39:17 +0000 | [diff] [blame] | 145 | 		PyErr_SetString(PyExc_ValueError, buffer); | 
 | 146 | 		return NULL; | 
 | 147 | 	} | 
 | 148 | 	/* Since end != s, the platform made *some* kind of sense out | 
 | 149 | 	   of the input.  Trust it. */ | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 150 | 	while (*end && isspace(Py_CHARMASK(*end))) | 
 | 151 | 		end++; | 
 | 152 | 	if (*end != '\0') { | 
| Barry Warsaw | af8aef9 | 2001-11-28 20:52:21 +0000 | [diff] [blame] | 153 | 		PyOS_snprintf(buffer, sizeof(buffer), | 
 | 154 | 			      "invalid literal for float(): %.200s", s); | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 155 | 		PyErr_SetString(PyExc_ValueError, buffer); | 
 | 156 | 		return NULL; | 
 | 157 | 	} | 
| Guido van Rossum | 4c08d55 | 2000-03-10 22:55:18 +0000 | [diff] [blame] | 158 | 	else if (end != last) { | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 159 | 		PyErr_SetString(PyExc_ValueError, | 
 | 160 | 				"null byte in argument for float()"); | 
 | 161 | 		return NULL; | 
 | 162 | 	} | 
| Tim Peters | ef14d73 | 2000-09-23 03:39:17 +0000 | [diff] [blame] | 163 | 	if (x == 0.0) { | 
 | 164 | 		/* See above -- may have been strtod being anal | 
 | 165 | 		   about denorms. */ | 
| Tim Peters | 858346e | 2000-09-25 21:01:28 +0000 | [diff] [blame] | 166 | 		PyFPE_START_PROTECT("atof", return NULL) | 
| Martin v. Löwis | 737ea82 | 2004-06-08 18:52:54 +0000 | [diff] [blame] | 167 | 		x = PyOS_ascii_atof(s); | 
| Tim Peters | 858346e | 2000-09-25 21:01:28 +0000 | [diff] [blame] | 168 | 		PyFPE_END_PROTECT(x) | 
| Tim Peters | ef14d73 | 2000-09-23 03:39:17 +0000 | [diff] [blame] | 169 | 		errno = 0;    /* whether atof ever set errno is undefined */ | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 170 | 	} | 
| Barry Warsaw | 226ae6c | 1999-10-12 19:54:53 +0000 | [diff] [blame] | 171 | 	return PyFloat_FromDouble(x); | 
 | 172 | } | 
 | 173 |  | 
| Guido van Rossum | 234f942 | 1993-06-17 12:35:49 +0000 | [diff] [blame] | 174 | static void | 
| Fred Drake | fd99de6 | 2000-07-09 05:02:18 +0000 | [diff] [blame] | 175 | float_dealloc(PyFloatObject *op) | 
| Guido van Rossum | 3132a5a | 1992-03-27 17:28:44 +0000 | [diff] [blame] | 176 | { | 
| Guido van Rossum | 9475a23 | 2001-10-05 20:51:39 +0000 | [diff] [blame] | 177 | 	if (PyFloat_CheckExact(op)) { | 
 | 178 | 		op->ob_type = (struct _typeobject *)free_list; | 
 | 179 | 		free_list = op; | 
 | 180 | 	} | 
 | 181 | 	else | 
 | 182 | 		op->ob_type->tp_free((PyObject *)op); | 
| Guido van Rossum | 3132a5a | 1992-03-27 17:28:44 +0000 | [diff] [blame] | 183 | } | 
 | 184 |  | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 185 | double | 
| Fred Drake | fd99de6 | 2000-07-09 05:02:18 +0000 | [diff] [blame] | 186 | PyFloat_AsDouble(PyObject *op) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 187 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 188 | 	PyNumberMethods *nb; | 
 | 189 | 	PyFloatObject *fo; | 
| Guido van Rossum | b6775db | 1994-08-01 11:34:53 +0000 | [diff] [blame] | 190 | 	double val; | 
| Tim Peters | d2364e8 | 2001-11-01 20:09:42 +0000 | [diff] [blame] | 191 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 192 | 	if (op && PyFloat_Check(op)) | 
 | 193 | 		return PyFloat_AS_DOUBLE((PyFloatObject*) op); | 
| Tim Peters | d2364e8 | 2001-11-01 20:09:42 +0000 | [diff] [blame] | 194 |  | 
| Neil Schemenauer | 2c77e90 | 2002-11-18 16:06:21 +0000 | [diff] [blame] | 195 | 	if (op == NULL) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 196 | 		PyErr_BadArgument(); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 197 | 		return -1; | 
 | 198 | 	} | 
| Tim Peters | d2364e8 | 2001-11-01 20:09:42 +0000 | [diff] [blame] | 199 |  | 
| Neil Schemenauer | 2c77e90 | 2002-11-18 16:06:21 +0000 | [diff] [blame] | 200 | 	if ((nb = op->ob_type->tp_as_number) == NULL || nb->nb_float == NULL) { | 
 | 201 | 		PyErr_SetString(PyExc_TypeError, "a float is required"); | 
 | 202 | 		return -1; | 
 | 203 | 	} | 
 | 204 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 205 | 	fo = (PyFloatObject*) (*nb->nb_float) (op); | 
| Guido van Rossum | b6775db | 1994-08-01 11:34:53 +0000 | [diff] [blame] | 206 | 	if (fo == NULL) | 
 | 207 | 		return -1; | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 208 | 	if (!PyFloat_Check(fo)) { | 
 | 209 | 		PyErr_SetString(PyExc_TypeError, | 
 | 210 | 				"nb_float should return float object"); | 
| Guido van Rossum | b6775db | 1994-08-01 11:34:53 +0000 | [diff] [blame] | 211 | 		return -1; | 
 | 212 | 	} | 
| Tim Peters | d2364e8 | 2001-11-01 20:09:42 +0000 | [diff] [blame] | 213 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 214 | 	val = PyFloat_AS_DOUBLE(fo); | 
 | 215 | 	Py_DECREF(fo); | 
| Tim Peters | d2364e8 | 2001-11-01 20:09:42 +0000 | [diff] [blame] | 216 |  | 
| Guido van Rossum | b6775db | 1994-08-01 11:34:53 +0000 | [diff] [blame] | 217 | 	return val; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 218 | } | 
 | 219 |  | 
 | 220 | /* Methods */ | 
 | 221 |  | 
| Tim Peters | 97019e4 | 2001-11-28 22:43:45 +0000 | [diff] [blame] | 222 | static void | 
| Neal Norwitz | 545686b | 2006-12-28 04:45:06 +0000 | [diff] [blame] | 223 | format_double(char *buf, size_t buflen, double ob_fval, int precision) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 224 | { | 
 | 225 | 	register char *cp; | 
| Martin v. Löwis | 737ea82 | 2004-06-08 18:52:54 +0000 | [diff] [blame] | 226 | 	char format[32]; | 
| Neal Norwitz | 545686b | 2006-12-28 04:45:06 +0000 | [diff] [blame] | 227 | 	/* Subroutine for float_repr, float_str, float_print and others. | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 228 | 	   We want float numbers to be recognizable as such, | 
 | 229 | 	   i.e., they should contain a decimal point or an exponent. | 
 | 230 | 	   However, %g may print the number as an integer; | 
 | 231 | 	   in such cases, we append ".0" to the string. */ | 
| Tim Peters | 97019e4 | 2001-11-28 22:43:45 +0000 | [diff] [blame] | 232 |  | 
| Martin v. Löwis | 737ea82 | 2004-06-08 18:52:54 +0000 | [diff] [blame] | 233 | 	PyOS_snprintf(format, 32, "%%.%ig", precision); | 
| Neal Norwitz | 545686b | 2006-12-28 04:45:06 +0000 | [diff] [blame] | 234 | 	PyOS_ascii_formatd(buf, buflen, format, ob_fval); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 235 | 	cp = buf; | 
 | 236 | 	if (*cp == '-') | 
 | 237 | 		cp++; | 
 | 238 | 	for (; *cp != '\0'; cp++) { | 
 | 239 | 		/* Any non-digit means it's not an integer; | 
 | 240 | 		   this takes care of NAN and INF as well. */ | 
| Guido van Rossum | 9fa2c11 | 1995-02-10 17:00:37 +0000 | [diff] [blame] | 241 | 		if (!isdigit(Py_CHARMASK(*cp))) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 242 | 			break; | 
 | 243 | 	} | 
 | 244 | 	if (*cp == '\0') { | 
 | 245 | 		*cp++ = '.'; | 
 | 246 | 		*cp++ = '0'; | 
 | 247 | 		*cp++ = '\0'; | 
 | 248 | 	} | 
 | 249 | } | 
 | 250 |  | 
| Neal Norwitz | 545686b | 2006-12-28 04:45:06 +0000 | [diff] [blame] | 251 | static void | 
 | 252 | format_float(char *buf, size_t buflen, PyFloatObject *v, int precision) | 
| Tim Peters | 97019e4 | 2001-11-28 22:43:45 +0000 | [diff] [blame] | 253 | { | 
| Neal Norwitz | 545686b | 2006-12-28 04:45:06 +0000 | [diff] [blame] | 254 | 	assert(PyFloat_Check(v)); | 
 | 255 | 	format_double(buf, buflen, PyFloat_AS_DOUBLE(v), precision); | 
| Tim Peters | 97019e4 | 2001-11-28 22:43:45 +0000 | [diff] [blame] | 256 | } | 
 | 257 |  | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 258 | /* Macro and helper that convert PyObject obj to a C double and store | 
 | 259 |    the value in dbl; this replaces the functionality of the coercion | 
| Tim Peters | 77d8a4f | 2001-12-11 20:31:34 +0000 | [diff] [blame] | 260 |    slot function.  If conversion to double raises an exception, obj is | 
 | 261 |    set to NULL, and the function invoking this macro returns NULL.  If | 
 | 262 |    obj is not of float, int or long type, Py_NotImplemented is incref'ed, | 
 | 263 |    stored in obj, and returned from the function invoking this macro. | 
 | 264 | */ | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 265 | #define CONVERT_TO_DOUBLE(obj, dbl)			\ | 
 | 266 | 	if (PyFloat_Check(obj))				\ | 
 | 267 | 		dbl = PyFloat_AS_DOUBLE(obj);		\ | 
 | 268 | 	else if (convert_to_double(&(obj), &(dbl)) < 0)	\ | 
 | 269 | 		return obj; | 
 | 270 |  | 
 | 271 | static int | 
| Tim Peters | 9fffa3e | 2001-09-04 05:14:19 +0000 | [diff] [blame] | 272 | convert_to_double(PyObject **v, double *dbl) | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 273 | { | 
 | 274 | 	register PyObject *obj = *v; | 
| Tim Peters | 9fffa3e | 2001-09-04 05:14:19 +0000 | [diff] [blame] | 275 |  | 
| Guido van Rossum | ddefaf3 | 2007-01-14 03:31:43 +0000 | [diff] [blame] | 276 | 	if (PyLong_Check(obj)) { | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 277 | 		*dbl = PyLong_AsDouble(obj); | 
| Tim Peters | 9fffa3e | 2001-09-04 05:14:19 +0000 | [diff] [blame] | 278 | 		if (*dbl == -1.0 && PyErr_Occurred()) { | 
 | 279 | 			*v = NULL; | 
 | 280 | 			return -1; | 
 | 281 | 		} | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 282 | 	} | 
 | 283 | 	else { | 
 | 284 | 		Py_INCREF(Py_NotImplemented); | 
 | 285 | 		*v = Py_NotImplemented; | 
 | 286 | 		return -1; | 
 | 287 | 	} | 
 | 288 | 	return 0; | 
 | 289 | } | 
 | 290 |  | 
| Guido van Rossum | 57072eb | 1999-12-23 19:00:28 +0000 | [diff] [blame] | 291 | /* Precisions used by repr() and str(), respectively. | 
 | 292 |  | 
 | 293 |    The repr() precision (17 significant decimal digits) is the minimal number | 
 | 294 |    that is guaranteed to have enough precision so that if the number is read | 
 | 295 |    back in the exact same binary value is recreated.  This is true for IEEE | 
 | 296 |    floating point by design, and also happens to work for all other modern | 
 | 297 |    hardware. | 
 | 298 |  | 
 | 299 |    The str() precision is chosen so that in most cases, the rounding noise | 
 | 300 |    created by various operations is suppressed, while giving plenty of | 
 | 301 |    precision for practical use. | 
 | 302 |  | 
 | 303 | */ | 
 | 304 |  | 
 | 305 | #define PREC_REPR	17 | 
 | 306 | #define PREC_STR	12 | 
 | 307 |  | 
| Guido van Rossum | 3132a5a | 1992-03-27 17:28:44 +0000 | [diff] [blame] | 308 | /* ARGSUSED */ | 
| Guido van Rossum | 9093361 | 1991-06-07 16:10:43 +0000 | [diff] [blame] | 309 | static int | 
| Fred Drake | fd99de6 | 2000-07-09 05:02:18 +0000 | [diff] [blame] | 310 | float_print(PyFloatObject *v, FILE *fp, int flags) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 311 | { | 
 | 312 | 	char buf[100]; | 
| Tim Peters | 97019e4 | 2001-11-28 22:43:45 +0000 | [diff] [blame] | 313 | 	format_float(buf, sizeof(buf), v, | 
 | 314 | 		     (flags & Py_PRINT_RAW) ? PREC_STR : PREC_REPR); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 315 | 	fputs(buf, fp); | 
| Guido van Rossum | 9093361 | 1991-06-07 16:10:43 +0000 | [diff] [blame] | 316 | 	return 0; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 317 | } | 
 | 318 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 319 | static PyObject * | 
| Fred Drake | fd99de6 | 2000-07-09 05:02:18 +0000 | [diff] [blame] | 320 | float_repr(PyFloatObject *v) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 321 | { | 
 | 322 | 	char buf[100]; | 
| Tim Peters | 97019e4 | 2001-11-28 22:43:45 +0000 | [diff] [blame] | 323 | 	format_float(buf, sizeof(buf), v, PREC_REPR); | 
| Guido van Rossum | 57072eb | 1999-12-23 19:00:28 +0000 | [diff] [blame] | 324 | 	return PyString_FromString(buf); | 
 | 325 | } | 
 | 326 |  | 
 | 327 | static PyObject * | 
| Fred Drake | fd99de6 | 2000-07-09 05:02:18 +0000 | [diff] [blame] | 328 | float_str(PyFloatObject *v) | 
| Guido van Rossum | 57072eb | 1999-12-23 19:00:28 +0000 | [diff] [blame] | 329 | { | 
 | 330 | 	char buf[100]; | 
| Tim Peters | 97019e4 | 2001-11-28 22:43:45 +0000 | [diff] [blame] | 331 | 	format_float(buf, sizeof(buf), v, PREC_STR); | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 332 | 	return PyString_FromString(buf); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 333 | } | 
 | 334 |  | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 335 | /* Comparison is pretty much a nightmare.  When comparing float to float, | 
 | 336 |  * we do it as straightforwardly (and long-windedly) as conceivable, so | 
 | 337 |  * that, e.g., Python x == y delivers the same result as the platform | 
 | 338 |  * C x == y when x and/or y is a NaN. | 
 | 339 |  * When mixing float with an integer type, there's no good *uniform* approach. | 
 | 340 |  * Converting the double to an integer obviously doesn't work, since we | 
 | 341 |  * may lose info from fractional bits.  Converting the integer to a double | 
 | 342 |  * also has two failure modes:  (1) a long int may trigger overflow (too | 
 | 343 |  * large to fit in the dynamic range of a C double); (2) even a C long may have | 
 | 344 |  * more bits than fit in a C double (e.g., on a a 64-bit box long may have | 
 | 345 |  * 63 bits of precision, but a C double probably has only 53), and then | 
 | 346 |  * we can falsely claim equality when low-order integer bits are lost by | 
 | 347 |  * coercion to double.  So this part is painful too. | 
 | 348 |  */ | 
 | 349 |  | 
| Michael W. Hudson | d3b33b5 | 2004-02-19 19:35:22 +0000 | [diff] [blame] | 350 | static PyObject* | 
 | 351 | float_richcompare(PyObject *v, PyObject *w, int op) | 
 | 352 | { | 
 | 353 | 	double i, j; | 
 | 354 | 	int r = 0; | 
 | 355 |  | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 356 | 	assert(PyFloat_Check(v)); | 
 | 357 | 	i = PyFloat_AS_DOUBLE(v); | 
| Michael W. Hudson | d3b33b5 | 2004-02-19 19:35:22 +0000 | [diff] [blame] | 358 |  | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 359 | 	/* Switch on the type of w.  Set i and j to doubles to be compared, | 
 | 360 | 	 * and op to the richcomp to use. | 
 | 361 | 	 */ | 
 | 362 | 	if (PyFloat_Check(w)) | 
 | 363 | 		j = PyFloat_AS_DOUBLE(w); | 
 | 364 |  | 
| Thomas Wouters | 477c8d5 | 2006-05-27 19:21:47 +0000 | [diff] [blame] | 365 | 	else if (!Py_IS_FINITE(i)) { | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 366 | 		if (PyInt_Check(w) || PyLong_Check(w)) | 
| Tim Peters | e1c69b3 | 2004-09-23 19:22:41 +0000 | [diff] [blame] | 367 | 			/* If i is an infinity, its magnitude exceeds any | 
 | 368 | 			 * finite integer, so it doesn't matter which int we | 
 | 369 | 			 * compare i with.  If i is a NaN, similarly. | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 370 | 			 */ | 
 | 371 | 			j = 0.0; | 
 | 372 | 		else | 
 | 373 | 			goto Unimplemented; | 
 | 374 | 	} | 
 | 375 |  | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 376 | 	else if (PyLong_Check(w)) { | 
 | 377 | 		int vsign = i == 0.0 ? 0 : i < 0.0 ? -1 : 1; | 
 | 378 | 		int wsign = _PyLong_Sign(w); | 
 | 379 | 		size_t nbits; | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 380 | 		int exponent; | 
 | 381 |  | 
 | 382 | 		if (vsign != wsign) { | 
 | 383 | 			/* Magnitudes are irrelevant -- the signs alone | 
 | 384 | 			 * determine the outcome. | 
 | 385 | 			 */ | 
 | 386 | 			i = (double)vsign; | 
 | 387 | 			j = (double)wsign; | 
 | 388 | 			goto Compare; | 
 | 389 | 		} | 
 | 390 | 		/* The signs are the same. */ | 
 | 391 | 		/* Convert w to a double if it fits.  In particular, 0 fits. */ | 
 | 392 | 		nbits = _PyLong_NumBits(w); | 
 | 393 | 		if (nbits == (size_t)-1 && PyErr_Occurred()) { | 
 | 394 | 			/* This long is so large that size_t isn't big enough | 
| Tim Peters | e1c69b3 | 2004-09-23 19:22:41 +0000 | [diff] [blame] | 395 | 			 * to hold the # of bits.  Replace with little doubles | 
 | 396 | 			 * that give the same outcome -- w is so large that | 
 | 397 | 			 * its magnitude must exceed the magnitude of any | 
 | 398 | 			 * finite float. | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 399 | 			 */ | 
 | 400 | 			PyErr_Clear(); | 
 | 401 | 			i = (double)vsign; | 
 | 402 | 			assert(wsign != 0); | 
 | 403 | 			j = wsign * 2.0; | 
 | 404 | 			goto Compare; | 
 | 405 | 		} | 
 | 406 | 		if (nbits <= 48) { | 
 | 407 | 			j = PyLong_AsDouble(w); | 
 | 408 | 			/* It's impossible that <= 48 bits overflowed. */ | 
 | 409 | 			assert(j != -1.0 || ! PyErr_Occurred()); | 
 | 410 | 			goto Compare; | 
 | 411 | 		} | 
 | 412 | 		assert(wsign != 0); /* else nbits was 0 */ | 
 | 413 | 		assert(vsign != 0); /* if vsign were 0, then since wsign is | 
 | 414 | 		                     * not 0, we would have taken the | 
 | 415 | 		                     * vsign != wsign branch at the start */ | 
 | 416 | 		/* We want to work with non-negative numbers. */ | 
 | 417 | 		if (vsign < 0) { | 
 | 418 | 			/* "Multiply both sides" by -1; this also swaps the | 
 | 419 | 			 * comparator. | 
 | 420 | 			 */ | 
 | 421 | 			i = -i; | 
 | 422 | 			op = _Py_SwappedOp[op]; | 
 | 423 | 		} | 
 | 424 | 		assert(i > 0.0); | 
| Neal Norwitz | b2da01b | 2006-01-08 01:11:25 +0000 | [diff] [blame] | 425 | 		(void) frexp(i, &exponent); | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 426 | 		/* exponent is the # of bits in v before the radix point; | 
 | 427 | 		 * we know that nbits (the # of bits in w) > 48 at this point | 
 | 428 | 		 */ | 
 | 429 | 		if (exponent < 0 || (size_t)exponent < nbits) { | 
 | 430 | 			i = 1.0; | 
 | 431 | 			j = 2.0; | 
 | 432 | 			goto Compare; | 
 | 433 | 		} | 
 | 434 | 		if ((size_t)exponent > nbits) { | 
 | 435 | 			i = 2.0; | 
 | 436 | 			j = 1.0; | 
 | 437 | 			goto Compare; | 
 | 438 | 		} | 
 | 439 | 		/* v and w have the same number of bits before the radix | 
 | 440 | 		 * point.  Construct two longs that have the same comparison | 
 | 441 | 		 * outcome. | 
 | 442 | 		 */ | 
 | 443 | 		{ | 
 | 444 | 			double fracpart; | 
 | 445 | 			double intpart; | 
 | 446 | 			PyObject *result = NULL; | 
 | 447 | 			PyObject *one = NULL; | 
 | 448 | 			PyObject *vv = NULL; | 
 | 449 | 			PyObject *ww = w; | 
 | 450 |  | 
 | 451 | 			if (wsign < 0) { | 
 | 452 | 				ww = PyNumber_Negative(w); | 
 | 453 | 				if (ww == NULL) | 
 | 454 | 					goto Error; | 
 | 455 | 			} | 
 | 456 | 			else | 
 | 457 | 				Py_INCREF(ww); | 
 | 458 |  | 
 | 459 | 			fracpart = modf(i, &intpart); | 
 | 460 | 			vv = PyLong_FromDouble(intpart); | 
 | 461 | 			if (vv == NULL) | 
 | 462 | 				goto Error; | 
 | 463 |  | 
 | 464 | 			if (fracpart != 0.0) { | 
 | 465 | 				/* Shift left, and or a 1 bit into vv | 
 | 466 | 				 * to represent the lost fraction. | 
 | 467 | 				 */ | 
 | 468 | 				PyObject *temp; | 
 | 469 |  | 
 | 470 | 				one = PyInt_FromLong(1); | 
 | 471 | 				if (one == NULL) | 
 | 472 | 					goto Error; | 
 | 473 |  | 
 | 474 | 				temp = PyNumber_Lshift(ww, one); | 
 | 475 | 				if (temp == NULL) | 
 | 476 | 					goto Error; | 
 | 477 | 				Py_DECREF(ww); | 
 | 478 | 				ww = temp; | 
 | 479 |  | 
 | 480 | 				temp = PyNumber_Lshift(vv, one); | 
 | 481 | 				if (temp == NULL) | 
 | 482 | 					goto Error; | 
 | 483 | 				Py_DECREF(vv); | 
 | 484 | 				vv = temp; | 
 | 485 |  | 
 | 486 | 				temp = PyNumber_Or(vv, one); | 
 | 487 | 				if (temp == NULL) | 
 | 488 | 					goto Error; | 
 | 489 | 				Py_DECREF(vv); | 
 | 490 | 				vv = temp; | 
 | 491 | 			} | 
 | 492 |  | 
 | 493 | 			r = PyObject_RichCompareBool(vv, ww, op); | 
 | 494 | 			if (r < 0) | 
 | 495 | 				goto Error; | 
 | 496 | 			result = PyBool_FromLong(r); | 
 | 497 |  		 Error: | 
 | 498 |  		 	Py_XDECREF(vv); | 
 | 499 |  		 	Py_XDECREF(ww); | 
 | 500 |  		 	Py_XDECREF(one); | 
 | 501 |  		 	return result; | 
 | 502 | 		} | 
 | 503 | 	} /* else if (PyLong_Check(w)) */ | 
 | 504 |  | 
 | 505 | 	else	/* w isn't float, int, or long */ | 
 | 506 | 		goto Unimplemented; | 
 | 507 |  | 
 | 508 |  Compare: | 
| Michael W. Hudson | d3b33b5 | 2004-02-19 19:35:22 +0000 | [diff] [blame] | 509 | 	PyFPE_START_PROTECT("richcompare", return NULL) | 
 | 510 | 	switch (op) { | 
 | 511 | 	case Py_EQ: | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 512 | 		r = i == j; | 
| Michael W. Hudson | d3b33b5 | 2004-02-19 19:35:22 +0000 | [diff] [blame] | 513 | 		break; | 
 | 514 | 	case Py_NE: | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 515 | 		r = i != j; | 
| Michael W. Hudson | d3b33b5 | 2004-02-19 19:35:22 +0000 | [diff] [blame] | 516 | 		break; | 
 | 517 | 	case Py_LE: | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 518 | 		r = i <= j; | 
| Michael W. Hudson | d3b33b5 | 2004-02-19 19:35:22 +0000 | [diff] [blame] | 519 | 		break; | 
 | 520 | 	case Py_GE: | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 521 | 		r = i >= j; | 
| Michael W. Hudson | d3b33b5 | 2004-02-19 19:35:22 +0000 | [diff] [blame] | 522 | 		break; | 
 | 523 | 	case Py_LT: | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 524 | 		r = i < j; | 
| Michael W. Hudson | d3b33b5 | 2004-02-19 19:35:22 +0000 | [diff] [blame] | 525 | 		break; | 
 | 526 | 	case Py_GT: | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 527 | 		r = i > j; | 
| Michael W. Hudson | d3b33b5 | 2004-02-19 19:35:22 +0000 | [diff] [blame] | 528 | 		break; | 
 | 529 | 	} | 
| Michael W. Hudson | 957f977 | 2004-02-26 12:33:09 +0000 | [diff] [blame] | 530 | 	PyFPE_END_PROTECT(r) | 
| Michael W. Hudson | d3b33b5 | 2004-02-19 19:35:22 +0000 | [diff] [blame] | 531 | 	return PyBool_FromLong(r); | 
| Tim Peters | 307fa78 | 2004-09-23 08:06:40 +0000 | [diff] [blame] | 532 |  | 
 | 533 |  Unimplemented: | 
 | 534 | 	Py_INCREF(Py_NotImplemented); | 
 | 535 | 	return Py_NotImplemented; | 
| Michael W. Hudson | d3b33b5 | 2004-02-19 19:35:22 +0000 | [diff] [blame] | 536 | } | 
 | 537 |  | 
| Guido van Rossum | 9bfef44 | 1993-03-29 10:43:31 +0000 | [diff] [blame] | 538 | static long | 
| Fred Drake | fd99de6 | 2000-07-09 05:02:18 +0000 | [diff] [blame] | 539 | float_hash(PyFloatObject *v) | 
| Guido van Rossum | 9bfef44 | 1993-03-29 10:43:31 +0000 | [diff] [blame] | 540 | { | 
| Tim Peters | 39dce29 | 2000-08-15 03:34:48 +0000 | [diff] [blame] | 541 | 	return _Py_HashDouble(v->ob_fval); | 
| Guido van Rossum | 9bfef44 | 1993-03-29 10:43:31 +0000 | [diff] [blame] | 542 | } | 
 | 543 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 544 | static PyObject * | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 545 | float_add(PyObject *v, PyObject *w) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 546 | { | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 547 | 	double a,b; | 
 | 548 | 	CONVERT_TO_DOUBLE(v, a); | 
 | 549 | 	CONVERT_TO_DOUBLE(w, b); | 
| Guido van Rossum | 09e6ad0 | 1997-02-14 22:54:21 +0000 | [diff] [blame] | 550 | 	PyFPE_START_PROTECT("add", return 0) | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 551 | 	a = a + b; | 
 | 552 | 	PyFPE_END_PROTECT(a) | 
 | 553 | 	return PyFloat_FromDouble(a); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 554 | } | 
 | 555 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 556 | static PyObject * | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 557 | float_sub(PyObject *v, PyObject *w) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 558 | { | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 559 | 	double a,b; | 
 | 560 | 	CONVERT_TO_DOUBLE(v, a); | 
 | 561 | 	CONVERT_TO_DOUBLE(w, b); | 
| Guido van Rossum | 09e6ad0 | 1997-02-14 22:54:21 +0000 | [diff] [blame] | 562 | 	PyFPE_START_PROTECT("subtract", return 0) | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 563 | 	a = a - b; | 
 | 564 | 	PyFPE_END_PROTECT(a) | 
 | 565 | 	return PyFloat_FromDouble(a); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 566 | } | 
 | 567 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 568 | static PyObject * | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 569 | float_mul(PyObject *v, PyObject *w) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 570 | { | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 571 | 	double a,b; | 
 | 572 | 	CONVERT_TO_DOUBLE(v, a); | 
 | 573 | 	CONVERT_TO_DOUBLE(w, b); | 
| Guido van Rossum | 09e6ad0 | 1997-02-14 22:54:21 +0000 | [diff] [blame] | 574 | 	PyFPE_START_PROTECT("multiply", return 0) | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 575 | 	a = a * b; | 
 | 576 | 	PyFPE_END_PROTECT(a) | 
 | 577 | 	return PyFloat_FromDouble(a); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 578 | } | 
 | 579 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 580 | static PyObject * | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 581 | float_div(PyObject *v, PyObject *w) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 582 | { | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 583 | 	double a,b; | 
 | 584 | 	CONVERT_TO_DOUBLE(v, a); | 
 | 585 | 	CONVERT_TO_DOUBLE(w, b); | 
 | 586 | 	if (b == 0.0) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 587 | 		PyErr_SetString(PyExc_ZeroDivisionError, "float division"); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 588 | 		return NULL; | 
 | 589 | 	} | 
| Guido van Rossum | 09e6ad0 | 1997-02-14 22:54:21 +0000 | [diff] [blame] | 590 | 	PyFPE_START_PROTECT("divide", return 0) | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 591 | 	a = a / b; | 
 | 592 | 	PyFPE_END_PROTECT(a) | 
 | 593 | 	return PyFloat_FromDouble(a); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 594 | } | 
 | 595 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 596 | static PyObject * | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 597 | float_rem(PyObject *v, PyObject *w) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 598 | { | 
| Guido van Rossum | 56cd67a | 1992-01-26 18:16:35 +0000 | [diff] [blame] | 599 | 	double vx, wx; | 
| Guido van Rossum | 9263e78 | 1999-05-06 14:26:34 +0000 | [diff] [blame] | 600 | 	double mod; | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 601 |  	CONVERT_TO_DOUBLE(v, vx); | 
 | 602 |  	CONVERT_TO_DOUBLE(w, wx); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 603 | 	if (wx == 0.0) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 604 | 		PyErr_SetString(PyExc_ZeroDivisionError, "float modulo"); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 605 | 		return NULL; | 
 | 606 | 	} | 
| Guido van Rossum | 09e6ad0 | 1997-02-14 22:54:21 +0000 | [diff] [blame] | 607 | 	PyFPE_START_PROTECT("modulo", return 0) | 
| Guido van Rossum | 56cd67a | 1992-01-26 18:16:35 +0000 | [diff] [blame] | 608 | 	mod = fmod(vx, wx); | 
| Guido van Rossum | 9263e78 | 1999-05-06 14:26:34 +0000 | [diff] [blame] | 609 | 	/* note: checking mod*wx < 0 is incorrect -- underflows to | 
 | 610 | 	   0 if wx < sqrt(smallest nonzero double) */ | 
 | 611 | 	if (mod && ((wx < 0) != (mod < 0))) { | 
| Guido van Rossum | 56cd67a | 1992-01-26 18:16:35 +0000 | [diff] [blame] | 612 | 		mod += wx; | 
| Guido van Rossum | 56cd67a | 1992-01-26 18:16:35 +0000 | [diff] [blame] | 613 | 	} | 
| Guido van Rossum | 45b8391 | 1997-03-14 04:32:50 +0000 | [diff] [blame] | 614 | 	PyFPE_END_PROTECT(mod) | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 615 | 	return PyFloat_FromDouble(mod); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 616 | } | 
 | 617 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 618 | static PyObject * | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 619 | float_divmod(PyObject *v, PyObject *w) | 
| Guido van Rossum | eba1b5e | 1991-05-05 20:07:00 +0000 | [diff] [blame] | 620 | { | 
| Guido van Rossum | 15ecff4 | 1991-10-20 20:16:45 +0000 | [diff] [blame] | 621 | 	double vx, wx; | 
| Guido van Rossum | 9263e78 | 1999-05-06 14:26:34 +0000 | [diff] [blame] | 622 | 	double div, mod, floordiv; | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 623 |  	CONVERT_TO_DOUBLE(v, vx); | 
 | 624 |  	CONVERT_TO_DOUBLE(w, wx); | 
| Guido van Rossum | 15ecff4 | 1991-10-20 20:16:45 +0000 | [diff] [blame] | 625 | 	if (wx == 0.0) { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 626 | 		PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()"); | 
| Guido van Rossum | 15ecff4 | 1991-10-20 20:16:45 +0000 | [diff] [blame] | 627 | 		return NULL; | 
 | 628 | 	} | 
| Guido van Rossum | 09e6ad0 | 1997-02-14 22:54:21 +0000 | [diff] [blame] | 629 | 	PyFPE_START_PROTECT("divmod", return 0) | 
| Guido van Rossum | 15ecff4 | 1991-10-20 20:16:45 +0000 | [diff] [blame] | 630 | 	mod = fmod(vx, wx); | 
| Tim Peters | 78fc0b5 | 2000-09-16 03:54:24 +0000 | [diff] [blame] | 631 | 	/* fmod is typically exact, so vx-mod is *mathematically* an | 
| Guido van Rossum | 9263e78 | 1999-05-06 14:26:34 +0000 | [diff] [blame] | 632 | 	   exact multiple of wx.  But this is fp arithmetic, and fp | 
 | 633 | 	   vx - mod is an approximation; the result is that div may | 
 | 634 | 	   not be an exact integral value after the division, although | 
 | 635 | 	   it will always be very close to one. | 
 | 636 | 	*/ | 
| Guido van Rossum | 15ecff4 | 1991-10-20 20:16:45 +0000 | [diff] [blame] | 637 | 	div = (vx - mod) / wx; | 
| Tim Peters | d2e40d6 | 2001-11-01 23:12:27 +0000 | [diff] [blame] | 638 | 	if (mod) { | 
 | 639 | 		/* ensure the remainder has the same sign as the denominator */ | 
 | 640 | 		if ((wx < 0) != (mod < 0)) { | 
 | 641 | 			mod += wx; | 
 | 642 | 			div -= 1.0; | 
 | 643 | 		} | 
 | 644 | 	} | 
 | 645 | 	else { | 
 | 646 | 		/* the remainder is zero, and in the presence of signed zeroes | 
 | 647 | 		   fmod returns different results across platforms; ensure | 
 | 648 | 		   it has the same sign as the denominator; we'd like to do | 
 | 649 | 		   "mod = wx * 0.0", but that may get optimized away */ | 
| Tim Peters | 4e8ab5d | 2001-11-01 23:59:56 +0000 | [diff] [blame] | 650 | 		mod *= mod;  /* hide "mod = +0" from optimizer */ | 
| Tim Peters | d2e40d6 | 2001-11-01 23:12:27 +0000 | [diff] [blame] | 651 | 		if (wx < 0.0) | 
 | 652 | 			mod = -mod; | 
| Guido van Rossum | 15ecff4 | 1991-10-20 20:16:45 +0000 | [diff] [blame] | 653 | 	} | 
| Guido van Rossum | 9263e78 | 1999-05-06 14:26:34 +0000 | [diff] [blame] | 654 | 	/* snap quotient to nearest integral value */ | 
| Tim Peters | d2e40d6 | 2001-11-01 23:12:27 +0000 | [diff] [blame] | 655 | 	if (div) { | 
 | 656 | 		floordiv = floor(div); | 
 | 657 | 		if (div - floordiv > 0.5) | 
 | 658 | 			floordiv += 1.0; | 
 | 659 | 	} | 
 | 660 | 	else { | 
 | 661 | 		/* div is zero - get the same sign as the true quotient */ | 
 | 662 | 		div *= div;	/* hide "div = +0" from optimizers */ | 
 | 663 | 		floordiv = div * vx / wx; /* zero w/ sign of vx/wx */ | 
 | 664 | 	} | 
 | 665 | 	PyFPE_END_PROTECT(floordiv) | 
| Guido van Rossum | 9263e78 | 1999-05-06 14:26:34 +0000 | [diff] [blame] | 666 | 	return Py_BuildValue("(dd)", floordiv, mod); | 
| Guido van Rossum | eba1b5e | 1991-05-05 20:07:00 +0000 | [diff] [blame] | 667 | } | 
 | 668 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 669 | static PyObject * | 
| Tim Peters | 63a3571 | 2001-12-11 19:57:24 +0000 | [diff] [blame] | 670 | float_floor_div(PyObject *v, PyObject *w) | 
 | 671 | { | 
 | 672 | 	PyObject *t, *r; | 
 | 673 |  | 
 | 674 | 	t = float_divmod(v, w); | 
| Tim Peters | 77d8a4f | 2001-12-11 20:31:34 +0000 | [diff] [blame] | 675 | 	if (t == NULL || t == Py_NotImplemented) | 
 | 676 | 		return t; | 
 | 677 | 	assert(PyTuple_CheckExact(t)); | 
 | 678 | 	r = PyTuple_GET_ITEM(t, 0); | 
 | 679 | 	Py_INCREF(r); | 
 | 680 | 	Py_DECREF(t); | 
 | 681 | 	return r; | 
| Tim Peters | 63a3571 | 2001-12-11 19:57:24 +0000 | [diff] [blame] | 682 | } | 
 | 683 |  | 
 | 684 | static PyObject * | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 685 | float_pow(PyObject *v, PyObject *w, PyObject *z) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 686 | { | 
 | 687 | 	double iv, iw, ix; | 
| Tim Peters | 32f453e | 2001-09-03 08:35:41 +0000 | [diff] [blame] | 688 |  | 
 | 689 | 	if ((PyObject *)z != Py_None) { | 
| Tim Peters | 4c483c4 | 2001-09-05 06:24:58 +0000 | [diff] [blame] | 690 | 		PyErr_SetString(PyExc_TypeError, "pow() 3rd argument not " | 
| Tim Peters | 97f4a33 | 2001-09-05 23:49:24 +0000 | [diff] [blame] | 691 | 			"allowed unless all arguments are integers"); | 
| Tim Peters | 32f453e | 2001-09-03 08:35:41 +0000 | [diff] [blame] | 692 | 		return NULL; | 
 | 693 | 	} | 
 | 694 |  | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 695 | 	CONVERT_TO_DOUBLE(v, iv); | 
 | 696 | 	CONVERT_TO_DOUBLE(w, iw); | 
| Tim Peters | c54d190 | 2000-10-06 00:36:09 +0000 | [diff] [blame] | 697 |  | 
 | 698 | 	/* Sort out special cases here instead of relying on pow() */ | 
| Tim Peters | 96685bf | 2001-08-23 22:31:37 +0000 | [diff] [blame] | 699 | 	if (iw == 0) { 		/* v**0 is 1, even 0**0 */ | 
| Tim Peters | c54d190 | 2000-10-06 00:36:09 +0000 | [diff] [blame] | 700 | 		PyFPE_START_PROTECT("pow", return NULL) | 
 | 701 | 		if ((PyObject *)z != Py_None) { | 
| Neil Schemenauer | 32117e5 | 2001-01-04 01:44:34 +0000 | [diff] [blame] | 702 | 			double iz; | 
| Neil Schemenauer | 010b0cc | 2001-01-08 06:29:50 +0000 | [diff] [blame] | 703 | 			CONVERT_TO_DOUBLE(z, iz); | 
| Tim Peters | 96685bf | 2001-08-23 22:31:37 +0000 | [diff] [blame] | 704 | 			ix = fmod(1.0, iz); | 
 | 705 | 			if (ix != 0 && iz < 0) | 
 | 706 | 				ix += iz; | 
| Guido van Rossum | 70d9346 | 1991-05-28 21:57:39 +0000 | [diff] [blame] | 707 | 		} | 
| Tim Peters | c54d190 | 2000-10-06 00:36:09 +0000 | [diff] [blame] | 708 | 		else | 
 | 709 | 			ix = 1.0; | 
 | 710 | 		PyFPE_END_PROTECT(ix) | 
| Tim Peters | d2364e8 | 2001-11-01 20:09:42 +0000 | [diff] [blame] | 711 | 		return PyFloat_FromDouble(ix); | 
| Tim Peters | c54d190 | 2000-10-06 00:36:09 +0000 | [diff] [blame] | 712 | 	} | 
| Tim Peters | 96685bf | 2001-08-23 22:31:37 +0000 | [diff] [blame] | 713 | 	if (iv == 0.0) {  /* 0**w is error if w<0, else 1 */ | 
| Tim Peters | c54d190 | 2000-10-06 00:36:09 +0000 | [diff] [blame] | 714 | 		if (iw < 0.0) { | 
 | 715 | 			PyErr_SetString(PyExc_ZeroDivisionError, | 
| Fred Drake | 661ea26 | 2000-10-24 19:57:45 +0000 | [diff] [blame] | 716 | 					"0.0 cannot be raised to a negative power"); | 
| Tim Peters | c54d190 | 2000-10-06 00:36:09 +0000 | [diff] [blame] | 717 | 			return NULL; | 
 | 718 | 		} | 
 | 719 | 		return PyFloat_FromDouble(0.0); | 
 | 720 | 	} | 
| Tim Peters | e87568d | 2003-05-24 20:18:24 +0000 | [diff] [blame] | 721 | 	if (iv < 0.0) { | 
 | 722 | 		/* Whether this is an error is a mess, and bumps into libm | 
 | 723 | 		 * bugs so we have to figure it out ourselves. | 
 | 724 | 		 */ | 
 | 725 | 		if (iw != floor(iw)) { | 
 | 726 | 			PyErr_SetString(PyExc_ValueError, "negative number " | 
 | 727 | 				"cannot be raised to a fractional power"); | 
 | 728 | 			return NULL; | 
 | 729 | 		} | 
 | 730 | 		/* iw is an exact integer, albeit perhaps a very large one. | 
 | 731 | 		 * -1 raised to an exact integer should never be exceptional. | 
 | 732 | 		 * Alas, some libms (chiefly glibc as of early 2003) return | 
 | 733 | 		 * NaN and set EDOM on pow(-1, large_int) if the int doesn't | 
 | 734 | 		 * happen to be representable in a *C* integer.  That's a | 
 | 735 | 		 * bug; we let that slide in math.pow() (which currently | 
 | 736 | 		 * reflects all platform accidents), but not for Python's **. | 
 | 737 | 		 */ | 
| Thomas Wouters | 477c8d5 | 2006-05-27 19:21:47 +0000 | [diff] [blame] | 738 | 		 if (iv == -1.0 && Py_IS_FINITE(iw)) { | 
| Tim Peters | e87568d | 2003-05-24 20:18:24 +0000 | [diff] [blame] | 739 | 		 	/* Return 1 if iw is even, -1 if iw is odd; there's | 
 | 740 | 		 	 * no guarantee that any C integral type is big | 
 | 741 | 		 	 * enough to hold iw, so we have to check this | 
 | 742 | 		 	 * indirectly. | 
 | 743 | 		 	 */ | 
 | 744 | 		 	ix = floor(iw * 0.5) * 2.0; | 
 | 745 | 			return PyFloat_FromDouble(ix == iw ? 1.0 : -1.0); | 
 | 746 | 		} | 
 | 747 | 		/* Else iv != -1.0, and overflow or underflow are possible. | 
 | 748 | 		 * Unless we're to write pow() ourselves, we have to trust | 
 | 749 | 		 * the platform to do this correctly. | 
 | 750 | 		 */ | 
| Guido van Rossum | 86c04c2 | 1996-08-09 20:50:14 +0000 | [diff] [blame] | 751 | 	} | 
| Tim Peters | 96685bf | 2001-08-23 22:31:37 +0000 | [diff] [blame] | 752 | 	errno = 0; | 
 | 753 | 	PyFPE_START_PROTECT("pow", return NULL) | 
 | 754 | 	ix = pow(iv, iw); | 
 | 755 | 	PyFPE_END_PROTECT(ix) | 
| Tim Peters | dc5a508 | 2002-03-09 04:58:24 +0000 | [diff] [blame] | 756 | 	Py_ADJUST_ERANGE1(ix); | 
| Guido van Rossum | 2a9096b | 1990-10-21 22:15:08 +0000 | [diff] [blame] | 757 | 	if (errno != 0) { | 
| Tim Peters | e87568d | 2003-05-24 20:18:24 +0000 | [diff] [blame] | 758 | 		/* We don't expect any errno value other than ERANGE, but | 
 | 759 | 		 * the range of libm bugs appears unbounded. | 
 | 760 | 		 */ | 
 | 761 | 		PyErr_SetFromErrno(errno == ERANGE ? PyExc_OverflowError : | 
 | 762 | 						     PyExc_ValueError); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 763 | 		return NULL; | 
| Guido van Rossum | 2a9096b | 1990-10-21 22:15:08 +0000 | [diff] [blame] | 764 | 	} | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 765 | 	return PyFloat_FromDouble(ix); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 766 | } | 
 | 767 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 768 | static PyObject * | 
| Fred Drake | fd99de6 | 2000-07-09 05:02:18 +0000 | [diff] [blame] | 769 | float_neg(PyFloatObject *v) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 770 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 771 | 	return PyFloat_FromDouble(-v->ob_fval); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 772 | } | 
 | 773 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 774 | static PyObject * | 
| Fred Drake | fd99de6 | 2000-07-09 05:02:18 +0000 | [diff] [blame] | 775 | float_pos(PyFloatObject *v) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 776 | { | 
| Tim Peters | 0280cf7 | 2001-09-11 21:53:35 +0000 | [diff] [blame] | 777 | 	if (PyFloat_CheckExact(v)) { | 
 | 778 | 		Py_INCREF(v); | 
 | 779 | 		return (PyObject *)v; | 
 | 780 | 	} | 
 | 781 | 	else | 
 | 782 | 		return PyFloat_FromDouble(v->ob_fval); | 
| Guido van Rossum | eba1b5e | 1991-05-05 20:07:00 +0000 | [diff] [blame] | 783 | } | 
 | 784 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 785 | static PyObject * | 
| Fred Drake | fd99de6 | 2000-07-09 05:02:18 +0000 | [diff] [blame] | 786 | float_abs(PyFloatObject *v) | 
| Guido van Rossum | eba1b5e | 1991-05-05 20:07:00 +0000 | [diff] [blame] | 787 | { | 
| Tim Peters | faf0cd2 | 2001-11-01 21:51:15 +0000 | [diff] [blame] | 788 | 	return PyFloat_FromDouble(fabs(v->ob_fval)); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 789 | } | 
 | 790 |  | 
| Guido van Rossum | 50b4ef6 | 1991-05-14 11:57:01 +0000 | [diff] [blame] | 791 | static int | 
| Jack Diederich | 4dafcc4 | 2006-11-28 19:15:13 +0000 | [diff] [blame] | 792 | float_bool(PyFloatObject *v) | 
| Guido van Rossum | 50b4ef6 | 1991-05-14 11:57:01 +0000 | [diff] [blame] | 793 | { | 
 | 794 | 	return v->ob_fval != 0.0; | 
 | 795 | } | 
 | 796 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 797 | static PyObject * | 
| Walter Dörwald | f171540 | 2002-11-19 20:49:15 +0000 | [diff] [blame] | 798 | float_long(PyObject *v) | 
 | 799 | { | 
 | 800 | 	double x = PyFloat_AsDouble(v); | 
 | 801 | 	return PyLong_FromDouble(x); | 
 | 802 | } | 
 | 803 |  | 
 | 804 | static PyObject * | 
| Fred Drake | fd99de6 | 2000-07-09 05:02:18 +0000 | [diff] [blame] | 805 | float_int(PyObject *v) | 
| Guido van Rossum | 1899c2e | 1992-09-12 11:09:23 +0000 | [diff] [blame] | 806 | { | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 807 | 	double x = PyFloat_AsDouble(v); | 
| Tim Peters | 7321ec4 | 2001-07-26 20:02:17 +0000 | [diff] [blame] | 808 | 	double wholepart;	/* integral portion of x, rounded toward 0 */ | 
| Tim Peters | 7321ec4 | 2001-07-26 20:02:17 +0000 | [diff] [blame] | 809 |  | 
 | 810 | 	(void)modf(x, &wholepart); | 
| Tim Peters | 7d79124 | 2002-11-21 22:26:37 +0000 | [diff] [blame] | 811 | 	/* Try to get out cheap if this fits in a Python int.  The attempt | 
 | 812 | 	 * to cast to long must be protected, as C doesn't define what | 
 | 813 | 	 * happens if the double is too big to fit in a long.  Some rare | 
 | 814 | 	 * systems raise an exception then (RISCOS was mentioned as one, | 
 | 815 | 	 * and someone using a non-default option on Sun also bumped into | 
 | 816 | 	 * that).  Note that checking for >= and <= LONG_{MIN,MAX} would | 
 | 817 | 	 * still be vulnerable:  if a long has more bits of precision than | 
 | 818 | 	 * a double, casting MIN/MAX to double may yield an approximation, | 
 | 819 | 	 * and if that's rounded up, then, e.g., wholepart=LONG_MAX+1 would | 
 | 820 | 	 * yield true from the C expression wholepart<=LONG_MAX, despite | 
 | 821 | 	 * that wholepart is actually greater than LONG_MAX. | 
 | 822 | 	 */ | 
 | 823 | 	if (LONG_MIN < wholepart && wholepart < LONG_MAX) { | 
 | 824 | 		const long aslong = (long)wholepart; | 
| Tim Peters | 7321ec4 | 2001-07-26 20:02:17 +0000 | [diff] [blame] | 825 | 		return PyInt_FromLong(aslong); | 
| Tim Peters | 7d79124 | 2002-11-21 22:26:37 +0000 | [diff] [blame] | 826 | 	} | 
 | 827 | 	return PyLong_FromDouble(wholepart); | 
| Guido van Rossum | 1899c2e | 1992-09-12 11:09:23 +0000 | [diff] [blame] | 828 | } | 
 | 829 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 830 | static PyObject * | 
| Fred Drake | fd99de6 | 2000-07-09 05:02:18 +0000 | [diff] [blame] | 831 | float_float(PyObject *v) | 
| Guido van Rossum | 1899c2e | 1992-09-12 11:09:23 +0000 | [diff] [blame] | 832 | { | 
| Brett Cannon | c3647ac | 2005-04-26 03:45:26 +0000 | [diff] [blame] | 833 | 	if (PyFloat_CheckExact(v)) | 
 | 834 | 		Py_INCREF(v); | 
 | 835 | 	else | 
 | 836 | 		v = PyFloat_FromDouble(((PyFloatObject *)v)->ob_fval); | 
| Guido van Rossum | 1899c2e | 1992-09-12 11:09:23 +0000 | [diff] [blame] | 837 | 	return v; | 
 | 838 | } | 
 | 839 |  | 
 | 840 |  | 
| Jeremy Hylton | 938ace6 | 2002-07-17 16:30:39 +0000 | [diff] [blame] | 841 | static PyObject * | 
| Guido van Rossum | bef1417 | 2001-08-29 15:47:46 +0000 | [diff] [blame] | 842 | float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds); | 
 | 843 |  | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 844 | static PyObject * | 
 | 845 | float_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
 | 846 | { | 
 | 847 | 	PyObject *x = Py_False; /* Integer zero */ | 
| Martin v. Löwis | 15e6274 | 2006-02-27 16:46:16 +0000 | [diff] [blame] | 848 | 	static char *kwlist[] = {"x", 0}; | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 849 |  | 
| Guido van Rossum | bef1417 | 2001-08-29 15:47:46 +0000 | [diff] [blame] | 850 | 	if (type != &PyFloat_Type) | 
 | 851 | 		return float_subtype_new(type, args, kwds); /* Wimp out */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 852 | 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:float", kwlist, &x)) | 
 | 853 | 		return NULL; | 
 | 854 | 	if (PyString_Check(x)) | 
 | 855 | 		return PyFloat_FromString(x, NULL); | 
 | 856 | 	return PyNumber_Float(x); | 
 | 857 | } | 
 | 858 |  | 
| Guido van Rossum | bef1417 | 2001-08-29 15:47:46 +0000 | [diff] [blame] | 859 | /* Wimpy, slow approach to tp_new calls for subtypes of float: | 
 | 860 |    first create a regular float from whatever arguments we got, | 
 | 861 |    then allocate a subtype instance and initialize its ob_fval | 
 | 862 |    from the regular float.  The regular float is then thrown away. | 
 | 863 | */ | 
 | 864 | static PyObject * | 
 | 865 | float_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) | 
 | 866 | { | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 867 | 	PyObject *tmp, *newobj; | 
| Guido van Rossum | bef1417 | 2001-08-29 15:47:46 +0000 | [diff] [blame] | 868 |  | 
 | 869 | 	assert(PyType_IsSubtype(type, &PyFloat_Type)); | 
 | 870 | 	tmp = float_new(&PyFloat_Type, args, kwds); | 
 | 871 | 	if (tmp == NULL) | 
 | 872 | 		return NULL; | 
| Tim Peters | 2400fa4 | 2001-09-12 19:12:49 +0000 | [diff] [blame] | 873 | 	assert(PyFloat_CheckExact(tmp)); | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 874 | 	newobj = type->tp_alloc(type, 0); | 
 | 875 | 	if (newobj == NULL) { | 
| Raymond Hettinger | f466793 | 2003-06-28 20:04:25 +0000 | [diff] [blame] | 876 | 		Py_DECREF(tmp); | 
| Guido van Rossum | bef1417 | 2001-08-29 15:47:46 +0000 | [diff] [blame] | 877 | 		return NULL; | 
| Raymond Hettinger | f466793 | 2003-06-28 20:04:25 +0000 | [diff] [blame] | 878 | 	} | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 879 | 	((PyFloatObject *)newobj)->ob_fval = ((PyFloatObject *)tmp)->ob_fval; | 
| Guido van Rossum | bef1417 | 2001-08-29 15:47:46 +0000 | [diff] [blame] | 880 | 	Py_DECREF(tmp); | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 881 | 	return newobj; | 
| Guido van Rossum | bef1417 | 2001-08-29 15:47:46 +0000 | [diff] [blame] | 882 | } | 
 | 883 |  | 
| Guido van Rossum | 5d9113d | 2003-01-29 17:58:45 +0000 | [diff] [blame] | 884 | static PyObject * | 
 | 885 | float_getnewargs(PyFloatObject *v) | 
 | 886 | { | 
 | 887 | 	return Py_BuildValue("(d)", v->ob_fval); | 
 | 888 | } | 
 | 889 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 890 | /* this is for the benefit of the pack/unpack routines below */ | 
 | 891 |  | 
 | 892 | typedef enum { | 
 | 893 | 	unknown_format, ieee_big_endian_format, ieee_little_endian_format | 
 | 894 | } float_format_type; | 
 | 895 |  | 
 | 896 | static float_format_type double_format, float_format; | 
 | 897 | static float_format_type detected_double_format, detected_float_format; | 
 | 898 |  | 
 | 899 | static PyObject * | 
 | 900 | float_getformat(PyTypeObject *v, PyObject* arg) | 
 | 901 | { | 
 | 902 | 	char* s; | 
 | 903 | 	float_format_type r; | 
 | 904 |  | 
 | 905 | 	if (!PyString_Check(arg)) { | 
 | 906 | 		PyErr_Format(PyExc_TypeError, | 
 | 907 | 	     "__getformat__() argument must be string, not %.500s", | 
 | 908 | 			     arg->ob_type->tp_name); | 
 | 909 | 		return NULL; | 
 | 910 | 	} | 
 | 911 | 	s = PyString_AS_STRING(arg); | 
 | 912 | 	if (strcmp(s, "double") == 0) { | 
 | 913 | 		r = double_format; | 
 | 914 | 	} | 
 | 915 | 	else if (strcmp(s, "float") == 0) { | 
 | 916 | 		r = float_format; | 
 | 917 | 	} | 
 | 918 | 	else { | 
 | 919 | 		PyErr_SetString(PyExc_ValueError, | 
 | 920 | 				"__getformat__() argument 1 must be " | 
 | 921 | 				"'double' or 'float'"); | 
 | 922 | 		return NULL; | 
 | 923 | 	} | 
 | 924 | 	 | 
 | 925 | 	switch (r) { | 
 | 926 | 	case unknown_format: | 
 | 927 | 		return PyString_FromString("unknown"); | 
 | 928 | 	case ieee_little_endian_format: | 
 | 929 | 		return PyString_FromString("IEEE, little-endian"); | 
 | 930 | 	case ieee_big_endian_format: | 
 | 931 | 		return PyString_FromString("IEEE, big-endian"); | 
 | 932 | 	default: | 
 | 933 | 		Py_FatalError("insane float_format or double_format"); | 
 | 934 | 		return NULL; | 
 | 935 | 	} | 
 | 936 | } | 
 | 937 |  | 
 | 938 | PyDoc_STRVAR(float_getformat_doc, | 
 | 939 | "float.__getformat__(typestr) -> string\n" | 
 | 940 | "\n" | 
 | 941 | "You probably don't want to use this function.  It exists mainly to be\n" | 
 | 942 | "used in Python's test suite.\n" | 
 | 943 | "\n" | 
 | 944 | "typestr must be 'double' or 'float'.  This function returns whichever of\n" | 
 | 945 | "'unknown', 'IEEE, big-endian' or 'IEEE, little-endian' best describes the\n" | 
 | 946 | "format of floating point numbers used by the C type named by typestr."); | 
 | 947 |  | 
 | 948 | static PyObject * | 
 | 949 | float_setformat(PyTypeObject *v, PyObject* args) | 
 | 950 | { | 
 | 951 | 	char* typestr; | 
 | 952 | 	char* format; | 
 | 953 | 	float_format_type f; | 
 | 954 | 	float_format_type detected; | 
 | 955 | 	float_format_type *p; | 
 | 956 |  | 
 | 957 | 	if (!PyArg_ParseTuple(args, "ss:__setformat__", &typestr, &format)) | 
 | 958 | 		return NULL; | 
 | 959 |  | 
 | 960 | 	if (strcmp(typestr, "double") == 0) { | 
 | 961 | 		p = &double_format; | 
 | 962 | 		detected = detected_double_format; | 
 | 963 | 	} | 
 | 964 | 	else if (strcmp(typestr, "float") == 0) { | 
 | 965 | 		p = &float_format; | 
 | 966 | 		detected = detected_float_format; | 
 | 967 | 	} | 
 | 968 | 	else { | 
 | 969 | 		PyErr_SetString(PyExc_ValueError, | 
 | 970 | 				"__setformat__() argument 1 must " | 
 | 971 | 				"be 'double' or 'float'"); | 
 | 972 | 		return NULL; | 
 | 973 | 	} | 
 | 974 | 	 | 
 | 975 | 	if (strcmp(format, "unknown") == 0) { | 
 | 976 | 		f = unknown_format; | 
 | 977 | 	} | 
 | 978 | 	else if (strcmp(format, "IEEE, little-endian") == 0) { | 
 | 979 | 		f = ieee_little_endian_format; | 
 | 980 | 	} | 
 | 981 | 	else if (strcmp(format, "IEEE, big-endian") == 0) { | 
 | 982 | 		f = ieee_big_endian_format; | 
 | 983 | 	} | 
 | 984 | 	else { | 
 | 985 | 		PyErr_SetString(PyExc_ValueError, | 
 | 986 | 				"__setformat__() argument 2 must be " | 
 | 987 | 				"'unknown', 'IEEE, little-endian' or " | 
 | 988 | 				"'IEEE, big-endian'"); | 
 | 989 | 		return NULL; | 
 | 990 |  | 
 | 991 | 	} | 
 | 992 |  | 
 | 993 | 	if (f != unknown_format && f != detected) { | 
 | 994 | 		PyErr_Format(PyExc_ValueError, | 
 | 995 | 			     "can only set %s format to 'unknown' or the " | 
 | 996 | 			     "detected platform value", typestr); | 
 | 997 | 		return NULL; | 
 | 998 | 	} | 
 | 999 |  | 
 | 1000 | 	*p = f; | 
 | 1001 | 	Py_RETURN_NONE; | 
 | 1002 | } | 
 | 1003 |  | 
 | 1004 | PyDoc_STRVAR(float_setformat_doc, | 
 | 1005 | "float.__setformat__(typestr, fmt) -> None\n" | 
 | 1006 | "\n" | 
 | 1007 | "You probably don't want to use this function.  It exists mainly to be\n" | 
 | 1008 | "used in Python's test suite.\n" | 
 | 1009 | "\n" | 
 | 1010 | "typestr must be 'double' or 'float'.  fmt must be one of 'unknown',\n" | 
 | 1011 | "'IEEE, big-endian' or 'IEEE, little-endian', and in addition can only be\n" | 
 | 1012 | "one of the latter two if it appears to match the underlying C reality.\n" | 
 | 1013 | "\n" | 
 | 1014 | "Overrides the automatic determination of C-level floating point type.\n" | 
 | 1015 | "This affects how floats are converted to and from binary strings."); | 
 | 1016 |  | 
| Guido van Rossum | 5d9113d | 2003-01-29 17:58:45 +0000 | [diff] [blame] | 1017 | static PyMethodDef float_methods[] = { | 
 | 1018 | 	{"__getnewargs__",	(PyCFunction)float_getnewargs,	METH_NOARGS}, | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1019 | 	{"__getformat__",	(PyCFunction)float_getformat,	 | 
 | 1020 | 	 METH_O|METH_CLASS,		float_getformat_doc}, | 
 | 1021 | 	{"__setformat__",	(PyCFunction)float_setformat,	 | 
 | 1022 | 	 METH_VARARGS|METH_CLASS,	float_setformat_doc}, | 
| Guido van Rossum | 5d9113d | 2003-01-29 17:58:45 +0000 | [diff] [blame] | 1023 | 	{NULL,		NULL}		/* sentinel */ | 
 | 1024 | }; | 
 | 1025 |  | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 1026 | PyDoc_STRVAR(float_doc, | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1027 | "float(x) -> floating point number\n\ | 
 | 1028 | \n\ | 
| Martin v. Löwis | 14f8b4c | 2002-06-13 20:33:02 +0000 | [diff] [blame] | 1029 | Convert a string or number to a floating point number, if possible."); | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1030 |  | 
 | 1031 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1032 | static PyNumberMethods float_as_number = { | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 1033 | 	float_add, 	/*nb_add*/ | 
 | 1034 | 	float_sub, 	/*nb_subtract*/ | 
 | 1035 | 	float_mul, 	/*nb_multiply*/ | 
 | 1036 | 	float_rem, 	/*nb_remainder*/ | 
 | 1037 | 	float_divmod, 	/*nb_divmod*/ | 
 | 1038 | 	float_pow, 	/*nb_power*/ | 
| Guido van Rossum | b6775db | 1994-08-01 11:34:53 +0000 | [diff] [blame] | 1039 | 	(unaryfunc)float_neg, /*nb_negative*/ | 
 | 1040 | 	(unaryfunc)float_pos, /*nb_positive*/ | 
 | 1041 | 	(unaryfunc)float_abs, /*nb_absolute*/ | 
| Jack Diederich | 4dafcc4 | 2006-11-28 19:15:13 +0000 | [diff] [blame] | 1042 | 	(inquiry)float_bool, /*nb_bool*/ | 
| Guido van Rossum | 27acb33 | 1991-10-24 14:55:28 +0000 | [diff] [blame] | 1043 | 	0,		/*nb_invert*/ | 
 | 1044 | 	0,		/*nb_lshift*/ | 
 | 1045 | 	0,		/*nb_rshift*/ | 
 | 1046 | 	0,		/*nb_and*/ | 
 | 1047 | 	0,		/*nb_xor*/ | 
 | 1048 | 	0,		/*nb_or*/ | 
| Neal Norwitz | 4886cc3 | 2006-08-21 17:06:07 +0000 | [diff] [blame] | 1049 | 	(coercion)0,	/*nb_coerce*/ | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 1050 | 	float_int, 	/*nb_int*/ | 
 | 1051 | 	float_long, 	/*nb_long*/ | 
 | 1052 | 	float_float,	/*nb_float*/ | 
| Guido van Rossum | 4668b00 | 2001-08-08 05:00:18 +0000 | [diff] [blame] | 1053 | 	0,		/* nb_oct */ | 
 | 1054 | 	0,		/* nb_hex */ | 
 | 1055 | 	0,		/* nb_inplace_add */ | 
 | 1056 | 	0,		/* nb_inplace_subtract */ | 
 | 1057 | 	0,		/* nb_inplace_multiply */ | 
| Guido van Rossum | 4668b00 | 2001-08-08 05:00:18 +0000 | [diff] [blame] | 1058 | 	0,		/* nb_inplace_remainder */ | 
 | 1059 | 	0, 		/* nb_inplace_power */ | 
 | 1060 | 	0,		/* nb_inplace_lshift */ | 
 | 1061 | 	0,		/* nb_inplace_rshift */ | 
 | 1062 | 	0,		/* nb_inplace_and */ | 
 | 1063 | 	0,		/* nb_inplace_xor */ | 
 | 1064 | 	0,		/* nb_inplace_or */ | 
| Tim Peters | 63a3571 | 2001-12-11 19:57:24 +0000 | [diff] [blame] | 1065 | 	float_floor_div, /* nb_floor_divide */ | 
| Guido van Rossum | 4668b00 | 2001-08-08 05:00:18 +0000 | [diff] [blame] | 1066 | 	float_div,	/* nb_true_divide */ | 
 | 1067 | 	0,		/* nb_inplace_floor_divide */ | 
 | 1068 | 	0,		/* nb_inplace_true_divide */ | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 1069 | }; | 
 | 1070 |  | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1071 | PyTypeObject PyFloat_Type = { | 
 | 1072 | 	PyObject_HEAD_INIT(&PyType_Type) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 1073 | 	0, | 
 | 1074 | 	"float", | 
| Guido van Rossum | c0b618a | 1997-05-02 03:12:38 +0000 | [diff] [blame] | 1075 | 	sizeof(PyFloatObject), | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 1076 | 	0, | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1077 | 	(destructor)float_dealloc,		/* tp_dealloc */ | 
 | 1078 | 	(printfunc)float_print, 		/* tp_print */ | 
 | 1079 | 	0,					/* tp_getattr */ | 
 | 1080 | 	0,					/* tp_setattr */ | 
| Michael W. Hudson | 08678a1 | 2004-05-26 17:36:12 +0000 | [diff] [blame] | 1081 | 	0,			 		/* tp_compare */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1082 | 	(reprfunc)float_repr,			/* tp_repr */ | 
 | 1083 | 	&float_as_number,			/* tp_as_number */ | 
 | 1084 | 	0,					/* tp_as_sequence */ | 
 | 1085 | 	0,					/* tp_as_mapping */ | 
 | 1086 | 	(hashfunc)float_hash,			/* tp_hash */ | 
 | 1087 | 	0,					/* tp_call */ | 
 | 1088 | 	(reprfunc)float_str,			/* tp_str */ | 
 | 1089 | 	PyObject_GenericGetAttr,		/* tp_getattro */ | 
 | 1090 | 	0,					/* tp_setattro */ | 
 | 1091 | 	0,					/* tp_as_buffer */ | 
| Guido van Rossum | 3cf5b1e | 2006-07-27 21:53:35 +0000 | [diff] [blame] | 1092 | 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1093 | 	float_doc,				/* tp_doc */ | 
 | 1094 |  	0,					/* tp_traverse */ | 
 | 1095 | 	0,					/* tp_clear */ | 
| Thomas Wouters | 49fd7fa | 2006-04-21 10:40:58 +0000 | [diff] [blame] | 1096 | 	float_richcompare,			/* tp_richcompare */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1097 | 	0,					/* tp_weaklistoffset */ | 
 | 1098 | 	0,					/* tp_iter */ | 
 | 1099 | 	0,					/* tp_iternext */ | 
| Guido van Rossum | 5d9113d | 2003-01-29 17:58:45 +0000 | [diff] [blame] | 1100 | 	float_methods,				/* tp_methods */ | 
| Tim Peters | 6d6c1a3 | 2001-08-02 04:15:00 +0000 | [diff] [blame] | 1101 | 	0,					/* tp_members */ | 
 | 1102 | 	0,					/* tp_getset */ | 
 | 1103 | 	0,					/* tp_base */ | 
 | 1104 | 	0,					/* tp_dict */ | 
 | 1105 | 	0,					/* tp_descr_get */ | 
 | 1106 | 	0,					/* tp_descr_set */ | 
 | 1107 | 	0,					/* tp_dictoffset */ | 
 | 1108 | 	0,					/* tp_init */ | 
 | 1109 | 	0,					/* tp_alloc */ | 
 | 1110 | 	float_new,				/* tp_new */ | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 1111 | }; | 
| Guido van Rossum | fbbd57e | 1997-08-05 02:16:08 +0000 | [diff] [blame] | 1112 |  | 
 | 1113 | void | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1114 | _PyFloat_Init(void) | 
 | 1115 | { | 
 | 1116 | 	/* We attempt to determine if this machine is using IEEE | 
 | 1117 | 	   floating point formats by peering at the bits of some | 
 | 1118 | 	   carefully chosen values.  If it looks like we are on an | 
 | 1119 | 	   IEEE platform, the float packing/unpacking routines can | 
 | 1120 | 	   just copy bits, if not they resort to arithmetic & shifts | 
 | 1121 | 	   and masks.  The shifts & masks approach works on all finite | 
 | 1122 | 	   values, but what happens to infinities, NaNs and signed | 
 | 1123 | 	   zeroes on packing is an accident, and attempting to unpack | 
 | 1124 | 	   a NaN or an infinity will raise an exception. | 
 | 1125 |  | 
 | 1126 | 	   Note that if we're on some whacked-out platform which uses | 
 | 1127 | 	   IEEE formats but isn't strictly little-endian or big- | 
 | 1128 | 	   endian, we will fall back to the portable shifts & masks | 
 | 1129 | 	   method. */ | 
 | 1130 |  | 
 | 1131 | #if SIZEOF_DOUBLE == 8 | 
 | 1132 | 	{ | 
 | 1133 | 		double x = 9006104071832581.0; | 
 | 1134 | 		if (memcmp(&x, "\x43\x3f\xff\x01\x02\x03\x04\x05", 8) == 0) | 
 | 1135 | 			detected_double_format = ieee_big_endian_format; | 
 | 1136 | 		else if (memcmp(&x, "\x05\x04\x03\x02\x01\xff\x3f\x43", 8) == 0) | 
 | 1137 | 			detected_double_format = ieee_little_endian_format; | 
 | 1138 | 		else  | 
 | 1139 | 			detected_double_format = unknown_format; | 
 | 1140 | 	} | 
 | 1141 | #else | 
 | 1142 | 	detected_double_format = unknown_format; | 
 | 1143 | #endif | 
 | 1144 |  | 
 | 1145 | #if SIZEOF_FLOAT == 4 | 
 | 1146 | 	{ | 
 | 1147 | 		float y = 16711938.0; | 
 | 1148 | 		if (memcmp(&y, "\x4b\x7f\x01\x02", 4) == 0) | 
 | 1149 | 			detected_float_format = ieee_big_endian_format; | 
 | 1150 | 		else if (memcmp(&y, "\x02\x01\x7f\x4b", 4) == 0) | 
 | 1151 | 			detected_float_format = ieee_little_endian_format; | 
 | 1152 | 		else  | 
 | 1153 | 			detected_float_format = unknown_format; | 
 | 1154 | 	} | 
 | 1155 | #else | 
 | 1156 | 	detected_float_format = unknown_format; | 
 | 1157 | #endif | 
 | 1158 |  | 
 | 1159 | 	double_format = detected_double_format; | 
 | 1160 | 	float_format = detected_float_format; | 
 | 1161 | } | 
 | 1162 |  | 
 | 1163 | void | 
| Fred Drake | fd99de6 | 2000-07-09 05:02:18 +0000 | [diff] [blame] | 1164 | PyFloat_Fini(void) | 
| Guido van Rossum | fbbd57e | 1997-08-05 02:16:08 +0000 | [diff] [blame] | 1165 | { | 
| Guido van Rossum | 3fce883 | 1999-03-12 19:43:17 +0000 | [diff] [blame] | 1166 | 	PyFloatObject *p; | 
 | 1167 | 	PyFloatBlock *list, *next; | 
| Neal Norwitz | 739a8f8 | 2004-07-08 01:55:58 +0000 | [diff] [blame] | 1168 | 	unsigned i; | 
| Guido van Rossum | f61bbc8 | 1999-03-12 00:12:21 +0000 | [diff] [blame] | 1169 | 	int bc, bf;	/* block count, number of freed blocks */ | 
 | 1170 | 	int frem, fsum;	/* remaining unfreed floats per block, total */ | 
 | 1171 |  | 
 | 1172 | 	bc = 0; | 
 | 1173 | 	bf = 0; | 
 | 1174 | 	fsum = 0; | 
 | 1175 | 	list = block_list; | 
 | 1176 | 	block_list = NULL; | 
| Guido van Rossum | d7b5fb8 | 1999-03-19 20:59:40 +0000 | [diff] [blame] | 1177 | 	free_list = NULL; | 
| Guido van Rossum | f61bbc8 | 1999-03-12 00:12:21 +0000 | [diff] [blame] | 1178 | 	while (list != NULL) { | 
| Guido van Rossum | f61bbc8 | 1999-03-12 00:12:21 +0000 | [diff] [blame] | 1179 | 		bc++; | 
 | 1180 | 		frem = 0; | 
| Guido van Rossum | d7b5fb8 | 1999-03-19 20:59:40 +0000 | [diff] [blame] | 1181 | 		for (i = 0, p = &list->objects[0]; | 
 | 1182 | 		     i < N_FLOATOBJECTS; | 
 | 1183 | 		     i++, p++) { | 
| Guido van Rossum | dea6ef9 | 2001-09-11 16:13:52 +0000 | [diff] [blame] | 1184 | 			if (PyFloat_CheckExact(p) && p->ob_refcnt != 0) | 
| Guido van Rossum | f61bbc8 | 1999-03-12 00:12:21 +0000 | [diff] [blame] | 1185 | 				frem++; | 
 | 1186 | 		} | 
| Guido van Rossum | 3fce883 | 1999-03-12 19:43:17 +0000 | [diff] [blame] | 1187 | 		next = list->next; | 
| Guido van Rossum | f61bbc8 | 1999-03-12 00:12:21 +0000 | [diff] [blame] | 1188 | 		if (frem) { | 
| Guido van Rossum | 3fce883 | 1999-03-12 19:43:17 +0000 | [diff] [blame] | 1189 | 			list->next = block_list; | 
 | 1190 | 			block_list = list; | 
| Guido van Rossum | d7b5fb8 | 1999-03-19 20:59:40 +0000 | [diff] [blame] | 1191 | 			for (i = 0, p = &list->objects[0]; | 
 | 1192 | 			     i < N_FLOATOBJECTS; | 
 | 1193 | 			     i++, p++) { | 
| Guido van Rossum | dea6ef9 | 2001-09-11 16:13:52 +0000 | [diff] [blame] | 1194 | 				if (!PyFloat_CheckExact(p) || | 
| Guido van Rossum | bef1417 | 2001-08-29 15:47:46 +0000 | [diff] [blame] | 1195 | 				    p->ob_refcnt == 0) { | 
| Guido van Rossum | d7b5fb8 | 1999-03-19 20:59:40 +0000 | [diff] [blame] | 1196 | 					p->ob_type = (struct _typeobject *) | 
 | 1197 | 						free_list; | 
 | 1198 | 					free_list = p; | 
 | 1199 | 				} | 
 | 1200 | 			} | 
| Guido van Rossum | f61bbc8 | 1999-03-12 00:12:21 +0000 | [diff] [blame] | 1201 | 		} | 
 | 1202 | 		else { | 
| Guido van Rossum | b18618d | 2000-05-03 23:44:39 +0000 | [diff] [blame] | 1203 | 			PyMem_FREE(list); /* XXX PyObject_FREE ??? */ | 
| Guido van Rossum | f61bbc8 | 1999-03-12 00:12:21 +0000 | [diff] [blame] | 1204 | 			bf++; | 
 | 1205 | 		} | 
 | 1206 | 		fsum += frem; | 
| Guido van Rossum | 3fce883 | 1999-03-12 19:43:17 +0000 | [diff] [blame] | 1207 | 		list = next; | 
| Guido van Rossum | f61bbc8 | 1999-03-12 00:12:21 +0000 | [diff] [blame] | 1208 | 	} | 
| Guido van Rossum | 3fce883 | 1999-03-12 19:43:17 +0000 | [diff] [blame] | 1209 | 	if (!Py_VerboseFlag) | 
 | 1210 | 		return; | 
 | 1211 | 	fprintf(stderr, "# cleanup floats"); | 
 | 1212 | 	if (!fsum) { | 
 | 1213 | 		fprintf(stderr, "\n"); | 
 | 1214 | 	} | 
 | 1215 | 	else { | 
 | 1216 | 		fprintf(stderr, | 
 | 1217 | 			": %d unfreed float%s in %d out of %d block%s\n", | 
 | 1218 | 			fsum, fsum == 1 ? "" : "s", | 
 | 1219 | 			bc - bf, bc, bc == 1 ? "" : "s"); | 
 | 1220 | 	} | 
 | 1221 | 	if (Py_VerboseFlag > 1) { | 
 | 1222 | 		list = block_list; | 
 | 1223 | 		while (list != NULL) { | 
| Guido van Rossum | d7b5fb8 | 1999-03-19 20:59:40 +0000 | [diff] [blame] | 1224 | 			for (i = 0, p = &list->objects[0]; | 
 | 1225 | 			     i < N_FLOATOBJECTS; | 
 | 1226 | 			     i++, p++) { | 
| Guido van Rossum | dea6ef9 | 2001-09-11 16:13:52 +0000 | [diff] [blame] | 1227 | 				if (PyFloat_CheckExact(p) && | 
| Guido van Rossum | bef1417 | 2001-08-29 15:47:46 +0000 | [diff] [blame] | 1228 | 				    p->ob_refcnt != 0) { | 
| Guido van Rossum | 3fce883 | 1999-03-12 19:43:17 +0000 | [diff] [blame] | 1229 | 					char buf[100]; | 
| Neal Norwitz | 545686b | 2006-12-28 04:45:06 +0000 | [diff] [blame] | 1230 | 					format_float(buf, sizeof(buf), p, PREC_STR); | 
| Thomas Wouters | 8b87a0b | 2006-03-01 05:41:20 +0000 | [diff] [blame] | 1231 | 					/* XXX(twouters) cast refcount to | 
 | 1232 | 					   long until %zd is universally | 
 | 1233 | 					   available | 
 | 1234 | 					 */ | 
| Guido van Rossum | 3fce883 | 1999-03-12 19:43:17 +0000 | [diff] [blame] | 1235 | 					fprintf(stderr, | 
| Thomas Wouters | 8b87a0b | 2006-03-01 05:41:20 +0000 | [diff] [blame] | 1236 | 			     "#   <float at %p, refcnt=%ld, val=%s>\n", | 
 | 1237 | 						p, (long)p->ob_refcnt, buf); | 
| Guido van Rossum | 3fce883 | 1999-03-12 19:43:17 +0000 | [diff] [blame] | 1238 | 				} | 
 | 1239 | 			} | 
 | 1240 | 			list = list->next; | 
| Guido van Rossum | f61bbc8 | 1999-03-12 00:12:21 +0000 | [diff] [blame] | 1241 | 		} | 
 | 1242 | 	} | 
| Guido van Rossum | fbbd57e | 1997-08-05 02:16:08 +0000 | [diff] [blame] | 1243 | } | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1244 |  | 
 | 1245 | /*---------------------------------------------------------------------------- | 
 | 1246 |  * _PyFloat_{Pack,Unpack}{4,8}.  See floatobject.h. | 
 | 1247 |  * | 
 | 1248 |  * TODO:  On platforms that use the standard IEEE-754 single and double | 
 | 1249 |  * formats natively, these routines could simply copy the bytes. | 
 | 1250 |  */ | 
 | 1251 | int | 
 | 1252 | _PyFloat_Pack4(double x, unsigned char *p, int le) | 
 | 1253 | { | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1254 | 	if (float_format == unknown_format) { | 
 | 1255 | 		unsigned char sign; | 
 | 1256 | 		int e; | 
 | 1257 | 		double f; | 
 | 1258 | 		unsigned int fbits; | 
 | 1259 | 		int incr = 1; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1260 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1261 | 		if (le) { | 
 | 1262 | 			p += 3; | 
 | 1263 | 			incr = -1; | 
 | 1264 | 		} | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1265 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1266 | 		if (x < 0) { | 
 | 1267 | 			sign = 1; | 
 | 1268 | 			x = -x; | 
 | 1269 | 		} | 
 | 1270 | 		else | 
 | 1271 | 			sign = 0; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1272 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1273 | 		f = frexp(x, &e); | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1274 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1275 | 		/* Normalize f to be in the range [1.0, 2.0) */ | 
 | 1276 | 		if (0.5 <= f && f < 1.0) { | 
 | 1277 | 			f *= 2.0; | 
 | 1278 | 			e--; | 
 | 1279 | 		} | 
 | 1280 | 		else if (f == 0.0) | 
 | 1281 | 			e = 0; | 
 | 1282 | 		else { | 
 | 1283 | 			PyErr_SetString(PyExc_SystemError, | 
 | 1284 | 					"frexp() result out of range"); | 
 | 1285 | 			return -1; | 
 | 1286 | 		} | 
 | 1287 |  | 
 | 1288 | 		if (e >= 128) | 
 | 1289 | 			goto Overflow; | 
 | 1290 | 		else if (e < -126) { | 
 | 1291 | 			/* Gradual underflow */ | 
 | 1292 | 			f = ldexp(f, 126 + e); | 
 | 1293 | 			e = 0; | 
 | 1294 | 		} | 
 | 1295 | 		else if (!(e == 0 && f == 0.0)) { | 
 | 1296 | 			e += 127; | 
 | 1297 | 			f -= 1.0; /* Get rid of leading 1 */ | 
 | 1298 | 		} | 
 | 1299 |  | 
 | 1300 | 		f *= 8388608.0; /* 2**23 */ | 
 | 1301 | 		fbits = (unsigned int)(f + 0.5); /* Round */ | 
 | 1302 | 		assert(fbits <= 8388608); | 
 | 1303 | 		if (fbits >> 23) { | 
 | 1304 | 			/* The carry propagated out of a string of 23 1 bits. */ | 
 | 1305 | 			fbits = 0; | 
 | 1306 | 			++e; | 
 | 1307 | 			if (e >= 255) | 
 | 1308 | 				goto Overflow; | 
 | 1309 | 		} | 
 | 1310 |  | 
 | 1311 | 		/* First byte */ | 
 | 1312 | 		*p = (sign << 7) | (e >> 1); | 
 | 1313 | 		p += incr; | 
 | 1314 |  | 
 | 1315 | 		/* Second byte */ | 
 | 1316 | 		*p = (char) (((e & 1) << 7) | (fbits >> 16)); | 
 | 1317 | 		p += incr; | 
 | 1318 |  | 
 | 1319 | 		/* Third byte */ | 
 | 1320 | 		*p = (fbits >> 8) & 0xFF; | 
 | 1321 | 		p += incr; | 
 | 1322 |  | 
 | 1323 | 		/* Fourth byte */ | 
 | 1324 | 		*p = fbits & 0xFF; | 
 | 1325 |  | 
 | 1326 | 		/* Done */ | 
 | 1327 | 		return 0; | 
 | 1328 |  | 
 | 1329 | 	  Overflow: | 
 | 1330 | 		PyErr_SetString(PyExc_OverflowError, | 
 | 1331 | 				"float too large to pack with f format"); | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1332 | 		return -1; | 
 | 1333 | 	} | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1334 | 	else { | 
| Michael W. Hudson | 3095ad0 | 2005-06-30 00:02:26 +0000 | [diff] [blame] | 1335 | 		float y = (float)x; | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1336 | 		const char *s = (char*)&y; | 
 | 1337 | 		int i, incr = 1; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1338 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1339 | 		if ((float_format == ieee_little_endian_format && !le) | 
 | 1340 | 		    || (float_format == ieee_big_endian_format && le)) { | 
 | 1341 | 			p += 3; | 
 | 1342 | 			incr = -1; | 
 | 1343 | 		} | 
 | 1344 | 		 | 
 | 1345 | 		for (i = 0; i < 4; i++) { | 
 | 1346 | 			*p = *s++; | 
 | 1347 | 			p += incr; | 
 | 1348 | 		} | 
 | 1349 | 		return 0; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1350 | 	} | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1351 | } | 
 | 1352 |  | 
 | 1353 | int | 
 | 1354 | _PyFloat_Pack8(double x, unsigned char *p, int le) | 
 | 1355 | { | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1356 | 	if (double_format == unknown_format) { | 
 | 1357 | 		unsigned char sign; | 
 | 1358 | 		int e; | 
 | 1359 | 		double f; | 
 | 1360 | 		unsigned int fhi, flo; | 
 | 1361 | 		int incr = 1; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1362 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1363 | 		if (le) { | 
 | 1364 | 			p += 7; | 
 | 1365 | 			incr = -1; | 
 | 1366 | 		} | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1367 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1368 | 		if (x < 0) { | 
 | 1369 | 			sign = 1; | 
 | 1370 | 			x = -x; | 
 | 1371 | 		} | 
 | 1372 | 		else | 
 | 1373 | 			sign = 0; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1374 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1375 | 		f = frexp(x, &e); | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1376 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1377 | 		/* Normalize f to be in the range [1.0, 2.0) */ | 
 | 1378 | 		if (0.5 <= f && f < 1.0) { | 
 | 1379 | 			f *= 2.0; | 
 | 1380 | 			e--; | 
 | 1381 | 		} | 
 | 1382 | 		else if (f == 0.0) | 
 | 1383 | 			e = 0; | 
 | 1384 | 		else { | 
 | 1385 | 			PyErr_SetString(PyExc_SystemError, | 
 | 1386 | 					"frexp() result out of range"); | 
 | 1387 | 			return -1; | 
 | 1388 | 		} | 
 | 1389 |  | 
 | 1390 | 		if (e >= 1024) | 
 | 1391 | 			goto Overflow; | 
 | 1392 | 		else if (e < -1022) { | 
 | 1393 | 			/* Gradual underflow */ | 
 | 1394 | 			f = ldexp(f, 1022 + e); | 
 | 1395 | 			e = 0; | 
 | 1396 | 		} | 
 | 1397 | 		else if (!(e == 0 && f == 0.0)) { | 
 | 1398 | 			e += 1023; | 
 | 1399 | 			f -= 1.0; /* Get rid of leading 1 */ | 
 | 1400 | 		} | 
 | 1401 |  | 
 | 1402 | 		/* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */ | 
 | 1403 | 		f *= 268435456.0; /* 2**28 */ | 
 | 1404 | 		fhi = (unsigned int)f; /* Truncate */ | 
 | 1405 | 		assert(fhi < 268435456); | 
 | 1406 |  | 
 | 1407 | 		f -= (double)fhi; | 
 | 1408 | 		f *= 16777216.0; /* 2**24 */ | 
 | 1409 | 		flo = (unsigned int)(f + 0.5); /* Round */ | 
 | 1410 | 		assert(flo <= 16777216); | 
 | 1411 | 		if (flo >> 24) { | 
 | 1412 | 			/* The carry propagated out of a string of 24 1 bits. */ | 
 | 1413 | 			flo = 0; | 
 | 1414 | 			++fhi; | 
 | 1415 | 			if (fhi >> 28) { | 
 | 1416 | 				/* And it also progagated out of the next 28 bits. */ | 
 | 1417 | 				fhi = 0; | 
 | 1418 | 				++e; | 
 | 1419 | 				if (e >= 2047) | 
 | 1420 | 					goto Overflow; | 
 | 1421 | 			} | 
 | 1422 | 		} | 
 | 1423 |  | 
 | 1424 | 		/* First byte */ | 
 | 1425 | 		*p = (sign << 7) | (e >> 4); | 
 | 1426 | 		p += incr; | 
 | 1427 |  | 
 | 1428 | 		/* Second byte */ | 
 | 1429 | 		*p = (unsigned char) (((e & 0xF) << 4) | (fhi >> 24)); | 
 | 1430 | 		p += incr; | 
 | 1431 |  | 
 | 1432 | 		/* Third byte */ | 
 | 1433 | 		*p = (fhi >> 16) & 0xFF; | 
 | 1434 | 		p += incr; | 
 | 1435 |  | 
 | 1436 | 		/* Fourth byte */ | 
 | 1437 | 		*p = (fhi >> 8) & 0xFF; | 
 | 1438 | 		p += incr; | 
 | 1439 |  | 
 | 1440 | 		/* Fifth byte */ | 
 | 1441 | 		*p = fhi & 0xFF; | 
 | 1442 | 		p += incr; | 
 | 1443 |  | 
 | 1444 | 		/* Sixth byte */ | 
 | 1445 | 		*p = (flo >> 16) & 0xFF; | 
 | 1446 | 		p += incr; | 
 | 1447 |  | 
 | 1448 | 		/* Seventh byte */ | 
 | 1449 | 		*p = (flo >> 8) & 0xFF; | 
 | 1450 | 		p += incr; | 
 | 1451 |  | 
 | 1452 | 		/* Eighth byte */ | 
 | 1453 | 		*p = flo & 0xFF; | 
 | 1454 | 		p += incr; | 
 | 1455 |  | 
 | 1456 | 		/* Done */ | 
 | 1457 | 		return 0; | 
 | 1458 |  | 
 | 1459 | 	  Overflow: | 
 | 1460 | 		PyErr_SetString(PyExc_OverflowError, | 
 | 1461 | 				"float too large to pack with d format"); | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1462 | 		return -1; | 
 | 1463 | 	} | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1464 | 	else { | 
 | 1465 | 		const char *s = (char*)&x; | 
 | 1466 | 		int i, incr = 1; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1467 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1468 | 		if ((double_format == ieee_little_endian_format && !le) | 
 | 1469 | 		    || (double_format == ieee_big_endian_format && le)) { | 
 | 1470 | 			p += 7; | 
 | 1471 | 			incr = -1; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1472 | 		} | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1473 | 		 | 
 | 1474 | 		for (i = 0; i < 8; i++) { | 
 | 1475 | 			*p = *s++; | 
 | 1476 | 			p += incr; | 
 | 1477 | 		} | 
 | 1478 | 		return 0; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1479 | 	} | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1480 | } | 
 | 1481 |  | 
| Neal Norwitz | 545686b | 2006-12-28 04:45:06 +0000 | [diff] [blame] | 1482 | /* Should only be used by marshal. */ | 
 | 1483 | int | 
 | 1484 | _PyFloat_Repr(double x, char *p, size_t len) | 
 | 1485 | { | 
 | 1486 | 	format_double(p, len, x, PREC_REPR); | 
 | 1487 | 	return (int)strlen(p); | 
 | 1488 | } | 
 | 1489 |  | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1490 | double | 
 | 1491 | _PyFloat_Unpack4(const unsigned char *p, int le) | 
 | 1492 | { | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1493 | 	if (float_format == unknown_format) { | 
 | 1494 | 		unsigned char sign; | 
 | 1495 | 		int e; | 
 | 1496 | 		unsigned int f; | 
 | 1497 | 		double x; | 
 | 1498 | 		int incr = 1; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1499 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1500 | 		if (le) { | 
 | 1501 | 			p += 3; | 
 | 1502 | 			incr = -1; | 
 | 1503 | 		} | 
 | 1504 |  | 
 | 1505 | 		/* First byte */ | 
 | 1506 | 		sign = (*p >> 7) & 1; | 
 | 1507 | 		e = (*p & 0x7F) << 1; | 
 | 1508 | 		p += incr; | 
 | 1509 |  | 
 | 1510 | 		/* Second byte */ | 
 | 1511 | 		e |= (*p >> 7) & 1; | 
 | 1512 | 		f = (*p & 0x7F) << 16; | 
 | 1513 | 		p += incr; | 
 | 1514 |  | 
 | 1515 | 		if (e == 255) { | 
 | 1516 | 			PyErr_SetString( | 
 | 1517 | 				PyExc_ValueError, | 
 | 1518 | 				"can't unpack IEEE 754 special value " | 
 | 1519 | 				"on non-IEEE platform"); | 
 | 1520 | 			return -1; | 
 | 1521 | 		} | 
 | 1522 |  | 
 | 1523 | 		/* Third byte */ | 
 | 1524 | 		f |= *p << 8; | 
 | 1525 | 		p += incr; | 
 | 1526 |  | 
 | 1527 | 		/* Fourth byte */ | 
 | 1528 | 		f |= *p; | 
 | 1529 |  | 
 | 1530 | 		x = (double)f / 8388608.0; | 
 | 1531 |  | 
 | 1532 | 		/* XXX This sadly ignores Inf/NaN issues */ | 
 | 1533 | 		if (e == 0) | 
 | 1534 | 			e = -126; | 
 | 1535 | 		else { | 
 | 1536 | 			x += 1.0; | 
 | 1537 | 			e -= 127; | 
 | 1538 | 		} | 
 | 1539 | 		x = ldexp(x, e); | 
 | 1540 |  | 
 | 1541 | 		if (sign) | 
 | 1542 | 			x = -x; | 
 | 1543 |  | 
 | 1544 | 		return x; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1545 | 	} | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1546 | 	else { | 
| Michael W. Hudson | b78a5fc | 2005-12-05 00:27:49 +0000 | [diff] [blame] | 1547 | 		float x; | 
 | 1548 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1549 | 		if ((float_format == ieee_little_endian_format && !le) | 
 | 1550 | 		    || (float_format == ieee_big_endian_format && le)) { | 
| Michael W. Hudson | b78a5fc | 2005-12-05 00:27:49 +0000 | [diff] [blame] | 1551 | 			char buf[4]; | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1552 | 			char *d = &buf[3]; | 
 | 1553 | 			int i; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1554 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1555 | 			for (i = 0; i < 4; i++) { | 
 | 1556 | 				*d-- = *p++; | 
 | 1557 | 			} | 
| Michael W. Hudson | b78a5fc | 2005-12-05 00:27:49 +0000 | [diff] [blame] | 1558 | 			memcpy(&x, buf, 4); | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1559 | 		} | 
 | 1560 | 		else { | 
| Michael W. Hudson | b78a5fc | 2005-12-05 00:27:49 +0000 | [diff] [blame] | 1561 | 			memcpy(&x, p, 4); | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1562 | 		} | 
| Michael W. Hudson | b78a5fc | 2005-12-05 00:27:49 +0000 | [diff] [blame] | 1563 |  | 
 | 1564 | 		return x; | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1565 | 	}		 | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1566 | } | 
 | 1567 |  | 
 | 1568 | double | 
 | 1569 | _PyFloat_Unpack8(const unsigned char *p, int le) | 
 | 1570 | { | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1571 | 	if (double_format == unknown_format) { | 
 | 1572 | 		unsigned char sign; | 
 | 1573 | 		int e; | 
 | 1574 | 		unsigned int fhi, flo; | 
 | 1575 | 		double x; | 
 | 1576 | 		int incr = 1; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1577 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1578 | 		if (le) { | 
 | 1579 | 			p += 7; | 
 | 1580 | 			incr = -1; | 
 | 1581 | 		} | 
 | 1582 |  | 
 | 1583 | 		/* First byte */ | 
 | 1584 | 		sign = (*p >> 7) & 1; | 
 | 1585 | 		e = (*p & 0x7F) << 4; | 
 | 1586 | 		 | 
 | 1587 | 		p += incr; | 
 | 1588 |  | 
 | 1589 | 		/* Second byte */ | 
 | 1590 | 		e |= (*p >> 4) & 0xF; | 
 | 1591 | 		fhi = (*p & 0xF) << 24; | 
 | 1592 | 		p += incr; | 
 | 1593 |  | 
 | 1594 | 		if (e == 2047) { | 
 | 1595 | 			PyErr_SetString( | 
 | 1596 | 				PyExc_ValueError, | 
 | 1597 | 				"can't unpack IEEE 754 special value " | 
 | 1598 | 				"on non-IEEE platform"); | 
 | 1599 | 			return -1.0; | 
 | 1600 | 		} | 
 | 1601 |  | 
 | 1602 | 		/* Third byte */ | 
 | 1603 | 		fhi |= *p << 16; | 
 | 1604 | 		p += incr; | 
 | 1605 |  | 
 | 1606 | 		/* Fourth byte */ | 
 | 1607 | 		fhi |= *p  << 8; | 
 | 1608 | 		p += incr; | 
 | 1609 |  | 
 | 1610 | 		/* Fifth byte */ | 
 | 1611 | 		fhi |= *p; | 
 | 1612 | 		p += incr; | 
 | 1613 |  | 
 | 1614 | 		/* Sixth byte */ | 
 | 1615 | 		flo = *p << 16; | 
 | 1616 | 		p += incr; | 
 | 1617 |  | 
 | 1618 | 		/* Seventh byte */ | 
 | 1619 | 		flo |= *p << 8; | 
 | 1620 | 		p += incr; | 
 | 1621 |  | 
 | 1622 | 		/* Eighth byte */ | 
 | 1623 | 		flo |= *p; | 
 | 1624 |  | 
 | 1625 | 		x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */ | 
 | 1626 | 		x /= 268435456.0; /* 2**28 */ | 
 | 1627 |  | 
 | 1628 | 		if (e == 0) | 
 | 1629 | 			e = -1022; | 
 | 1630 | 		else { | 
 | 1631 | 			x += 1.0; | 
 | 1632 | 			e -= 1023; | 
 | 1633 | 		} | 
 | 1634 | 		x = ldexp(x, e); | 
 | 1635 |  | 
 | 1636 | 		if (sign) | 
 | 1637 | 			x = -x; | 
 | 1638 |  | 
 | 1639 | 		return x; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1640 | 	} | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1641 | 	else { | 
| Michael W. Hudson | b78a5fc | 2005-12-05 00:27:49 +0000 | [diff] [blame] | 1642 | 		double x; | 
 | 1643 |  | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1644 | 		if ((double_format == ieee_little_endian_format && !le) | 
 | 1645 | 		    || (double_format == ieee_big_endian_format && le)) { | 
 | 1646 | 			char buf[8]; | 
 | 1647 | 			char *d = &buf[7]; | 
 | 1648 | 			int i; | 
 | 1649 | 			 | 
 | 1650 | 			for (i = 0; i < 8; i++) { | 
 | 1651 | 				*d-- = *p++; | 
 | 1652 | 			} | 
| Michael W. Hudson | b78a5fc | 2005-12-05 00:27:49 +0000 | [diff] [blame] | 1653 | 			memcpy(&x, buf, 8); | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1654 | 		} | 
 | 1655 | 		else { | 
| Michael W. Hudson | b78a5fc | 2005-12-05 00:27:49 +0000 | [diff] [blame] | 1656 | 			memcpy(&x, p, 8); | 
| Michael W. Hudson | ba283e2 | 2005-05-27 15:23:20 +0000 | [diff] [blame] | 1657 | 		} | 
| Michael W. Hudson | b78a5fc | 2005-12-05 00:27:49 +0000 | [diff] [blame] | 1658 |  | 
 | 1659 | 		return x; | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1660 | 	} | 
| Tim Peters | 9905b94 | 2003-03-20 20:53:32 +0000 | [diff] [blame] | 1661 | } |