[pyar] Valores incorrectos

Diego E. Ahumada eddie.cpp en gmail.com
Vie Oct 15 19:22:00 ART 2010


El 15 de octubre de 2010 19:13, Pablo Ziliani <pablo en kultroom.com> escribió:

> Diego E. Ahumada wrote:
>
>>
>> 2010/10/15 Cristian Segura <ska.python en gmail.com <mailto:
>> ska.python en gmail.com>>
>>
>>
>>    Buenas chicos, mi primer duda a la lista :P
>>
>>    Estaba resolviendo un ejercicio, y me surgió un problema. El
>>    ejercicio en cuestión es el siguiente:
>>
>>    "Dada una cantidad de dinero, indicar como repartir el vuelto de
>>    manera que se utilice la menor cantidad de monedas"
>>
>>    El código que tengo es el siguiente:
>>
>>    b = (100, 50, 20, 10, 5, 2, 1, .5, .25, .1, .05)
>>
>>    v = float(raw_input("Ingrese vuelto: "))
>>    i = 0
>>    j = 0
>>    l = len(b)
>>
>>    while i != l:
>>        while v - b[i] >= 0:
>>            v -= b[i]
>>            j += 1
>>        if j != 0:
>>            print j, " billetes/monedas de ", b[i]
>>            print "El valor restante es: ", v    # Esta unicamente
>>    para comprobar los resultados
>>        j = 0
>>        i += 1
>>
>>    La salida del script utilizando como valor 1807.35 es:
>>    18  billetes/monedas de  100
>>    El valor restante es:  7.35
>>    1  billetes/monedas de  5
>>    El valor restante es:  2.35
>>    1  billetes/monedas de  2
>>    El valor restante es:  0.35
>>    1  billetes/monedas de  0.25
>>    El valor restante es:  0.0999999999999
>>    1  billetes/monedas de  0.05
>>    El valor restante es:  0.0499999999999
>>
>>    Mi pregunta es, por que al hacer la resta 0.35-0.25 devuelve 0.09
>>    y no 0.1?
>>
>>    Un saludo y gracias
>>
>> El problema se debe a cómo python y las computadoras en general manejan
>> los números de coma flotante. La respuesta precisa la encontrás en:
>> http://docs.python.org/tutorial/floatingpoint.html
>>
>
> Por cierto, el módulo Decimal fue hecho (entre otros) por Facundo Batista,
> uno de los creadores de PyAr. Muy probablemente también él haya escrito o
> ayudado a escribir ese artículo.
>
>
>  Las alternativas son utilizar el módulo 'decimal' (from decimal import *),
>>
>
> Es mejor hacer "from decimal import Decimal". Importar con asterisco está
> fuertemente desaconsejado.
>
>
>  o hacer, por ejemplo, round(3.5-2.5,2).
>>
>
> Yo estoy lejos de conocer los detalles, pero redondear es cambiar el tipo
> de problema, no solucionarlo. De todas maneras ojo, en tu ejemplo no hay
> "ganancia":
>
>
> >>> round(3.5 - 2.5, 2)
> 1.0
> >>> 3.5 - 2.5
> 1.0
>
> Tampoco la habría con un número no redondo:
>
> >>> 3.4 - 2.5
> 0.89999999999999991
> >>> round(3.4 - 2.5, 2)
> 0.90000000000000002
> >>> round(0.9, 2)
> 0.90000000000000002
> >>> 0.9
> 0.90000000000000002
>
>
> ¿cuál es mejor?
>
> Podés manejar más precisión (agregar decimales) y truncar el resultado AL
> FINAL de la operación, pero siempre vas a tener algún grado de error de
> redondeo. Hay mucha literatura al respecto.
>
> Como regla de oro, si es plata (o cualquier cosa donde los decimales sean
> críticos), usá Decimal. Decimal se basa en la representación visual del
> número (que es la que usamos los humanos) y no en la cantidad de bits que
> maneja el silicio por el que transita, por eso se crea a partir de una
> string y no un float.
>
>
Gracias!!! No me di cuenta que no resolvía nada con el round en mi ejemplo.
Voy a tener en cuenta lo del import de asteriscos, seguramente es para
evitar tener cientos de nombres inútiles dando vuelta en el programa, lo que
puede ocasionar que dos se dupliquen y estés llamando a metodos o clases de
un paquete, cuándo en realidad querías hacerlo de otro.

Diego.
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.python.org.ar/pipermail/pyar/attachments/20101015/9c1ed5eb/attachment.html>


More information about the pyar mailing list