Saltar al contenido principal
LibreTexts Español

3.2: Enteros y números de punto flotante

  • Page ID
    125027
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    Las computadoras digitales almacenan todos los datos en forma de bits (unos y ceros), y un número generalmente se almacena como una secuencia de bits de longitud fija. Por ejemplo, un número etiquetado como x podría referirse a una secuencia de ocho bits a partir de alguna dirección específica, como se muestra en la siguiente figura:

    clipboard_ea4f584487004a0fb45066daac69e8a61.png
    Figura\(\PageIndex{1}\): Un número de ocho bits almacenado en una variable x.

    El cuadro verde indica el conjunto de direcciones de memoria, de ocho bits de longitud, donde se almacena el número. (Los otros bits, a la izquierda y a la derecha de esta caja, podrían ser utilizados por la computadora para otros fines, o simplemente no utilizados). ¿Qué número real representa esta secuencia de ocho bits? Depende: existen dos tipos de formatos para almacenar números, llamados enteros y números de punto flotante.

    3.2.1 Enteros

    En formato entero, uno de los bits se utiliza para denotar el signo del número (positivo o negativo), y los bits restantes especifican un entero en una representación binaria. Debido a que solo hay disponible un número fijo de bits, solo se puede representar un rango finito de números enteros. En las computadoras modernas de 64 bits, los enteros generalmente se almacenan usando 64 bits, por lo que solo se pueden representar enteros\(2^{64}\) distintos. Los números enteros mínimos y máximos son

    \[n_{\mathrm{min}} \, = -2^{63}\quad = -9223372036854775808\]

    \[n_{\mathrm{max}} = 2^{63}-1 = +9223372036854775807\]

    Python es algo capaz de ocultar esta limitación a través de una característica de “entero de ancho variable”. Si los números con los que estás tratando superan los límites anteriores, puede convertir los números a un formato diferente, en el que el número de bits puede ser arbitrariamente mayor que 64 bits. Sin embargo, estos enteros de ancho variable tienen varias limitaciones. Por un lado, no se pueden almacenar en una matriz Scipy destinada a almacenar enteros estándar de ancho fijo:

    >>> n = array([-2**63])                 # Create an integer array.
    >>> n                                   # Check the array's contents.
    array([-9223372036854775808])
    >>> n.dtype                             # Check the array's data type: it should store 64-bit integers.
    dtype('int64')
    >>> m = -2**63 - 1                      # If we specify an integer that's too negative, Python makes it variable-width.
    >>> m
    -9223372036854775809
    >>> n[0] = m                            # What if we try to store it in a 64-bit integer array?
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    OverflowError: Python int too large to convert to C long
    

    Además, realizar operaciones aritméticas en enteros de ancho variable es mucho más lento que la aritmética estándar de ancho fijo. Por lo tanto, generalmente es mejor evitar tratar con enteros que son demasiado grandes o demasiado pequeños.

    3.2.2 Números de punto flotante

    Los números de punto flotante (a veces llamados flotadores) son un formato para representar aproximadamente “números reales”, números que no son necesariamente enteros. Cada número se divide en tres componentes: el “signo”, “fracción” y “exponente”. Por ejemplo, la carga de un electrón se puede representar como

    \[q \approx - 1.60217657 \times 10^{-19} = \Big(-\Big)\Big(160217657\Big) \times 10^{-27}\]

    Este número se puede almacenar así como un bit (el signo\(-\)), y dos enteros (la fracción\(160217646\) y el exponente\(-27\)). Los dos enteros se almacenan en formato de ancho fijo, por lo que el número global de punto flotante también tiene ancho fijo (64 bits en computadoras modernas). Los detalles reales de implementación de los números de punto flotante difieren del ejemplo anterior en algunas formas, notablemente, los números se representan usando potencias de\(2\) más que potencias de\(10\), pero esta es la idea básica.

    En el código Python, los números de punto flotante se especifican en notación decimal (por ejemplo, 0.000001) o notación exponencial (por ejemplo, 1e-6). Si quieres representar un entero en formato de punto flotante, dale un punto decimal final, así: 3. (o, equivalentemente, 3.0). Si realiza aritmética entre un entero y un número de punto flotante, como 2 + 3.0, el resultado es un número de punto flotante. Y si divides dos enteros, el resultado es un número de punto flotante:

    >>> a, b = 6, 3   # a and b are both integers
    >>> a/b           # a/b is in floating-point format
    2.0
    

    Nota

    En Python 2, dividir dos enteros produjo un entero redondeado. Esta es una fuente frecuente de errores, así que ten en cuenta este comportamiento si alguna vez usas Python 2.

    Imprecisión numérica

    Debido a que los números de punto flotante utilizan un número finito de bits, la gran mayoría de los números reales no se pueden representar exactamente en formato de punto flotante. Sólo se pueden aproximar. Esto da lugar a peculiaridades interesantes, como esta:

    >>> 0.1 + 0.1 + 0.1
    0.30000000000000004
    

    La razón es que el número decimal\(0.1\) no corresponde exactamente a una representación de punto flotante, así que cuando le dices a la computadora que cree un número “0.1", en su lugar se aproxima a ese número usando un número de punto flotante cuyo valor decimal es\(0.1000000000000000055511512...\)

    Debido a esta falta de precisión, no debe comparar números de punto flotante usando el operador de igualdad de Python ==:

    >>> x = 0.1 + 0.1 + 0.1
    >>> y = 0.3
    >>> x == y  
    False
    

    En lugar de usar ==, puedes comparar x e y comprobando si están más cerca de una cierta cantidad:

    >>> epsilon = 1e-6
    >>> abs(x-y) < epsilon
    True
    

    La “densidad” de números reales representados exactamente números de punto flotante disminuye exponencialmente con la magnitud del número. Por lo tanto, los números de punto flotante grandes son menos precisos que los pequeños. Por esta razón, los algoritmos numéricos (como la eliminación gaussiana) a menudo intentan evitar multiplicarse por números muy grandes, o dividir por números muy pequeños.

    Valores Especiales

    Al igual que los enteros, los números de punto flotante tienen un número máximo y mínimo que se pueden representar (esto es inevitable, ya que solo tienen un número finito de bits). Cualquier número por encima del máximo se le asigna un valor especial, inf (infinito):

    >>> 1e308
    1e+308
    >>> 1e309
    inf
    

    De igual manera, cualquier número por debajo del mínimo de punto flotante está representado por -inf. Hay otro valor especial llamado nan (not-a-number), que representa los resultados de cálculos que no tienen sentido, como “infinito menos infinito”:

    >>> x = 1e310
    >>> x
    inf
    >>> y = x - x
    >>> y
    nan
    

    Si alguna vez necesitas verificar si un número es inf, puedes usar la función isinf de Scipy. Puedes verificar si nan usando la función isnan de Scipy:

    >>> isinf(x)
    True
    >>> isnan(y)
    True
    >>> isnan(x)
    False
    

    3.2.3 Números Complejos

    Los números complejos no son un tipo de datos fundamental. Python implementa cada número complejo como un compuesto de dos números de punto flotante (las partes real e imaginaria). Puede especificar un número complejo usando la notación X+Yj:

    >>> z = 2+1j
    >>> z
    (2+1j)
    

    Las operaciones aritméticas de Python pueden manejar operaciones aritméticas en números complejos:

    >>> u = 3.4-1.2j
    >>> z * u
    (8+1j)
    >>> z/u
    (0.4307692307692308+0.44615384615384623j)
    

    Puede recuperar las partes reales e imaginarias de un número complejo usando las ranuras .real y .imag:

    >>> z.real
    2.0
    >>> z.imag
    1.0
    

    Alternativamente, puedes usar las funciones real e imag de Scipy (que también funcionan en matrices). Del mismo modo, las funciones absolutas (o abs) y angulares devuelven la magnitud y el argumento de un número complejo:

    >>> z = 2+1j
    >>> real(z)
    array(2.0)
    >>> imag(z)
    array(1.0)
    >>> absolute(z)
    2.2360679774997898
    >>> angle(z)
    0.46364760900080609
    

    This page titled 3.2: Enteros y números de punto flotante is shared under a CC BY-SA 4.0 license and was authored, remixed, and/or curated by Y. D. Chong via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.