diff options
Diffstat (limited to 'Objects/floatobject.c')
| -rw-r--r-- | Objects/floatobject.c | 52 | 
1 files changed, 50 insertions, 2 deletions
| diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 48d29d7042..c876c74063 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -114,7 +114,7 @@ PyFloat_FromDouble(double fval)  PyObject *  PyFloat_FromString(PyObject *v)  { -	const char *s, *last, *end; +	const char *s, *last, *end, *sp;  	double x;  	char buffer[256]; /* for errors */  	char *s_buffer = NULL; @@ -146,6 +146,7 @@ PyFloat_FromString(PyObject *v)  		PyErr_SetString(PyExc_ValueError, "empty string for float()");  		goto error;  	} +	sp = s;  	/* We don't care about overflow or underflow.  If the platform supports  	 * them, infinities and signed zeroes (on underflow) are fine.  	 * However, strtod can return 0 for denormalized numbers, where atof @@ -161,7 +162,26 @@ PyFloat_FromString(PyObject *v)  	   byte at the end of the string, when the input is inf(inity). */  	if (end > last)  		end = last; +	/* Check for inf and nan. This is done late because it rarely happens. */  	if (end == s) { +		char *p = (char*)sp; +		int sign = 1; + +		if (*p == '-') { +			sign = -1; +			p++; +		} +		if (*p == '+') { +			p++; +		} +		if (PyOS_strnicmp(p, "inf", 4) == 0) { +			return PyFloat_FromDouble(sign * Py_HUGE_VAL); +		} +#ifdef Py_NAN +		if(PyOS_strnicmp(p, "nan", 4) == 0) { +			return PyFloat_FromDouble(Py_NAN); +		} +#endif  		PyOS_snprintf(buffer, sizeof(buffer),  			      "invalid literal for float(): %.200s", s);  		PyErr_SetString(PyExc_ValueError, buffer); @@ -250,7 +270,9 @@ format_double(char *buf, size_t buflen, double ob_fval, int precision)  {  	register char *cp;  	char format[32]; -	/* Subroutine for float_repr, float_str, and others. +	int i; + +	/* Subroutine for float_repr, float_str and float_print.  	   We want float numbers to be recognizable as such,  	   i.e., they should contain a decimal point or an exponent.  	   However, %g may print the number as an integer; @@ -271,7 +293,33 @@ format_double(char *buf, size_t buflen, double ob_fval, int precision)  		*cp++ = '.';  		*cp++ = '0';  		*cp++ = '\0'; +		return;  	} +	/* Checking the next three chars should be more than enough to +	 * detect inf or nan, even on Windows. We check for inf or nan +	 * at last because they are rare cases. +	 */ +	for (i=0; *cp != '\0' && i<3; cp++, i++) { +		if (isdigit(Py_CHARMASK(*cp)) || *cp == '.') +			continue; +		/* found something that is neither a digit nor point +		 * it might be a NaN or INF +		 */ +#ifdef Py_NAN +		if (Py_IS_NAN(ob_fval)) { +			strcpy(buf, "nan"); +		} +                else +#endif +		if (Py_IS_INFINITY(ob_fval)) { +			cp = buf; +			if (*cp == '-') +				cp++; +			strcpy(cp, "inf"); +		} +		break; +	} +  }  static void | 
