Convertir un flotador en una cadena sin redondearlo


Estoy haciendo un programa que, por razones que no necesitan ser explicadas, requiere que un float sea convertido en una cadena para ser contada con len(). Sin embargo, str(float(x)) resulta en que x se redondea cuando se convierte en una cadena, lo que arroja toda la cosa. ¿Alguien sabe de una solución para él? Aquí está el código que se está utilizando si quieres saber:

len(str(float(x)/3))
Author: aioobe, 2009-08-23

4 answers

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 utiliza su computadora).

Por ejemplo:

>>> .1
0.10000000000000001

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

>>> repr(.1)
'0.10000000000000001'

Creo que python corta los últimos dígitos cuando usas str () para solucionar este problema, pero es una solución parcial que no sustituye a entender lo que está pasando.

>>> str(.1)
'0.1'

No estoy seguro exactamente qué problemas te está causando el "redondeo". ¿Tal vez lo haría mejor con el formato de cadena como una forma de controlar más precisamente su salida?

Por ejemplo

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

Documentación aquí .

 103
Author: John Fouhy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-23 02:10:13
len(repr(float(x)/3))

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

Los flotadores se ingresan/muestran como números decimales, pero su computadora (de hecho, su biblioteca estándar de C) los almacena como binarios. Usted obtiene 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 está en este capítulo del tutorial de python.

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

>>> print len(str(decimal.Decimal('0.1')))
3
 11
Author: nosklo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-23 02:13:11

Otras respuestas ya señalaron que la representación de números flotantes es una cuestión espinosa, por decir lo menos.

Dado que 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 sencillo de mi prompt (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

Tal vez esto puede ayudar? decimal está en python stdlib desde 2.4, con adiciones en python 2.6.

Espero que esto ayude, Francesco

 3
Author: Francesco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-23 11:14:57

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 index y una cadena imgfile y 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.

 0
Author: Harsh Wardhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-17 14:48:51