• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

337
Views
¿Por qué 1//0.01 == 99 en Python?

Me imagino que esta es una pregunta clásica de precisión de punto flotante, pero estoy tratando de entender este resultado, ejecutar 1//0.01 en Python 3.7.5 produce 99 .

Me imagino que es un resultado esperado, pero ¿hay alguna forma de decidir cuándo es más seguro usar int(1/f) en lugar de 1//f ?

over 3 years ago · Santiago Trujillo
5 answers
Answer question

0

Si se tratara de una división con números reales, 1//0.01 sería exactamente 100. Sin embargo, dado que son aproximaciones de punto flotante, 0.01 es un poco más grande que 1/100, lo que significa que el cociente es un poco más pequeño que 100. Es este 99.algo valor que luego se reduce a 99.

over 3 years ago · Santiago Trujillo Report

0

Las razones de este resultado son como usted dice, y se explican en ¿Están rotas las matemáticas de punto flotante? y muchas otras preguntas y respuestas similares.

Cuando conoce la cantidad de decimales del numerador y el denominador, una forma más confiable es multiplicar esos números primero para que puedan tratarse como enteros y luego realizar una división entera en ellos:

Entonces, en su caso, 1//0.01 debe convertirse primero en 1*100//(0.01*100) , que es 100.

En casos más extremos, aún puede obtener resultados "inesperados". Puede ser necesario agregar una llamada round al numerador y al denominador antes de realizar la división entera:

 1 * 100000000000 // round(0.00000000001 * 100000000000)

Pero, si se trata de trabajar con decimales fijos (dinero, centavos), considere trabajar con centavos como unidad , de modo que toda la aritmética se pueda hacer como aritmética de enteros, y solo convierta a/desde la unidad monetaria principal (dólar) al hacer E/S.

O alternativamente, use una biblioteca para decimales, como decimal , que:

...proporciona soporte para aritmética de coma flotante decimal redondeada correctamente.

 from decimal import Decimal cent = Decimal(1) / Decimal(100) # Contrary to floating point, this is exactly 0.01 print (Decimal(1) // cent) # 100
over 3 years ago · Santiago Trujillo Report

0

Lo que tienes que tener en cuenta es que // es el operador de floor y como tal primero debes pensar que tienes la misma probabilidad de caer en 100 que en 99 (*) (porque la operación será 100 ± epsilon con epsilon>0 siempre que las posibilidades de obtener exactamente 100.00..0 sean extremadamente bajas).

De hecho, puedes ver lo mismo con un signo menos,

 >>> 1//.01 99.0 >>> -1//.01 -100.0

y deberías estar como (no) sorprendido.

Por otro lado, int(-1/.01) realiza primero la división y luego aplica el int() en el número, que no es piso sino un truncamiento hacia 0 ! lo que significa que en ese caso,

 >>> 1/.01 100.0 >>> -1/.01 -100.0

por eso,

 >>> int(1/.01) 100 >>> int(-1/.01) -100

Sin embargo, el redondeo le daría SU resultado esperado para este operador porque nuevamente, el error es pequeño para esas cifras.

(*) No digo que la probabilidad sea la misma, solo digo que, a priori, cuando realizas un cálculo de este tipo con aritmética flotante, es una estimación de lo que obtienes.

over 3 years ago · Santiago Trujillo Report

0

Si ejecutas lo siguiente

 from decimal import * num = Decimal(1) / Decimal(0.01) print(num)

La salida será:

 99.99999999999999791833182883

Así es como se representa internamente, por lo que redondearlo hacia abajo // dará 99

over 3 years ago · Santiago Trujillo Report

0

Los números de coma flotante no pueden representar exactamente la mayoría de los números decimales, por lo que cuando escribe un literal de coma flotante, en realidad obtiene una aproximación de ese literal. La aproximación puede ser mayor o menor que el número que escribió.

Puede ver el valor exacto de un número de coma flotante convirtiéndolo en Decimal o Fracción.

 >>> from decimal import Decimal >>> Decimal(0.01) Decimal('0.01000000000000000020816681711721685132943093776702880859375') >>> from fractions import Fractio >>> Fraction(0.01) Fraction(5764607523034235, 576460752303423488)

Podemos usar el tipo Fraction para encontrar el error causado por nuestro literal inexacto.

 >>> float((Fraction(1)/Fraction(0.01)) - 100) -2.0816681711721685e-15

También podemos averiguar qué tan granulares son los números de punto flotante de doble precisión alrededor de 100 usando nextafter de numpy.

 >>> from numpy import nextafter >>> nextafter(100,0)-100 -1.4210854715202004e-14

De esto podemos suponer que el número de punto flotante más cercano a 1/0.01000000000000000020816681711721685132943093776702880859375 es, de hecho, exactamente 100.

La diferencia entre 1//0.01 e int(1/0.01) es el redondeo. 1//0.01 redondea el resultado exacto al siguiente número entero en un solo paso. Entonces obtenemos un resultado de 99.

int(1/0.01) por otro lado redondea en dos etapas, primero redondea el resultado al número de coma flotante de precisión doble más cercano (que es exactamente 100), luego redondea ese número de coma flotante al siguiente entero (que es otra vez exactamente 100).

over 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error