Convertir un flotador en una cuerda sin redondearlo

88

Estoy creando un programa que, por razones que no es necesario explicar, requiere que un flotante se convierta en una cadena que se cuente con len (). Sin embargo, str (float (x)) da como resultado que x se redondee cuando se convierte en una cadena, lo que desecha todo. ¿Alguien sabe de una solución? Aquí está el código que se está utilizando si quiere saberlo:

len(str(float(x)/3))
Galileo
fuente
2
si x es originalmente str, ¿por qué el elenco?
Vinko Vrsalovic
1
-1: No hay ejemplos de la salida requerida para diferentes valores de x. Sin ejemplos, solo podemos adivinar cuál es el problema.
S.Lott

Respuestas:

128

Alguna forma de redondeo es a menudo inevitable cuando se trata de números de coma flotante. Esto se debe a que los números que puede expresar exactamente en base 10 no siempre se pueden expresar exactamente en base 2 (que usa su computadora).

Por ejemplo:

>>> .1
0.10000000000000001

En este caso, está viendo .1 convertido a una cadena usando repr:

>>> repr(.1)
'0.10000000000000001'

Creo que Python corta los últimos dígitos cuando usa str () para solucionar este problema, pero es una solución parcial que no sustituye a la comprensión de lo que está sucediendo.

>>> str(.1)
'0.1'

No estoy seguro de qué problemas le está causando el "redondeo". ¿Quizás le iría mejor con el formato de cadena como una forma de controlar con mayor precisión su salida?

p.ej

>>> '%.5f' % .1
'0.10000'
>>> '%.5f' % .12345678
'0.12346'

Documentación aquí .

John Fouhy
fuente
12
len(repr(float(x)/3))

Sin embargo, debo decir que esto no es tan confiable como crees.

Los flotantes se ingresan / muestran como números decimales, pero su computadora (de hecho, su biblioteca C estándar) los almacena como binarios. Obtienes algunos efectos secundarios de esta transición:

>>> print len(repr(0.1))
19
>>> print repr(0.1)
0.10000000000000001

La explicación de por qué sucede esto se encuentra en este capítulo del tutorial de Python.

Una solución sería usar un tipo que rastree específicamente números decimales, como Python decimal.Decimal:

>>> print len(str(decimal.Decimal('0.1')))
3
nosklo
fuente
Buena publicación sobre cómo trabajar con resultados flotantes de la división: stackoverflow.com/questions/2958684/python-division
Trutane
3

Otras respuestas ya señalaron que la representación de números flotantes es un tema espinoso, por decir lo menos.

Como no da suficiente contexto en su pregunta, no puedo saber si el módulo decimal puede ser útil para sus necesidades:

http://docs.python.org/library/decimal.html

Entre otras cosas, puede especificar explícitamente la precisión que desea obtener (de los documentos):

>>> getcontext().prec = 6
>>> Decimal('3.0')
Decimal('3.0')
>>> Decimal('3.1415926535')
Decimal('3.1415926535')
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85987')
>>> getcontext().rounding = ROUND_UP
>>> Decimal('3.1415926535') + Decimal('2.7182818285')
Decimal('5.85988')

Un ejemplo simple de mi indicador (python 2.6):

>>> import decimal
>>> a = decimal.Decimal('10.000000001')
>>> a
Decimal('10.000000001')
>>> print a
10.000000001
>>> b = decimal.Decimal('10.00000000000000000000000000900000002')
>>> print b
10.00000000000000000000000000900000002
>>> print str(b)
10.00000000000000000000000000900000002
>>> len(str(b/decimal.Decimal('3.0')))
29

¿Quizás esto pueda ayudar? decimal está en python stdlib desde 2.4, con adiciones en python 2.6.

Espero que esto ayude, Francesco

Francesco
fuente
0

Sé que es demasiado tarde, pero para aquellos que vienen aquí por primera vez, me gustaría publicar una solución. Tengo un valor flotante indexy una cadena imgfiley tuve el mismo problema que tú. Así es como solucioné el problema

index = 1.0
imgfile = 'data/2.jpg'
out = '%.1f,%s' % (index,imgfile)
print out

La salida es

1.0,data/2.jpg

Puede modificar este ejemplo de formato según su conveniencia.

Harsh Wardhan
fuente