Cómo manejar la comparación de números de punto flotante en Python

PythonPythonBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

Los números de punto flotante se utilizan ampliamente en Python para cálculos numéricos, pero su representación puede llevar a veces a un comportamiento inesperado al comparar valores. Este tutorial lo guiará a través de los conceptos fundamentales de la representación de números de punto flotante en Python y le proporcionará técnicas prácticas para manejar comparaciones precisas de números de punto flotante.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/BasicConceptsGroup(["Basic Concepts"]) python(("Python")) -.-> python/PythonStandardLibraryGroup(["Python Standard Library"]) python/BasicConceptsGroup -.-> python/numeric_types("Numeric Types") python/BasicConceptsGroup -.-> python/type_conversion("Type Conversion") python/PythonStandardLibraryGroup -.-> python/math_random("Math and Random") python/PythonStandardLibraryGroup -.-> python/data_collections("Data Collections") subgraph Lab Skills python/numeric_types -.-> lab-395072{{"Cómo manejar la comparación de números de punto flotante en Python"}} python/type_conversion -.-> lab-395072{{"Cómo manejar la comparación de números de punto flotante en Python"}} python/math_random -.-> lab-395072{{"Cómo manejar la comparación de números de punto flotante en Python"}} python/data_collections -.-> lab-395072{{"Cómo manejar la comparación de números de punto flotante en Python"}} end

Representación de números de punto flotante en Python

En Python, los números de punto flotante se representan utilizando el estándar IEEE 754, que es un estándar ampliamente adoptado para representar números reales en computadoras. Este estándar define el formato y el comportamiento de la aritmética de punto flotante, incluyendo la representación de valores especiales como el infinito positivo y negativo, y el no-número (NaN).

Representación de números de punto flotante

Los números de punto flotante en Python se almacenan en un formato de 64 bits, también conocido como números de punto flotante de "doble precisión". Este formato consta de tres componentes:

  1. Bit de signo: Determina si el número es positivo o negativo.
  2. Exponente: Representa la potencia de 2 a la que se eleva el significando.
  3. Significando: La parte fraccionaria del número.

La representación de un número de punto flotante en Python se puede visualizar de la siguiente manera:

graph TD A[Sign Bit] --> B[Exponent] B --> C[Significand]

El estándar IEEE 754 define patrones de bits específicos para representar valores especiales, como el cero positivo y negativo, el infinito positivo y negativo, y el NaN.

Precisión y redondeo

La aritmética de punto flotante en las computadoras no siempre es exacta debido al número finito de bits utilizado para representar los números. Esto puede llevar a errores de redondeo y un comportamiento inesperado al comparar valores de punto flotante. Por ejemplo, el siguiente código demuestra el problema:

import sys

x = 0.1
y = 0.2
print(x + y)  ## Output: 0.30000000000000004

La razón de este comportamiento es que la representación binaria de 0.1 y 0.2 no se puede representar exactamente en el número finito de bits utilizado para almacenar números de punto flotante.

Para abordar este problema, en la siguiente sección se analizan diversas técnicas para la comparación precisa de números de punto flotante.

Comparación de números de punto flotante

Comparar números de punto flotante en Python puede ser un desafío debido a las inexactitudes inherentes en su representación. Las siguientes técnicas se pueden utilizar para realizar comparaciones precisas de números de punto flotante:

Comparación por diferencia absoluta

El enfoque más sencillo es comprobar si la diferencia absoluta entre dos números de punto flotante es menor que un valor umbral pequeño. Este método es adecuado cuando se conoce la precisión esperada de los valores que se están comparando.

import sys

x = 0.1
y = 0.2
epsilon = sys.float_info.epsilon  ## Pequeño número de punto flotante positivo x tal que 1.0 + x!= 1.0
if abs(x + y - 0.3) < epsilon:
    print("x + y is equal to 0.3")
else:
    print("x + y is not equal to 0.3")

Comparación por diferencia relativa

En casos donde la magnitud de los números que se comparan varía, la comparación por diferencia relativa puede ser más adecuada. Este método comprueba si la diferencia absoluta entre los números es pequeña en comparación con la magnitud de los números.

import sys

x = 1.0
y = 1.000000001
epsilon = sys.float_info.epsilon
if abs(x - y) / max(abs(x), abs(y)) < epsilon:
    print("x is equal to y")
else:
    print("x is not equal to y")

Comparación por ULP (Unidad en el último lugar)

El método de comparación por ULP comprueba si la diferencia entre dos números de punto flotante es menor que un cierto número de unidades en el último lugar (ULP, por sus siglas en inglés). Este enfoque es más preciso que los métodos de comparación por diferencia absoluta o relativa.

import math

x = 0.1
y = 0.100000000000001
if abs(x - y) <= 2 * math.ulp(max(x, y)):
    print("x is equal to y")
else:
    print("x is not equal to y")

Al utilizar estas técnicas, se pueden comparar eficazmente números de punto flotante en Python y manejar las inexactitudes inherentes en su representación.

Técnicas para la comparación precisa de números de punto flotante

Cuando se trabaja con números de punto flotante en Python, es importante utilizar técnicas adecuadas para garantizar comparaciones precisas. Aquí hay algunas técnicas que puedes utilizar:

Comparación por diferencia absoluta

La comparación por diferencia absoluta comprueba si la diferencia absoluta entre dos números de punto flotante es menor que un valor umbral pequeño. Este método es adecuado cuando se conoce la precisión esperada de los valores que se están comparando.

import sys

x = 0.1
y = 0.2
epsilon = sys.float_info.epsilon  ## Pequeño número de punto flotante positivo x tal que 1.0 + x!= 1.0
if abs(x + y - 0.3) < epsilon:
    print("x + y is equal to 0.3")
else:
    print("x + y is not equal to 0.3")

Comparación por diferencia relativa

La comparación por diferencia relativa comprueba si la diferencia absoluta entre dos números de punto flotante es pequeña en comparación con la magnitud de los números. Este método es útil cuando la magnitud de los números que se comparan varía.

import sys

x = 1.0
y = 1.000000001
epsilon = sys.float_info.epsilon
if abs(x - y) / max(abs(x), abs(y)) < epsilon:
    print("x is equal to y")
else:
    print("x is not equal to y")

Comparación por ULP (Unidad en el último lugar)

El método de comparación por ULP comprueba si la diferencia entre dos números de punto flotante es menor que un cierto número de unidades en el último lugar (ULP, por sus siglas en inglés). Este enfoque es más preciso que los métodos de comparación por diferencia absoluta o relativa.

import math

x = 0.1
y = 0.100000000000001
if abs(x - y) <= 2 * math.ulp(max(x, y)):
    print("x is equal to y")
else:
    print("x is not equal to y")

Al utilizar estas técnicas, puedes manejar eficazmente las comparaciones de números de punto flotante en Python y garantizar el nivel de precisión deseado en tus cálculos.

Resumen

En este tutorial de Python, has aprendido sobre los desafíos de la representación de números de punto flotante y estrategias efectivas para realizar comparaciones precisas de números de punto flotante. Al entender los principios subyacentes y aplicar las técnicas cubiertas, puedes escribir código Python más robusto y confiable que maneje con precisión las operaciones y comparaciones de números de punto flotante.