Un formato de número de computadora es la representación interna de valores numéricos en hardware y software de dispositivos digitales, como en computadoras programables y calculadoras . [1] Los valores numéricos se almacenan como agrupaciones de bits , como bytes y palabras. La codificación entre valores numéricos y patrones de bits se elige para la conveniencia del funcionamiento de la computadora; [ cita requerida ] la codificación utilizada por el conjunto de instrucciones de la computadora generalmente requiere conversión para uso externo, como para impresión y visualización. Diferentes tipos de procesadores pueden tener diferentes representaciones internas de valores numéricos y se utilizan diferentes convenciones para números enteros y reales. La mayoría de los cálculos se llevan a cabo con formatos de números que encajan en un registro de procesador, pero algunos sistemas de software permiten la representación de números arbitrariamente grandes utilizando múltiples palabras de memoria.
Las computadoras representan los datos en conjuntos de dígitos binarios. La representación está compuesta por bits, que a su vez se agrupan en conjuntos más grandes, como los bytes.
Un bit es un dígito binario que representa uno de dos estados . El concepto de bit puede entenderse como un valor de 1 o 0 , encendido o apagado , sí o no , verdadero o falso , o codificado por un interruptor o palanca de algún tipo.
Si bien un solo bit, por sí solo, puede representar solo dos valores, se puede utilizar una cadena de bits para representar valores mayores. Por ejemplo, una cadena de tres bits puede representar hasta ocho valores distintos, como se ilustra en la Tabla 1.
A medida que aumenta el número de bits que componen una cadena, el número de posibles combinaciones de 0 y 1 aumenta exponencialmente . Un solo bit permite solo dos combinaciones de valores, dos bits combinados pueden formar cuatro valores separados, tres bits ocho, y así sucesivamente, aumentando con la fórmula 2 n . La cantidad de combinaciones posibles se duplica con cada dígito binario agregado, como se ilustra en la Tabla 2.
Las agrupaciones con un número específico de bits se utilizan para representar cosas variables y tienen nombres específicos.
Un byte es una cadena de bits que contiene la cantidad de bits necesarios para representar un carácter . En la mayoría de las computadoras modernas, esta es una cadena de ocho bits. Debido a que la definición de un byte está relacionada con la cantidad de bits que componen un carácter, algunas computadoras más antiguas han usado una longitud de bits diferente para su byte. [2] En muchas arquitecturas de computadora , el byte es la unidad direccionable más pequeña , el átomo de direccionabilidad, digamos. Por ejemplo, aunque los procesadores de 64 bits pueden direccionar la memoria de sesenta y cuatro bits a la vez, aún pueden dividir esa memoria en partes de ocho bits. Esto se llama memoria direccionable por bytes. Históricamente, muchas CPU leen datos en algún múltiplo de ocho bits. [3] Debido a que el tamaño de byte de ocho bits es tan común, pero la definición no está estandarizada, el término octeto a veces se usa para describir explícitamente una secuencia de ocho bits.
Un nibble (a veces nybble ) es un número compuesto por cuatro bits. [4] Al ser medio byte , el nibble recibió su nombre como un juego de palabras. Una persona puede necesitar varios nibbles para un bocado de algo; de manera similar, un nybble es una parte de un byte. Debido a que cuatro bits permiten dieciséis valores, un nibble a veces se conoce como dígito hexadecimal . [5]
La codificación octal y hexadecimal son formas convenientes de representar números binarios, como los que utilizan las computadoras. Los ingenieros informáticos a menudo necesitan escribir cantidades binarias, pero en la práctica escribir un número binario como 1001001101010001 es tedioso y propenso a errores. Por lo tanto, las cantidades binarias se escriben en un formato numérico de base 8 u "octal" o, mucho más comúnmente, en un formato numérico de base 16, "hexadecimal" ( hex ). En el sistema decimal, hay 10 dígitos, del 0 al 9, que se combinan para formar números. En un sistema octal, solo hay 8 dígitos, del 0 al 7. Es decir, el valor de un "10" octal es el mismo que el de un "8" decimal, un "20" octal es el de un "16" decimal, y así sucesivamente. En un sistema hexadecimal, hay 16 dígitos, del 0 al 9, seguidos, por convención, de la A a la F. Es decir, un "10" hexadecimal es lo mismo que un "16" decimal y un "20" hexadecimal es lo mismo que un "32" decimal. En la siguiente tabla se describe un ejemplo y una comparación de números en diferentes bases.
Al escribir números, se utilizan caracteres de formato para describir el sistema numérico, por ejemplo, 000_0000B o 0b000_00000 para binarios y 0F8H o 0xf8 para números hexadecimales.
Cada uno de estos sistemas numéricos es un sistema posicional, pero mientras que los pesos decimales son potencias de 10, los pesos octales son potencias de 8 y los pesos hexadecimales son potencias de 16. Para convertir de hexadecimal u octal a decimal, para cada dígito se multiplica el valor del dígito por el valor de su posición y luego se suman los resultados. Por ejemplo:
El formato de punto fijo puede ser útil para representar fracciones en binario.
Para almacenar las partes fraccionarias y enteras de un número, se debe elegir la cantidad de bits necesaria para la precisión y el rango deseados. Por ejemplo, si se utiliza un formato de 32 bits, se pueden utilizar 16 bits para el entero y 16 para la fracción.
El bit del ocho va seguido del bit del cuatro, luego del bit del dos, luego del bit del uno. Los bits fraccionarios continúan el patrón establecido por los bits enteros. El siguiente bit es el bit de la mitad, luego el bit del cuarto, luego el bit del ⅛, y así sucesivamente. Por ejemplo:
Esta forma de codificación no puede representar algunos valores en binario. Por ejemplo, la fracción 1/5, 0,2 en decimal, las aproximaciones más cercanas serían las siguientes:
Incluso si se utilizan más dígitos, es imposible una representación exacta. El número 1/3 , escrito en decimal como 0,333333333..., continúa indefinidamente. Si se termina prematuramente, el valor no representaría 1/3 precisamente.
Si bien en los sistemas digitales se utilizan números enteros con y sin signo, ni siquiera un número entero de 32 bits es suficiente para manejar todo el rango de números que puede manejar una calculadora, y eso sin incluir las fracciones. Para aproximarnos al mayor rango y precisión de los números reales , tenemos que abandonar los números enteros con signo y los números de punto fijo y pasar a un formato de " punto flotante ".
En el sistema decimal, estamos familiarizados con números de punto flotante de la forma ( notación científica ):
o, de forma más compacta:
que significa "1,1030402 por 1 seguido de 5 ceros". Tenemos un valor numérico determinado (1,1030402) conocido como " mantisa ", multiplicado por una potencia de 10 (E5, que significa 10 5 o 100.000), conocida como " exponente ". Si tenemos un exponente negativo, eso significa que el número se multiplica por un 1 que se encuentra a la derecha del punto decimal. Por ejemplo:
La ventaja de este esquema es que al utilizar el exponente podemos obtener un rango mucho más amplio de números, incluso si el número de dígitos en la mantisa, o la "precisión numérica", es mucho menor que el rango. Se pueden definir formatos binarios de punto flotante similares para computadoras. Existe una serie de esquemas de este tipo, el más popular ha sido definido por el Instituto de Ingenieros Eléctricos y Electrónicos (IEEE). La especificación estándar IEEE 754-2008 define un formato de punto flotante de 64 bits con:
Con los bits almacenados en 8 bytes de memoria:
donde "S" denota el bit de signo, "x" denota un bit de exponente y "m" denota un bit de significación. Una vez extraídos los bits, se convierten con el siguiente cálculo:
Este esquema proporciona números válidos hasta aproximadamente 15 dígitos decimales, con el siguiente rango de números:
La especificación también define varios valores especiales que no son números definidos y que se conocen como NaN ( por sus siglas en inglés, Not A Number). Los programas los utilizan para designar operaciones no válidas y similares.
Algunos programas también utilizan números de coma flotante de 32 bits. El esquema más común utiliza una mantisa de 23 bits con un bit de signo, más un exponente de 8 bits en formato "exceso-127", lo que da siete dígitos decimales válidos.
Los bits se convierten en un valor numérico con el cálculo:
lo que da como resultado el siguiente rango de números:
Estos números de punto flotante se conocen como "reales" o "flotantes" en general, pero con una serie de variaciones:
A un valor flotante de 32 bits a veces se le denomina "real32" o "single", que significa "valor de punto flotante de precisión simple".
A un número flotante de 64 bits a veces se le denomina "real64" o "double", que significa "valor de punto flotante de doble precisión".
La relación entre números y patrones de bits se elige por conveniencia en la manipulación informática; ocho bytes almacenados en la memoria de la computadora pueden representar un número real de 64 bits, dos números reales de 32 bits, o cuatro enteros con o sin signo, o algún otro tipo de datos que quepan en ocho bytes. La única diferencia es cómo los interpreta la computadora. Si la computadora almacenara cuatro enteros sin signo y luego los leyera de nuevo desde la memoria como un número real de 64 bits, casi siempre sería un número real perfectamente válido, aunque sería información basura.
Solo un rango finito de números reales puede representarse con una cantidad dada de bits. Las operaciones aritméticas pueden desbordarse o desbordarse, generando un valor demasiado grande o demasiado pequeño para ser representado.
La representación tiene una precisión limitada. Por ejemplo, solo se pueden representar 15 dígitos decimales con un número real de 64 bits. Si se suma un número de punto flotante muy pequeño a uno grande, el resultado es solo el grande. El número pequeño era demasiado pequeño para aparecer siquiera en 15 o 16 dígitos de resolución, y la computadora lo descarta de manera efectiva. Analizar el efecto de la precisión limitada es un problema bien estudiado. Las estimaciones de la magnitud de los errores de redondeo y los métodos para limitar su efecto en cálculos grandes son parte de cualquier proyecto de computación grande. El límite de precisión es diferente del límite de rango, ya que afecta a la mantisa, no al exponente.
La mantisa es una fracción binaria que no necesariamente coincide perfectamente con una fracción decimal. En muchos casos, la suma de potencias recíprocas de 2 no coincide con una fracción decimal específica y los resultados de los cálculos serán ligeramente diferentes. Por ejemplo, la fracción decimal "0,1" es equivalente a una fracción binaria que se repite infinitamente: 0,000110011 ... [6]
La programación en lenguaje ensamblador requiere que el programador lleve un registro de la representación de los números. Cuando el procesador no admite una operación matemática requerida, el programador debe elaborar un algoritmo y una secuencia de instrucciones adecuados para llevar a cabo la operación; en algunos microprocesadores, incluso la multiplicación de números enteros debe realizarse mediante software.
Los lenguajes de programación de alto nivel, como Ruby y Python, ofrecen un número abstracto que puede ser un tipo expandido, como racional , bignum o complejo . Las operaciones matemáticas se llevan a cabo mediante rutinas de biblioteca proporcionadas por la implementación del lenguaje. Un símbolo matemático dado en el código fuente, mediante la sobrecarga de operadores , invocará un código objeto diferente apropiado para la representación del tipo numérico; las operaciones matemáticas sobre cualquier número (ya sea con signo, sin signo, racional, de punto flotante, de punto fijo, integral o complejo) se escriben exactamente de la misma manera.
Algunos lenguajes, como REXX y Java , proporcionan operaciones de punto flotante decimal, que generan errores de redondeo de una forma diferente.
La versión inicial de este artículo se basó en un artículo de dominio público del sitio Vectorsite de Greg Goebel.