¿Pueden los registros de la CPU representar números reales?

Oh, la locura de nuestras convenciones de nombres.

Decimos “números reales”, por lo que las personas (naturalmente) creen que son reales . Luego llamamos a esos otros “números imaginarios”, por lo que las personas (naturalmente) suponen que son imaginarios, es decir, no reales. Y los “números trascendentales” son de alguna manera trascendentales. Y “números irracionales”, ¡deben estar locos!

Nada de esto es verdad.

La gran mayoría de los números reales no son “reales” en ningún sentido físico. Eso no quiere decir que no sean útiles: el sistema de números reales es una de las abstracciones más profundamente útiles para comprender el mundo físico. Pero casi ninguno de sus miembros, los números reales, son “reales”.

Olvídese de los registros de la CPU: la gran mayoría de los números reales no pueden ser representados por una computadora. No importa dónde intente almacenarlos: registros de CPU, memoria, disco duro, todas las nubes de Google y Amazon juntas, un solo número real no cabe en ninguno de esos lugares, excepto por una pequeña minoría de ellos.

Entonces no. La respuesta es no. Los registros de la CPU no pueden representar números reales. Las computadoras pueden almacenar, manipular y representar objetos con una descripción finita , y los números reales casi nunca tienen una descripción finita.

Los números naturales tienen una descripción finita, por lo que los registros de la CPU ciertamente pueden representar números naturales. La mayoría de los números naturales requerirían más memoria para representarlos que la que está disponible en cualquier computadora real, pero está bien; todavía podemos representar números naturales pequeños perfectamente bien, donde por “pequeño” quiero decir “realmente grande en términos cotidianos”. Un registro de CPU puede almacenar fácilmente una representación de 3, o -23, o 4,294,967,296.

Con los números reales, la situación es diferente, ya que la mayoría de los números reales, independientemente de su magnitud, requieren una cantidad infinita de información para describir. Por el contrario, el número “imaginario” [matemático] i = \ sqrt {-1} [/ matemático] se puede representar en una computadora muy bien, por eso la nomenclatura alrededor de “real” e “imaginario” es tan engañosa.

Una vez que acordamos un esquema de representación adecuado, las piezas de memoria de la computadora (como los registros de la CPU) pueden representar y manipular con éxito:

  • Números naturales como 0, 1, 2, 3, 4, …
  • Enteros como -1, -2, -3, -4, …
  • Números racionales como [matemática] \ frac {355} {113} [/ matemática] o [matemática] 3.1415 [/ matemática]
  • Números algebraicos como [math] 7+ \ sqrt {-17} [/ math] o [math] \ sqrt {5- \ sqrt [3] {12}} [/ math]
  • Números elementales (en el sentido de Tim Chow) como [matemáticas] e, \ sqrt {\ pi} [/ matemáticas] o [matemáticas] i + \ log (1 + e ^ {2/3}) [/ matemáticas]
  • Números hipercerrados (en el sentido de Borwein y Crandall) como [math] \ zeta (7) [/ math] o [math] J_5 (\ sqrt {2}) [/ math], donde [math] \ zeta [/ math ] es la función zeta de Riemann y [math] J_n [/ math] es una función de Bessel.
  • Números ordinales (con forma normal finita de Cantor) como [math] \ omega ^ {\ omega ^ \ omega} \ cdot 19+ \ omega ^ 2 + 5 [/ math].
  • Números surrealistas (en el sentido de Conway) con descripciones finitas, como [matemática] 1 / \ omega [/ matemática] y [matemática] \ sqrt {\ pi + \ omega} [/ matemática].

Muchos de estos números “representables” van mucho más allá del ámbito de los números reales. Se diría que algunos de ellos son “infinitos” porque exceden en magnitud cualquier número natural (o pueden ser infinitamente pequeños). Algunos son complejos, por lo que ni siquiera tienen una relación de orden con los números reales. La magnitud de un número (o su ausencia) no importa mucho; lo único que importa es que tiene una descripción finita, y con un poco de imaginación podemos dejar que nuestros esquemas de representación capturen mucho que parece completamente irreal, mientras que nunca podrían capturar todo lo que se llama “real”.

Cuando intente evaluar si el registro de la CPU puede hacer lo que necesita, debe considerar lo que importa sobre los números que desea manipular. Si realmente necesita poder representar números reales arbitrarios, no tiene suerte, pero es poco probable que realmente lo necesite. Para fines prácticos, una de las familias mencionadas anteriormente debería ser más que suficiente.

(frontispicio de “Con números y juegos” de Conway).

Un registro puede contener un número fijo de bits .

En cierto sentido, eso es todo lo que hay que hacer. La forma de interpretar estos bits depende totalmente de usted. Nada en el registro en sí mismo le dice que está sosteniendo un número entero, un número de coma flotante o incluso un puntero (que, semánticamente, no es un número per se ).

Entonces, ¿qué puede representar un registro? Cualquier cosa que pueda expresar útilmente en [matemáticas] 2 ^ {64} [/ matemáticas] símbolos distintos. Lo cual es, en el gran esquema de las cosas, no tanto. (En particular, es decididamente finito ) .

¿Podemos usar esto para trabajar con números reales? ¡Seguro! Números reales como 1 o 2, por ejemplo. O incluso números reales como 1.5 o 1034.34. Pero solo podemos trabajar con un conjunto pequeño y finito de estos a la vez. El conjunto exacto al que podemos acceder depende de nuestra codificación, de cómo leemos y escribimos números como n bits, pero siempre hay una compensación entre lo precisos que podemos ser y cuán amplio es el rango de números que podemos expresar. Si nos limitamos a un pequeño rango de números, podemos incluir algunos muy cercanos en nuestro presupuesto [matemático] 2 ^ {64} [/ matemático]; si queremos abarcar un amplio rango (digamos mucho más amplio que [math] 2 ^ {64} [/ math]), inevitablemente nos separaremos bastante.

En la práctica, aquí están las codificaciones que se usan con mayor frecuencia con el rango que pueden cubrir en 64 bits:

  • enteros sin signo : podemos expresar enteros desde [matemática] 0 [/ matemática] a [matemática] 2 ^ {64} – 1 [/ matemática], inclusive. Todos estos son números reales, ¡pero sospecho que eso no es lo que querías decir!
  • enteros con signo : la misma idea, excepto que necesitamos gastar un poco en el signo. Como [math] 0 [/ math] y [math] -0 [/ math] son ​​iguales, obtenemos un número adicional en un extremo de nuestro rango, lo que nos da de [math] -2 ^ {63} [/ math ] a [matemáticas] 2 ^ {63} – 1 [/ matemáticas], inclusive.
  • números de punto fijo : números con un punto decimal preestablecido. Hablando en términos generales, es como tomar los enteros que codificamos arriba y simplemente leerlos como si tuvieran un punto decimal: 11101, 10111 y 10001 podrían convertirse en 111.01, 101.11 y 100.01 respectivamente.

    Esto deja en claro el equilibrio general: tenemos menos rango (ya que todos nuestros números están divididos por algo) pero cada número está más cerca.

  • números de coma flotante : esta es la codificación común más complicada con diferencia, y la aproximación más cercana a los números reales con los que trabajamos habitualmente. Los números de coma flotante codifican un amplio rango² (algo así como [matemáticas] 5 \ veces 10 ^ {- 324} [/ matemáticas] a [matemáticas] 10 ^ {308} [/ matemáticas] en 64 bits) con un nivel de precisión que cambia dependiendo del tamaño del número. (Es por eso que se llaman números de coma flotante ). Esencialmente, cuanto más pequeño sea su número, más precisamente podrá almacenarlo.

    Los números en coma flotante son lo que probablemente obtienes cuando usas tu calculadora o divides algo en un lenguaje de programación normal. Para las cosas comunes del día a día, realmente se sienten como números reales.

Los números en coma flotante parecen mágicos, pero recuerde: llevan exactamente tanta información como un humilde int . 64 bits y eso es todo. Cubren un rango más amplio al ser menos precisos; todavía hay [math] 2 ^ {64} [/ math] valores distintos que pueden asumir. (De hecho, es aún peor que eso porque el punto flotante también tiene un montón de valores llamados NaN que no representan ningún número). Hacer frente a este hecho es una gran parte de un campo completo de matemática aplicada: análisis numérico.

Entonces, si su pregunta era si un registro podría contener algún número real, la respuesta es no. Hay muchos números reales, mucho más que [matemáticas] 2 ^ {64} [/ matemáticas]. De hecho, hay mucho más que todos los programas posibles que podríamos ejecutar, o cualquier información posible con la que podamos trabajar en una computadora. Los verdaderos números reales están fundamentalmente más allá del cálculo, al menos las computadoras digitales.

notas al pie
¹ Bueno, nada normalmente. Algunos sistemas (máquinas Lisp, famoso) reservaron algunos bits para decirle si tenía un puntero o un dato de algún tipo, pero las arquitecturas modernas no.

² Técnicamente, los números de coma flotante nos permiten codificar [math] \ infty [/ math] y [math] – \ infty [/ math] para que el rango sea infinito, pero esta no es una observación útil. El rango de números finitos que podemos expresar es, de hecho, finito.

¿Pueden los registros de la CPU representar números reales?

En general, las computadoras y los lenguajes de computadora tienen un tipo variable “incorporado” de punto flotante, usado para aproximar la entidad matemática de un número real, y en algunos idiomas a los que se hace referencia con el nombre de tipo “real”.

Para algunos números racionales, la representación será exacta, pero para la mayoría de los números reales será una aproximación de manera similar que [math] \ frac17 [/ math] solo se aproxima por la representación decimal [math] 0.142857 [/ math].

Ahora, todas las computadoras tienen las capacidades de una entidad abstracta llamada máquina de Turing. Como resultado, pueden representar todo tipo de algoritmos finitos. Si su número real es un número real definible, entonces podemos representar esa definición en la computadora. Probablemente también podamos hacer aritmética en esas representaciones, de modo que produzcamos una multiplicación real exacta, por ejemplo. Es probable que todo esto se haga en el software de varias capas de computadora por encima de la CPU, pero, en principio, podría integrarse en la CPU.

Una computadora elegante que tenía una forma de representar números reales matemáticos realmente está haciendo álgebra en lugar de aritmética. Es más parecido a la computación simbólica que a tu calculadora.

En general, solo aproximadamente y suponiendo que el número no es ni demasiado grande ni demasiado pequeño. Los números reales irracionales nunca se pueden representar exactamente. Muchos números reales racionales se pueden representar exactamente. Hay números demasiado grandes para representar incluso con coma flotante. Hay números tan pequeños que 0.0 es la mejor aproximación posible.

Claro, incluso si la CPU no tiene instrucciones de números reales, puede escribir subrutinas que realicen operaciones reales y las que usen registros enteros, varias de ellas.

Las CPU más nuevas y spiffier tienen un conjunto separado de registros de punto flotante.

Depende de la arquitectura de la máquina, pero Intel / AMD ha tenido esto (en algunos modelos) desde el 387 en 1987. En 1999, la extensión SSE dio números de 128 bits.

Los chips ARM 32 tienen un número variable de registros de coma flotante, y los chips ARM64 / 32 tienen 32 de ellos.

No todos ellos, aunque puede elegir representar un subconjunto finito de ellos.