Python

Python

Tutorial Python: Módulo math

Aprende a usar el módulo math de Python con constantes, funciones trigonométricas, logarítmicas y técnicas de redondeo para cálculos precisos.

Aprende Python y certifícate

Constantes matemáticas

El módulo math de Python proporciona acceso a un conjunto de constantes matemáticas fundamentales que son esenciales para cálculos científicos y de ingeniería. Estas constantes están definidas con alta precisión y nos evitan tener que recordar o calcular sus valores aproximados.

Para utilizar estas constantes, primero debemos importar el módulo math:

import math

Constantes principales

El módulo math incluye varias constantes matemáticas importantes:

  • math.pi: El valor de π (pi), la relación entre la circunferencia de un círculo y su diámetro.
import math

# Valor de pi
print(f"El valor de π es: {math.pi}")
# Salida: El valor de π es: 3.141592653589793
  • math.e: La base de los logaritmos naturales, conocida como número de Euler.
# Número de Euler
print(f"El valor de e es: {math.e}")
# Salida: El valor de e es: 2.718281828459045
  • math.tau: Equivalente a 2π, representa el ángulo de una vuelta completa en radianes.
# Tau (2π)
print(f"El valor de τ es: {math.tau}")
# Salida: El valor de τ es: 6.283185307179586
  • math.inf: Representa el infinito positivo.
# Infinito
print(f"Infinito positivo: {math.inf}")
print(f"Infinito negativo: {-math.inf}")
# Salida: Infinito positivo: inf
#         Infinito negativo: -inf
  • math.nan: Representa "Not a Number" (No es un número).
# Not a Number
print(f"NaN: {math.nan}")
# Salida: NaN: nan
print(f"¿Es NaN?: {math.isnan(math.nan)}")
# Salida: ¿Es NaN?: True

Aplicaciones prácticas

Estas constantes son fundamentales para diversos cálculos. Veamos algunos ejemplos prácticos:

Cálculo del área y circunferencia de un círculo

import math

radio = 5

# Área del círculo: πr²
area = math.pi * radio**2
print(f"Área del círculo con radio {radio}: {area:.2f} unidades cuadradas")

# Circunferencia: 2πr
circunferencia = math.tau * radio  # Equivalente a 2 * math.pi * radio
print(f"Circunferencia: {circunferencia:.2f} unidades")

# Salida: Área del círculo con radio 5: 78.54 unidades cuadradas
#         Circunferencia: 31.42 unidades

Crecimiento exponencial con el número e

El número e es especialmente útil para modelar crecimiento exponencial, como en inversiones con interés compuesto continuo:

import math

principal = 1000  # Inversión inicial
tasa = 0.05       # Tasa de interés (5%)
tiempo = 10       # Años

# Fórmula de interés compuesto continuo: P * e^(rt)
monto_final = principal * math.e**(tasa * tiempo)
print(f"Inversión inicial: ${principal}")
print(f"Monto después de {tiempo} años: ${monto_final:.2f}")

# Salida: Inversión inicial: $1000
#         Monto después de 10 años: $1648.72

Comparación con infinito

Las constantes math.inf y -math.inf son útiles para inicializar variables en algoritmos de búsqueda:

import math

numeros = [15, 7, 23, 42, 8, 4]

# Inicializar con infinito para encontrar el mínimo
minimo = math.inf
for num in numeros:
    if num < minimo:
        minimo = num

# Inicializar con -infinito para encontrar el máximo
maximo = -math.inf
for num in numeros:
    if num > maximo:
        maximo = num

print(f"El valor mínimo es: {minimo}")
print(f"El valor máximo es: {maximo}")

# Salida: El valor mínimo es: 4
#         El valor máximo es: 42

Constantes menos conocidas

Además de las constantes más populares, el módulo math también proporciona algunas constantes especializadas:

# Constante de Euler-Mascheroni
print(f"Constante de Euler-Mascheroni: {math.inf - sum(1/n for n in range(1, 1000000)):.6f} (aproximación)")

# Precisión de punto flotante
print(f"Épsilon de punto flotante: {math.ulp(1.0)}")

Verificación de valores especiales

El módulo math también proporciona funciones para verificar si un valor es una de estas constantes especiales:

import math

# Verificar si un valor es infinito
print(f"¿Es infinito?: {math.isinf(math.inf)}")  # True
print(f"¿Es infinito?: {math.isinf(42)}")        # False

# Verificar si un valor es NaN
resultado = math.sqrt(-1)  # Esto generará un error en Python estándar
# Para generar un NaN sin error:
import numpy as np
resultado = np.sqrt(-1)
print(f"¿Es NaN?: {math.isnan(resultado)}")  # True

Las constantes matemáticas del módulo math proporcionan valores precisos para cálculos científicos y de ingeniería, evitando aproximaciones imprecisas y haciendo el código más legible. Al utilizar estas constantes predefinidas, nos aseguramos de trabajar con los valores más precisos disponibles en Python para nuestros cálculos matemáticos.

Funciones trigonométricas

El módulo math de Python proporciona un conjunto completo de funciones trigonométricas que son fundamentales para cálculos geométricos, físicos y de ingeniería. Estas funciones trabajan con ángulos expresados en radianes, no en grados, lo que es importante tener en cuenta al utilizarlas.

Para empezar a trabajar con estas funciones, primero debemos importar el módulo:

import math

Funciones trigonométricas básicas

El módulo math incluye las tres funciones trigonométricas fundamentales:

  • math.sin(x): Calcula el seno de un ángulo x (en radianes)
  • math.cos(x): Calcula el coseno de un ángulo x (en radianes)
  • math.tan(x): Calcula la tangente de un ángulo x (en radianes)
import math

# Calcular seno, coseno y tangente de 45 grados (π/4 radianes)
angulo_rad = math.pi / 4  # 45 grados en radianes

seno = math.sin(angulo_rad)
coseno = math.cos(angulo_rad)
tangente = math.tan(angulo_rad)

print(f"Seno de π/4: {seno:.6f}")
print(f"Coseno de π/4: {coseno:.6f}")
print(f"Tangente de π/4: {tangente:.6f}")

# Salida:
# Seno de π/4: 0.707107
# Coseno de π/4: 0.707107
# Tangente de π/4: 1.000000

Conversión entre grados y radianes

Como las funciones trigonométricas en Python trabajan con radianes, el módulo math proporciona funciones para convertir entre grados y radianes:

  • math.radians(x): Convierte x de grados a radianes
  • math.degrees(x): Convierte x de radianes a grados
import math

# Convertir 180 grados a radianes
radianes = math.radians(180)
print(f"180 grados = {radianes} radianes (π)")

# Convertir π/2 radianes a grados
grados = math.degrees(math.pi/2)
print(f"π/2 radianes = {grados} grados")

# Salida:
# 180 grados = 3.141592653589793 radianes (π)
# π/2 radianes = 90.0 grados

Funciones trigonométricas inversas

El módulo también incluye las funciones trigonométricas inversas (arcoseno, arcocoseno y arcotangente):

  • math.asin(x): Devuelve el arcoseno de x en radianes
  • math.acos(x): Devuelve el arcocoseno de x en radianes
  • math.atan(x): Devuelve el arcotangente de x en radianes
  • math.atan2(y, x): Devuelve el arcotangente de y/x en radianes, pero considera el cuadrante basado en los signos de ambos argumentos
import math

# Funciones trigonométricas inversas
valor = 0.5

arcoseno = math.asin(valor)
arcocoseno = math.acos(valor)
arcotangente = math.atan(valor)

print(f"Arcoseno de 0.5: {arcoseno} radianes ({math.degrees(arcoseno):.2f}°)")
print(f"Arcocoseno de 0.5: {arcocoseno} radianes ({math.degrees(arcocoseno):.2f}°)")
print(f"Arcotangente de 0.5: {arcotangente} radianes ({math.degrees(arcotangente):.2f}°)")

# Salida:
# Arcoseno de 0.5: 0.5235987755982989 radianes (30.00°)
# Arcocoseno de 0.5: 1.0471975511965979 radianes (60.00°)
# Arcotangente de 0.5: 0.4636476090008061 radianes (26.57°)

La función math.atan2(y, x) es especialmente útil para calcular el ángulo en coordenadas polares:

import math

# Calcular el ángulo de un punto en el plano cartesiano
x, y = -1, 1  # Punto en el segundo cuadrante

# atan2 considera el cuadrante correctamente
angulo = math.atan2(y, x)
print(f"Ángulo del punto ({x}, {y}): {angulo} radianes ({math.degrees(angulo):.2f}°)")

# Comparar con atan normal (que no considera el cuadrante)
angulo_simple = math.atan(y/x)
print(f"Usando solo atan: {angulo_simple} radianes ({math.degrees(angulo_simple):.2f}°)")

# Salida:
# Ángulo del punto (-1, 1): 2.356194490192345 radianes (135.00°)
# Usando solo atan: -0.7853981633974483 radianes (-45.00°)

Funciones hiperbólicas

El módulo math también incluye funciones trigonométricas hiperbólicas, útiles en diversos campos como la física y la ingeniería:

  • math.sinh(x): Seno hiperbólico de x
  • math.cosh(x): Coseno hiperbólico de x
  • math.tanh(x): Tangente hiperbólica de x
  • math.asinh(x): Arcoseno hiperbólico de x
  • math.acosh(x): Arcocoseno hiperbólico de x
  • math.atanh(x): Arcotangente hiperbólica de x
import math

# Funciones hiperbólicas
x = 1.0

senh = math.sinh(x)
cosh = math.cosh(x)
tanh = math.tanh(x)

print(f"Seno hiperbólico de 1: {senh:.6f}")
print(f"Coseno hiperbólico de 1: {cosh:.6f}")
print(f"Tangente hiperbólica de 1: {tanh:.6f}")

# Funciones hiperbólicas inversas
asenh = math.asinh(senh)
acosh = math.acosh(cosh)
atanh = math.atanh(tanh)

print(f"Arcoseno hiperbólico de {senh:.6f}: {asenh:.6f}")
print(f"Arcocoseno hiperbólico de {cosh:.6f}: {acosh:.6f}")
print(f"Arcotangente hiperbólica de {tanh:.6f}: {atanh:.6f}")

# Salida:
# Seno hiperbólico de 1: 1.175201
# Coseno hiperbólico de 1: 1.543081
# Tangente hiperbólica de 1: 0.761594
# Arcoseno hiperbólico de 1.175201: 1.000000
# Arcocoseno hiperbólico de 1.543081: 1.000000
# Arcotangente hiperbólica de 0.761594: 1.000000

Aplicaciones prácticas

Las funciones trigonométricas tienen numerosas aplicaciones prácticas. Veamos algunos ejemplos:

Cálculo de distancias en un plano

import math

# Calcular la distancia entre dos puntos usando trigonometría
def distancia_entre_puntos(x1, y1, x2, y2):
    dx = x2 - x1
    dy = y2 - y1
    return math.sqrt(dx**2 + dy**2)

# Ejemplo: distancia entre los puntos (1,2) y (4,6)
dist = distancia_entre_puntos(1, 2, 4, 6)
print(f"Distancia entre los puntos: {dist:.2f} unidades")

# Salida: Distancia entre los puntos: 5.00 unidades

Cálculo de componentes de un vector

import math

# Calcular las componentes de un vector dado su magnitud y ángulo
def componentes_vector(magnitud, angulo_grados):
    angulo_rad = math.radians(angulo_grados)
    x = magnitud * math.cos(angulo_rad)
    y = magnitud * math.sin(angulo_rad)
    return x, y

# Vector con magnitud 10 y ángulo de 30 grados
comp_x, comp_y = componentes_vector(10, 30)
print(f"Componente X: {comp_x:.2f}")
print(f"Componente Y: {comp_y:.2f}")

# Salida:
# Componente X: 8.66
# Componente Y: 5.00

Cálculo de altura de un objeto usando trigonometría

import math

# Calcular la altura de un objeto usando el ángulo de elevación
def calcular_altura(distancia, angulo_grados):
    angulo_rad = math.radians(angulo_grados)
    altura = distancia * math.tan(angulo_rad)
    return altura

# Ejemplo: objeto a 100 metros de distancia, ángulo de elevación de 25 grados
altura = calcular_altura(100, 25)
print(f"La altura del objeto es: {altura:.2f} metros")

# Salida: La altura del objeto es: 46.63 metros

Generación de puntos en un círculo

import math

# Generar puntos equidistantes en un círculo
def puntos_en_circulo(centro_x, centro_y, radio, num_puntos):
    puntos = []
    for i in range(num_puntos):
        angulo = 2 * math.pi * i / num_puntos
        x = centro_x + radio * math.cos(angulo)
        y = centro_y + radio * math.sin(angulo)
        puntos.append((x, y))
    return puntos

# Generar 8 puntos en un círculo de radio 5 centrado en (0,0)
puntos = puntos_en_circulo(0, 0, 5, 8)
for i, (x, y) in enumerate(puntos):
    print(f"Punto {i+1}: ({x:.2f}, {y:.2f})")

# Salida:
# Punto 1: (5.00, 0.00)
# Punto 2: (3.54, 3.54)
# Punto 3: (0.00, 5.00)
# Punto 4: (-3.54, 3.54)
# Punto 5: (-5.00, 0.00)
# Punto 6: (-3.54, -3.54)
# Punto 7: (-0.00, -5.00)
# Punto 8: (3.54, -3.54)

Las funciones trigonométricas del módulo math son herramientas esenciales para resolver problemas geométricos, físicos y de ingeniería. Al proporcionar implementaciones precisas y eficientes de estas funciones, Python facilita el desarrollo de aplicaciones que requieren cálculos trigonométricos, desde simulaciones físicas hasta gráficos por computadora y análisis de señales.

Funciones logarítmicas y exponenciales

El módulo math de Python proporciona un conjunto completo de funciones logarítmicas y exponenciales que son fundamentales para diversos cálculos científicos, financieros y de ingeniería. Estas funciones permiten modelar fenómenos de crecimiento, decrecimiento y escalas no lineales con precisión.

Funciones exponenciales

Las funciones exponenciales modelan procesos donde la tasa de cambio es proporcional al valor actual, como el crecimiento poblacional o el interés compuesto.

  • math.exp(x): Calcula e^x (e elevado a la potencia x)
import math

# Calcular e^2
resultado = math.exp(2)
print(f"e^2 = {resultado:.6f}")
# Salida: e^2 = 7.389056
  • math.pow(x, y): Calcula x^y (x elevado a la potencia y)
# Calcular 2^10 usando math.pow
potencia = math.pow(2, 10)
print(f"2^10 = {potencia}")
# Salida: 2^10 = 1024.0

Es importante destacar que math.pow(x, y) siempre devuelve un valor de tipo float, mientras que el operador ** puede devolver un entero si tanto la base como el exponente son enteros:

# Comparación entre math.pow y el operador **
print(f"math.pow(2, 10) = {math.pow(2, 10)}, tipo: {type(math.pow(2, 10))}")
print(f"2 ** 10 = {2 ** 10}, tipo: {type(2 ** 10)}")
# Salida: 
# math.pow(2, 10) = 1024.0, tipo: <class 'float'>
# 2 ** 10 = 1024, tipo: <class 'int'>

Funciones logarítmicas

Los logaritmos son las operaciones inversas de las exponenciales y son útiles para resolver ecuaciones exponenciales, analizar datos en diferentes escalas y calcular tasas de crecimiento.

  • math.log(x): Calcula el logaritmo natural (base e) de x
import math

# Logaritmo natural de 10
ln_10 = math.log(10)
print(f"ln(10) = {ln_10:.6f}")
# Salida: ln(10) = 2.302585
  • math.log10(x): Calcula el logaritmo en base 10 de x
# Logaritmo base 10 de 100
log10_100 = math.log10(100)
print(f"log10(100) = {log10_100}")
# Salida: log10(100) = 2.0
  • math.log2(x): Calcula el logaritmo en base 2 de x
# Logaritmo base 2 de 8
log2_8 = math.log2(8)
print(f"log2(8) = {log2_8}")
# Salida: log2(8) = 3.0
  • math.log(x, base): Calcula el logaritmo de x en cualquier base
# Logaritmo base 5 de 125
log5_125 = math.log(125, 5)
print(f"log5(125) = {log5_125}")
# Salida: log5(125) = 3.0

Aplicaciones prácticas

Cálculo de interés compuesto

El interés compuesto es un ejemplo clásico de crecimiento exponencial:

import math

def calcular_monto_final(principal, tasa_anual, años, compuesto_por_año=1):
    """
    Calcula el monto final con interés compuesto.
    
    Args:
        principal: Cantidad inicial invertida
        tasa_anual: Tasa de interés anual (en decimal, ej: 0.05 para 5%)
        años: Número de años
        compuesto_por_año: Número de veces que se compone el interés por año
    """
    # Fórmula: P(1 + r/n)^(nt)
    tasa_por_periodo = tasa_anual / compuesto_por_año
    periodos = compuesto_por_año * años
    
    return principal * math.pow(1 + tasa_por_periodo, periodos)

# Ejemplo: $1000 al 5% anual durante 10 años
monto_anual = calcular_monto_final(1000, 0.05, 10)
print(f"Monto final (compuesto anualmente): ${monto_anual:.2f}")

# Compuesto mensualmente
monto_mensual = calcular_monto_final(1000, 0.05, 10, 12)
print(f"Monto final (compuesto mensualmente): ${monto_mensual:.2f}")

# Compuesto continuamente (usando e^rt)
monto_continuo = 1000 * math.exp(0.05 * 10)
print(f"Monto final (compuesto continuamente): ${monto_continuo:.2f}")

# Salida:
# Monto final (compuesto anualmente): $1628.89
# Monto final (compuesto mensualmente): $1647.01
# Monto final (compuesto continuamente): $1648.72

Cálculo del tiempo de duplicación

Usando logaritmos, podemos calcular cuánto tiempo tardará una cantidad en duplicarse con una tasa de crecimiento dada:

import math

def tiempo_duplicacion(tasa_crecimiento):
    """
    Calcula el tiempo necesario para que una cantidad se duplique
    con una tasa de crecimiento dada.
    
    Args:
        tasa_crecimiento: Tasa de crecimiento (en decimal)
    
    Returns:
        Tiempo necesario para duplicar la cantidad
    """
    # Fórmula: ln(2)/r
    return math.log(2) / tasa_crecimiento

# Ejemplo: Tasa de crecimiento del 5% anual
años_para_duplicar = tiempo_duplicacion(0.05)
print(f"Con un crecimiento del 5% anual, una cantidad se duplica en {años_para_duplicar:.2f} años")

# Regla del 72 (aproximación financiera)
regla_72 = 72 / (5)  # 5% expresado como número entero
print(f"Según la regla del 72: {regla_72:.2f} años")

# Salida:
# Con un crecimiento del 5% anual, una cantidad se duplica en 13.86 años
# Según la regla del 72: 14.40 años

Escala logarítmica para visualización de datos

Los logaritmos son útiles para representar datos que abarcan varios órdenes de magnitud:

import math

# Convertir valores a escala logarítmica
valores = [1, 10, 100, 1000, 10000]
escala_log10 = [math.log10(v) for v in valores]

print("Valores originales vs. escala logarítmica (base 10):")
for original, log in zip(valores, escala_log10):
    print(f"{original:7} → {log:.1f}")

# Salida:
# Valores originales vs. escala logarítmica (base 10):
#       1 → 0.0
#      10 → 1.0
#     100 → 2.0
#    1000 → 3.0
#   10000 → 4.0

Cálculo de pH (escala logarítmica)

El pH es un ejemplo de aplicación de logaritmos en química:

import math

def calcular_ph(concentracion_h):
    """
    Calcula el pH a partir de la concentración de iones de hidrógeno.
    
    Args:
        concentracion_h: Concentración de iones H+ en moles/litro
    
    Returns:
        Valor de pH
    """
    return -math.log10(concentracion_h)

# Ejemplos de cálculo de pH
concentraciones = {
    "Ácido de batería": 1.0,
    "Jugo de limón": 1e-2,
    "Agua pura": 1e-7,
    "Jabón": 1e-10,
    "Lejía": 1e-13
}

print("Sustancia               Concentración H+    pH")
print("------------------------------------------------")
for sustancia, conc in concentraciones.items():
    ph = calcular_ph(conc)
    print(f"{sustancia:22} {conc:e}        {ph:.1f}")

# Salida:
# Sustancia               Concentración H+    pH
# ------------------------------------------------
# Ácido de batería        1.000000e+00        0.0
# Jugo de limón           1.000000e-02        2.0
# Agua pura               1.000000e-07        7.0
# Jabón                   1.000000e-10        10.0
# Lejía                   1.000000e-13        13.0

Cálculo de decibelios (escala logarítmica)

Los decibelios son otra aplicación común de logaritmos, usados para medir intensidad de sonido:

import math

def calcular_decibelios(intensidad, intensidad_referencia=1e-12):
    """
    Calcula el nivel de sonido en decibelios.
    
    Args:
        intensidad: Intensidad del sonido en W/m²
        intensidad_referencia: Intensidad de referencia (umbral de audición)
    
    Returns:
        Nivel de sonido en decibelios (dB)
    """
    return 10 * math.log10(intensidad / intensidad_referencia)

# Ejemplos de niveles de sonido
intensidades = {
    "Umbral de audición": 1e-12,
    "Susurro": 1e-10,
    "Conversación normal": 1e-6,
    "Tráfico urbano": 1e-4,
    "Concierto de rock": 1e-1,
    "Umbral de dolor": 1e1
}

print("Fuente de sonido         Intensidad (W/m²)    Nivel (dB)")
print("--------------------------------------------------------")
for fuente, intensidad in intensidades.items():
    db = calcular_decibelios(intensidad)
    print(f"{fuente:24} {intensidad:e}        {db:.1f}")

# Salida:
# Fuente de sonido         Intensidad (W/m²)    Nivel (dB)
# --------------------------------------------------------
# Umbral de audición       1.000000e-12        0.0
# Susurro                  1.000000e-10        20.0
# Conversación normal      1.000000e-06        60.0
# Tráfico urbano           1.000000e-04        80.0
# Concierto de rock        1.000000e-01        110.0
# Umbral de dolor          1.000000e+01        130.0

Funciones exponenciales y logarítmicas especiales

El módulo math también incluye algunas funciones especializadas:

  • math.expm1(x): Calcula e^x - 1 con mayor precisión para valores pequeños de x
import math

# Comparación entre exp(x) - 1 y expm1(x) para valores pequeños
x = 1e-10
resultado1 = math.exp(x) - 1
resultado2 = math.expm1(x)

print(f"exp({x}) - 1 = {resultado1}")
print(f"expm1({x}) = {resultado2}")
print(f"Diferencia relativa: {abs((resultado1 - resultado2) / resultado2):.2e}")

# Salida:
# exp(1e-10) - 1 = 0.0
# expm1(1e-10) = 1e-10
# Diferencia relativa: 1.00e+00
  • math.log1p(x): Calcula log(1 + x) con mayor precisión para valores pequeños de x
# Comparación entre log(1 + x) y log1p(x) para valores pequeños
x = 1e-10
resultado1 = math.log(1 + x)
resultado2 = math.log1p(x)

print(f"log(1 + {x}) = {resultado1}")
print(f"log1p({x}) = {resultado2}")
print(f"Diferencia relativa: {abs((resultado1 - resultado2) / resultado2):.2e}")

# Salida:
# log(1 + 1e-10) = 0.0
# log1p(1e-10) = 1e-10
# Diferencia relativa: 1.00e+00

Estas funciones especiales son particularmente útiles en cálculos numéricos y estadísticos donde la precisión es crucial, especialmente cuando se trabaja con valores muy pequeños.

Relación entre funciones exponenciales y logarítmicas

Las funciones exponenciales y logarítmicas son inversas entre sí, lo que significa que:

import math

x = 2.5
# Si y = e^x, entonces x = ln(y)
y = math.exp(x)
x_recuperado = math.log(y)

print(f"x original: {x}")
print(f"y = e^x: {y}")
print(f"x recuperado = ln(y): {x_recuperado}")
print(f"¿Son iguales? {math.isclose(x, x_recuperado)}")

# Salida:
# x original: 2.5
# y = e^x: 12.182493960703473
# x recuperado = ln(y): 2.5
# ¿Son iguales? True

Esta propiedad hace que estas funciones sean especialmente útiles para resolver ecuaciones donde la incógnita aparece como exponente.

Las funciones logarítmicas y exponenciales del módulo math proporcionan herramientas poderosas para modelar fenómenos de crecimiento y decrecimiento, trabajar con escalas no lineales y resolver problemas en campos tan diversos como finanzas, física, química y procesamiento de señales.

Redondeo y truncamiento

El módulo math de Python proporciona diversas funciones de redondeo y truncamiento que son esenciales para controlar la precisión numérica en cálculos científicos, financieros y de ingeniería. Estas funciones permiten ajustar valores decimales según diferentes criterios matemáticos.

Funciones de redondeo

Python ofrece varias formas de redondear números, cada una con comportamientos específicos:

  • math.ceil(x): Redondea hacia arriba al entero más cercano (techo)
import math

# Redondeo hacia arriba
print(f"math.ceil(3.2) = {math.ceil(3.2)}")  # 4
print(f"math.ceil(3.7) = {math.ceil(3.7)}")  # 4
print(f"math.ceil(-2.3) = {math.ceil(-2.3)}")  # -2
  • math.floor(x): Redondea hacia abajo al entero más cercano (suelo)
# Redondeo hacia abajo
print(f"math.floor(3.2) = {math.floor(3.2)}")  # 3
print(f"math.floor(3.7) = {math.floor(3.7)}")  # 3
print(f"math.floor(-2.3) = {math.floor(-2.3)}")  # -3
  • math.trunc(x): Trunca hacia cero (elimina la parte decimal)
# Truncamiento (elimina parte decimal)
print(f"math.trunc(3.2) = {math.trunc(3.2)}")  # 3
print(f"math.trunc(3.7) = {math.trunc(3.7)}")  # 3
print(f"math.trunc(-2.3) = {math.trunc(-2.3)}")  # -2
  • round(x, n): Función incorporada de Python que redondea al valor más cercano
# Función round (incorporada en Python)
print(f"round(3.2) = {round(3.2)}")  # 3
print(f"round(3.7) = {round(3.7)}")  # 4
print(f"round(2.5) = {round(2.5)}")  # 2 (redondeo a par en caso de empate)
print(f"round(3.5) = {round(3.5)}")  # 4 (redondeo a par en caso de empate)

Es importante destacar que round() utiliza la estrategia de "redondeo bancario" o "redondeo a par" cuando un número está exactamente a mitad de camino entre dos enteros. Esto significa que 0.5 se redondea al entero par más cercano, lo que puede resultar sorprendente:

# Demostración del redondeo bancario
print(f"round(2.5) = {round(2.5)}")  # 2
print(f"round(3.5) = {round(3.5)}")  # 4

Redondeo con precisión decimal

La función round() también permite especificar el número de decimales:

# Redondeo con precisión decimal
pi = math.pi
print(f"π original: {pi}")
print(f"π redondeado a 2 decimales: {round(pi, 2)}")
print(f"π redondeado a 4 decimales: {round(pi, 4)}")
print(f"π redondeado a 0 decimales: {round(pi, 0)}")  # Equivalente a round(pi)

# Salida:
# π original: 3.141592653589793
# π redondeado a 2 decimales: 3.14
# π redondeado a 4 decimales: 3.1416
# π redondeado a 0 decimales: 3.0

Diferencias entre truncamiento y redondeo

Es importante entender la diferencia entre truncar y redondear:

import math

valor = 3.75
print(f"Valor original: {valor}")
print(f"Truncado (math.trunc): {math.trunc(valor)}")  # 3
print(f"Redondeado (round): {round(valor)}")  # 4
print(f"Redondeado hacia abajo (math.floor): {math.floor(valor)}")  # 3
print(f"Redondeado hacia arriba (math.ceil): {math.ceil(valor)}")  # 4

# Con números negativos
valor_neg = -2.75
print(f"\nValor original negativo: {valor_neg}")
print(f"Truncado (math.trunc): {math.trunc(valor_neg)}")  # -2
print(f"Redondeado (round): {round(valor_neg)}")  # -3
print(f"Redondeado hacia abajo (math.floor): {math.floor(valor_neg)}")  # -3
print(f"Redondeado hacia arriba (math.ceil): {math.ceil(valor_neg)}")  # -2

Función isclose para comparaciones con punto flotante

Cuando trabajamos con números de punto flotante, las comparaciones directas pueden ser problemáticas debido a errores de redondeo. El módulo math proporciona la función isclose() para comparar números con una tolerancia:

import math

# Problema con comparaciones de punto flotante
a = 0.1 + 0.2
b = 0.3
print(f"0.1 + 0.2 = {a}")
print(f"0.3 = {b}")
print(f"¿Son iguales? {a == b}")  # False debido a errores de redondeo

# Solución con math.isclose
print(f"¿Son aproximadamente iguales? {math.isclose(a, b)}")  # True

# Personalizar la tolerancia
print(f"Con tolerancia personalizada: {math.isclose(a, b, rel_tol=1e-10, abs_tol=1e-10)}")

Funciones para redondeo especial

El módulo math incluye funciones para casos especiales de redondeo:

  • math.fmod(x, y): Calcula el módulo con el mismo signo que x (a diferencia del operador %)
import math

# Diferencia entre % y math.fmod
print(f"5.5 % 2 = {5.5 % 2}")  # 1.5
print(f"math.fmod(5.5, 2) = {math.fmod(5.5, 2)}")  # 1.5

# Con números negativos hay diferencia
print(f"-5.5 % 2 = {-5.5 % 2}")  # 0.5 (resultado siempre positivo con %)
print(f"math.fmod(-5.5, 2) = {math.fmod(-5.5, 2)}")  # -1.5 (mantiene el signo del dividendo)
  • math.remainder(x, y): Calcula el resto IEEE 754, que es x - n*y donde n es el entero más cercano a x/y
# Resto IEEE 754
print(f"math.remainder(5.5, 2) = {math.remainder(5.5, 2)}")  # -0.5
print(f"math.remainder(-5.5, 2) = {math.remainder(-5.5, 2)}")  # 0.5
  • math.modf(x): Devuelve la parte fraccionaria y la parte entera de x
# Separar parte fraccionaria y entera
frac, entero = math.modf(3.75)
print(f"Parte fraccionaria de 3.75: {frac}")  # 0.75
print(f"Parte entera de 3.75: {entero}")  # 3.0

# Con números negativos
frac_neg, entero_neg = math.modf(-3.75)
print(f"Parte fraccionaria de -3.75: {frac_neg}")  # -0.75
print(f"Parte entera de -3.75: {entero_neg}")  # -3.0
  • math.copysign(x, y): Devuelve x con el signo de y
# Copiar el signo
print(f"math.copysign(1.5, -3) = {math.copysign(1.5, -3)}")  # -1.5
print(f"math.copysign(-1.5, 3) = {math.copysign(-1.5, 3)}")  # 1.5

Aplicaciones prácticas

Redondeo en cálculos financieros

En finanzas, el redondeo adecuado es crucial para evitar errores de acumulación:

import math

def calcular_pago_mensual(principal, tasa_anual, años):
    """
    Calcula el pago mensual de un préstamo.
    
    Args:
        principal: Monto del préstamo
        tasa_anual: Tasa de interés anual (decimal)
        años: Duración del préstamo en años
    """
    tasa_mensual = tasa_anual / 12
    num_pagos = años * 12
    
    # Fórmula de amortización
    pago = principal * (tasa_mensual * math.pow(1 + tasa_mensual, num_pagos)) / (math.pow(1 + tasa_mensual, num_pagos) - 1)
    
    # Redondear a 2 decimales para centavos
    return round(pago, 2)

# Ejemplo: Préstamo de $200,000 al 4.5% por 30 años
pago_mensual = calcular_pago_mensual(200000, 0.045, 30)
print(f"Pago mensual: ${pago_mensual}")

# Verificar que los pagos totales cubren el préstamo
total_pagado = pago_mensual * 30 * 12
print(f"Total pagado en 30 años: ${total_pagado:.2f}")
print(f"Intereses pagados: ${total_pagado - 200000:.2f}")

Truncamiento para división entera

El truncamiento es útil cuando necesitamos la parte entera de una división:

import math

def division_entera_personalizada(dividendo, divisor):
    """
    Realiza división entera con diferentes métodos.
    """
    # Métodos de división entera
    resultado_operador = dividendo // divisor
    resultado_trunc = math.trunc(dividendo / divisor)
    resultado_floor = math.floor(dividendo / divisor)
    
    return {
        "operador //": resultado_operador,
        "math.trunc": resultado_trunc,
        "math.floor": resultado_floor
    }

# Ejemplos con números positivos
print("División: 17 ÷ 5")
for método, resultado in division_entera_personalizada(17, 5).items():
    print(f"  {método}: {resultado}")

# Ejemplos con números negativos (donde hay diferencias)
print("\nDivisión: -17 ÷ 5")
for método, resultado in division_entera_personalizada(-17, 5).items():
    print(f"  {método}: {resultado}")

# Salida:
# División: 17 ÷ 5
#   operador //: 3
#   math.trunc: 3
#   math.floor: 3
#
# División: -17 ÷ 5
#   operador //: -4
#   math.trunc: -3
#   math.floor: -4

Redondeo para visualización de datos

El redondeo es esencial para presentar datos de manera legible:

import math
import random

# Generar datos de temperatura simulados
temperaturas = [random.uniform(20, 30) for _ in range(10)]

print("Temperaturas originales vs. redondeadas:")
print("Original    | Redondeada | Floor  | Ceil")
print("-" * 45)

for temp in temperaturas:
    print(f"{temp:.6f} | {round(temp, 1):.1f}     | {math.floor(temp):.0f}     | {math.ceil(temp):.0f}")

# Calcular estadísticas
media = sum(temperaturas) / len(temperaturas)
print(f"\nTemperatura media: {media:.6f}")
print(f"Redondeada a 1 decimal: {round(media, 1):.1f}")

Cuantización de señales

En procesamiento de señales, el truncamiento y redondeo se utilizan para la cuantización:

import math
import numpy as np
import matplotlib.pyplot as plt

# Crear una señal continua simple
x = np.linspace(0, 2*np.pi, 100)
señal = np.sin(x)

# Diferentes métodos de cuantización
cuantizada_trunc = [math.trunc(val * 4) / 4 for val in señal]
cuantizada_round = [round(val * 4) / 4 for val in señal]
cuantizada_floor = [math.floor(val * 4) / 4 for val in señal]
cuantizada_ceil = [math.ceil(val * 4) / 4 for val in señal]

# Visualizar los primeros valores
print("Comparación de métodos de cuantización (primeros 5 valores):")
print("Original | Truncado | Redondeado | Floor | Ceil")
print("-" * 60)

for i in range(5):
    print(f"{señal[i]:.6f} | {cuantizada_trunc[i]:.2f}    | {cuantizada_round[i]:.2f}      | {cuantizada_floor[i]:.2f}   | {cuantizada_ceil[i]:.2f}")

# Calcular error de cuantización
error_trunc = sum((s - q)**2 for s, q in zip(señal, cuantizada_trunc))
error_round = sum((s - q)**2 for s, q in zip(señal, cuantizada_round))

print(f"\nError cuadrático medio (truncamiento): {error_trunc:.6f}")
print(f"Error cuadrático medio (redondeo): {error_round:.6f}")

Consideraciones de rendimiento

Las diferentes funciones de redondeo tienen distintas características de rendimiento:

import math
import time

def medir_tiempo(func, valor, repeticiones=1000000):
    """Mide el tiempo de ejecución de una función."""
    inicio = time.time()
    for _ in range(repeticiones):
        func(valor)
    fin = time.time()
    return fin - inicio

valor_prueba = 3.75

# Comparar rendimiento
tiempo_trunc = medir_tiempo(math.trunc, valor_prueba)
tiempo_floor = medir_tiempo(math.floor, valor_prueba)
tiempo_ceil = medir_tiempo(math.ceil, valor_prueba)
tiempo_round = medir_tiempo(round, valor_prueba)

print("Comparación de rendimiento (tiempo en segundos para 1 millón de operaciones):")
print(f"math.trunc: {tiempo_trunc:.4f}s")
print(f"math.floor: {tiempo_floor:.4f}s")
print(f"math.ceil: {tiempo_ceil:.4f}s")
print(f"round: {tiempo_round:.4f}s")

Redondeo a múltiplos específicos

A veces necesitamos redondear a múltiplos específicos, como 0.05 para precios:

import math

def redondear_a_multiplo(valor, multiplo, metodo='round'):
    """
    Redondea un valor al múltiplo más cercano.
    
    Args:
        valor: Valor a redondear
        multiplo: Múltiplo al que redondear
        metodo: 'round', 'floor' o 'ceil'
    """
    if metodo == 'round':
        return round(valor / multiplo) * multiplo
    elif metodo == 'floor':
        return math.floor(valor / multiplo) * multiplo
    elif metodo == 'ceil':
        return math.ceil(valor / multiplo) * multiplo
    else:
        raise ValueError("Método no válido. Use 'round', 'floor' o 'ceil'")

# Ejemplos de redondeo a múltiplos
precio = 9.37

print(f"Precio original: ${precio}")
print(f"Redondeado al nickel (0.05) más cercano: ${redondear_a_multiplo(precio, 0.05)}")
print(f"Redondeado al dime (0.10) más cercano: ${redondear_a_multiplo(precio, 0.10)}")
print(f"Redondeado al cuarto (0.25) más cercano: ${redondear_a_multiplo(precio, 0.25)}")
print(f"Redondeado al dólar más cercano: ${redondear_a_multiplo(precio, 1)}")

# Redondeo hacia abajo (floor)
print(f"Redondeado hacia abajo al cuarto más cercano: ${redondear_a_multiplo(precio, 0.25, 'floor')}")

# Redondeo hacia arriba (ceil)
print(f"Redondeado hacia arriba al cuarto más cercano: ${redondear_a_multiplo(precio, 0.25, 'ceil')}")

Las funciones de redondeo y truncamiento del módulo math proporcionan herramientas esenciales para controlar la precisión numérica en aplicaciones Python. Estas funciones permiten ajustar valores según diferentes criterios matemáticos, lo que es crucial en campos como finanzas, ciencia de datos, procesamiento de señales y visualización de información.

Aprende Python online

Otros ejercicios de programación de Python

Evalúa tus conocimientos de esta lección Módulo math con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Módulo math

Python
Puzzle

Reto herencia

Python
Código

Excepciones

Python
Test

Introducción a Python

Python
Test

Reto variables

Python
Código

Funciones Python

Python
Puzzle

Reto funciones

Python
Código

Módulo datetime

Python
Test

Reto acumulación

Python
Código

Reto estructuras condicionales

Python
Código

Polimorfismo

Python
Test

Módulo os

Python
Test

Reto métodos dunder

Python
Código

Diccionarios

Python
Puzzle

Reto clases y objetos

Python
Código

Reto operadores

Python
Código

Operadores

Python
Test

Estructuras de control

Python
Puzzle

Funciones lambda

Python
Test

Reto diccionarios

Python
Código

Reto función lambda

Python
Código

Encapsulación

Python
Puzzle

Reto coleciones

Python
Proyecto

Reto funciones auxiliares

Python
Código

Crear módulos y paquetes

Python
Puzzle

Módulo datetime

Python
Puzzle

Excepciones

Python
Puzzle

Operadores

Python
Puzzle

Diccionarios

Python
Test

Reto map, filter

Python
Código

Reto tuplas

Python
Código

Proyecto gestor de tareas CRUD

Python
Proyecto

Tuplas

Python
Puzzle

Variables

Python
Puzzle

Tipos de datos

Python
Puzzle

Conjuntos

Python
Test

Reto mixins

Python
Código

Módulo csv

Python
Test

Módulo json

Python
Test

Herencia

Python
Test

Análisis de datos de ventas con Pandas

Python
Proyecto

Reto fechas y tiempo

Python
Proyecto

Reto estructuras de iteración

Python
Código

Funciones

Python
Test

Reto comprehensions

Python
Código

Variables

Python
Test

Reto serialización

Python
Proyecto

Módulo csv

Python
Puzzle

Reto polimorfismo

Python
Código

Polimorfismo

Python
Puzzle

Clases y objetos

Python
Código

Reto encapsulación

Python
Código

Estructuras de control

Python
Test

Importar módulos y paquetes

Python
Test

Módulo math

Python
Test

Funciones lambda

Python
Puzzle

Reto excepciones

Python
Código

Listas

Python
Puzzle

Reto archivos

Python
Proyecto

Encapsulación

Python
Test

Reto conjuntos

Python
Código

Clases y objetos

Python
Test

Instalación de Python y creación de proyecto

Python
Test

Reto listas

Python
Código

Tipos de datos

Python
Test

Crear módulos y paquetes

Python
Test

Tuplas

Python
Test

Herencia

Python
Puzzle

Reto acceso a sistema

Python
Proyecto

Proyecto sintaxis calculadora

Python
Proyecto

Importar módulos y paquetes

Python
Puzzle

Clases y objetos

Python
Puzzle

Módulo os

Python
Puzzle

Listas

Python
Test

Conjuntos

Python
Puzzle

Reto tipos de datos

Python
Código

Reto matemáticas

Python
Proyecto

Módulo json

Python
Puzzle

Todas las lecciones de Python

Accede a todas las lecciones de Python y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Introducción A Python

Python

Introducción

Instalación Y Creación De Proyecto

Python

Introducción

Tema 2: Tipos De Datos, Variables Y Operadores

Python

Introducción

Instalación De Python

Python

Introducción

Tipos De Datos

Python

Sintaxis

Variables

Python

Sintaxis

Operadores

Python

Sintaxis

Estructuras De Control

Python

Sintaxis

Funciones

Python

Sintaxis

Estructuras Control Iterativo

Python

Sintaxis

Estructuras Control Condicional

Python

Sintaxis

Testing Con Pytest

Python

Sintaxis

Listas

Python

Estructuras De Datos

Tuplas

Python

Estructuras De Datos

Diccionarios

Python

Estructuras De Datos

Conjuntos

Python

Estructuras De Datos

Comprehensions

Python

Estructuras De Datos

Clases Y Objetos

Python

Programación Orientada A Objetos

Excepciones

Python

Programación Orientada A Objetos

Encapsulación

Python

Programación Orientada A Objetos

Herencia

Python

Programación Orientada A Objetos

Polimorfismo

Python

Programación Orientada A Objetos

Mixins Y Herencia Múltiple

Python

Programación Orientada A Objetos

Métodos Especiales (Dunder Methods)

Python

Programación Orientada A Objetos

Composición De Clases

Python

Programación Orientada A Objetos

Funciones Lambda

Python

Programación Funcional

Aplicación Parcial

Python

Programación Funcional

Entrada Y Salida, Manejo De Archivos

Python

Programación Funcional

Decoradores

Python

Programación Funcional

Generadores

Python

Programación Funcional

Paradigma Funcional

Python

Programación Funcional

Composición De Funciones

Python

Programación Funcional

Funciones Orden Superior Map Y Filter

Python

Programación Funcional

Funciones Auxiliares

Python

Programación Funcional

Reducción Y Acumulación

Python

Programación Funcional

Archivos Comprimidos

Python

Entrada Y Salida Io

Entrada Y Salida Avanzada

Python

Entrada Y Salida Io

Archivos Temporales

Python

Entrada Y Salida Io

Contexto With

Python

Entrada Y Salida Io

Módulo Csv

Python

Biblioteca Estándar

Módulo Json

Python

Biblioteca Estándar

Módulo Datetime

Python

Biblioteca Estándar

Módulo Math

Python

Biblioteca Estándar

Módulo Os

Python

Biblioteca Estándar

Módulo Re

Python

Biblioteca Estándar

Módulo Random

Python

Biblioteca Estándar

Módulo Time

Python

Biblioteca Estándar

Módulo Collections

Python

Biblioteca Estándar

Módulo Sys

Python

Biblioteca Estándar

Módulo Statistics

Python

Biblioteca Estándar

Módulo Pickle

Python

Biblioteca Estándar

Módulo Pathlib

Python

Biblioteca Estándar

Importar Módulos Y Paquetes

Python

Paquetes Y Módulos

Crear Módulos Y Paquetes

Python

Paquetes Y Módulos

Entornos Virtuales (Virtualenv, Venv)

Python

Entorno Y Dependencias

Gestión De Dependencias (Pip, Requirements.txt)

Python

Entorno Y Dependencias

Python-dotenv Y Variables De Entorno

Python

Entorno Y Dependencias

Acceso A Datos Con Mysql, Pymongo Y Pandas

Python

Acceso A Bases De Datos

Acceso A Mongodb Con Pymongo

Python

Acceso A Bases De Datos

Acceso A Mysql Con Mysql Connector

Python

Acceso A Bases De Datos

Novedades Python 3.13

Python

Características Modernas

Operador Walrus

Python

Características Modernas

Pattern Matching

Python

Características Modernas

Instalación Beautiful Soup

Python

Web Scraping

Sintaxis General De Beautiful Soup

Python

Web Scraping

Tipos De Selectores

Python

Web Scraping

Web Scraping De Html

Python

Web Scraping

Web Scraping Para Ciencia De Datos

Python

Web Scraping

Autenticación Y Acceso A Recursos Protegidos

Python

Web Scraping

Combinación De Selenium Con Beautiful Soup

Python

Web Scraping

Accede GRATIS a Python y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender y utilizar las constantes matemáticas predefinidas en el módulo math.
  • Aplicar funciones trigonométricas y sus inversas, incluyendo conversión entre grados y radianes.
  • Manejar funciones logarítmicas y exponenciales para modelar fenómenos de crecimiento y escalas no lineales.
  • Diferenciar y aplicar correctamente técnicas de redondeo y truncamiento numérico.
  • Implementar ejemplos prácticos que integren estas funciones en problemas reales de ingeniería, finanzas y ciencias.