tipos numeros letras imprimir entrada datos convertir concatenar python python-2.7 python-3.x floating-point-conversion

numeros - ¿Por qué str(float) devuelve más dígitos en Python 3 que Python 2?



string en python (1)

No, no hay PEP. Hay un bugs.python.org/issue9337 en el rastreador de errores y una discusión asociada en la lista de correo de desarrolladores de Python. Si bien fui responsable de proponer e implementar el cambio, no puedo afirmar que fue mi idea: surgió durante las conversaciones con Guido en EuroPython 2010.

Algunos detalles más: como ya se mencionó en los comentarios, Python 3.1 introdujo un nuevo algoritmo para la repr de la cadena de un flotador (más tarde se introdujo en la serie Python 2, por lo que también aparece en Python 2.7). Como resultado de este nuevo algoritmo, un número decimal "corto" escrito en el indicador tiene una representación correspondientemente corta. Esto eliminó una de las razones existentes para la diferencia entre str y repr , y permitió utilizar el mismo algoritmo para str y repr . Entonces, para Python 3.2, siguiendo la discusión vinculada a lo anterior, str y repr se hicieron idénticos. En cuanto a por qué: hace que el lenguaje sea un poco más pequeño y limpio, y elimina la elección bastante arbitraria de 12 dígitos al generar la cadena. (La elección de 17 dígitos utilizados para la repr en versiones de Python anteriores a 2.7 está lejos de ser arbitraria, por cierto: dos flotadores binarios IEEE 754 distintos tendrán representaciones distintas cuando se conviertan a decimal con 17 dígitos significativos, y 17 es el entero más pequeño con esta propiedad)

Además de la simplicidad, hay algunos beneficios menos obvios. Un aspecto de la distinción repr versus str que ha sido confuso para los usuarios en el pasado es el hecho de que repr se usa automáticamente en contenedores. Entonces, por ejemplo, en Python 2.7:

>>> x = 1.4 * 1.5 >>> print x 2.1 >>> print [x] [2.0999999999999996]

Estoy seguro de que hay al menos una pregunta de StackOverflow sobre este fenómeno en alguna parte: aquí hay una , y another más reciente. Con la simplificación introducida en Python 3.2, obtenemos esto en su lugar:

>>> x = 1.4 * 1.5 >>> print(x) 2.0999999999999996 >>> print([x]) [2.0999999999999996]

que es al menos más consistente.

Si desea poder ocultar imprecisiones, la forma correcta de hacerlo sigue siendo la misma: utilice el formato de cadena para un control preciso del formato de salida.

>>> print("{:.12g}".format(x)) 2.1

Espero que eso explique algunos de los razonamientos detrás del cambio. No voy a argumentar que es universalmente beneficioso: como usted señala, el viejo str tenía el conveniente efecto secundario de ocultar imprecisiones. Pero en mi opinión (por supuesto, soy parcial), ayuda a eliminar algunas sorpresas del lenguaje.

En Python 2.7, la repr de un float devuelve el número decimal más cercano de hasta 17 dígitos de largo; Esto es lo suficientemente preciso como para identificar de forma exclusiva cada valor de punto flotante IEEE posible. str de un float funcionó de manera similar, excepto que limitó el resultado a 12 dígitos; Para la mayoría de los propósitos, este es un resultado más razonable y lo aísla de las pequeñas diferencias entre la representación binaria y decimal.

Demostración de Python 2: http://ideone.com/OKJtxv

print str(1.4*1.5) 2.1 print repr(1.4*1.5) 2.0999999999999996

En Python 3.2 aparece str y repr devuelven lo mismo.

Demostración de Python 3: http://ideone.com/oAKRsb

print(str(1.4*1.5)) 2.0999999999999996 print(repr(1.4*1.5)) 2.0999999999999996

¿Existe una PEP que describa el cambio o alguna otra declaración de alguien responsable?