5 de febrero de 2018

Unidades de Información.

  • La unidad básica de información en una computadora digital es llamada bit (por binary digit) , la cuál consiste en un sólo carácter 0 ó 1.
  • En 1964, desarrolladores trabajando para IBM establecieron la convención de llamar byte a grupos de 8 bits.
  • Bajo una arquitectura, una palabra (word) es un grupo de bytes usado como unidad por el sistema.
    • A través de los años se han usado varios tamaños de palabra.
    • Las computadoras personales modernas (ej. x86, x86-64, ARMv6 y ARMv8-A) usan palabras de tamaño 32 y 64 bits (4 y 8 bytes respectivamente).

Tipos Primitivos

Los tipos primitivos de datos de un lenguaje de programación son aquellos que ofrece la especificación del mismo como punto de partida para empezar a programar. Sobre estos se construye los tipos de datos compuestos y demás estructuras de datos.

En C se classifican:

Número Sr. Tipo Descripción
1 Básicos Son de naturaleza aritmética y se dividen en tipos enteros y de punto flotante.
2 De tipo Void Se usa para declarar un valor vacío o nulo.
3 Derivados Incluyen apuntadores, arreglos, estructuras, funciones y uniones.

Tipos Enteros 1

Tipo Tamaño Rango
char 1 byte [0, 255] ó [-128, 127]
unsigned char 1 byte [0, 255]
signed char 1 byte [-128, 127]
int 2 ó 4 bytes [-32 768, 32 767] ó [-2 147 483 648, 2 147 483 647]
unsigned int 2 bytes [-32 768, 32 767]
short 2 bytes [0, 65 535]

Tipos Enteros 2

Tipo Tamaño Rango
unsigned short 1 byte [0, 65 535]
long 4 bytes [-2 147 483 648, 2 147 483 647]
unsigned long 4 bytes [0, 4 294 967 295]

Tipos Flotantes

Tipo Tamaño Valor de Rango Precisión
float 4 bytes 1.2E-38 a 3.4E+38 6 dígitos decimales
double 8 bytes 2.3E-308 a 1.7E+308 15 dígitos decimales
long double 10 bytes 3.4E-4932 a 1.1E+4932 19 dígitos decimales

Representación en Memoria: int

Le representación de un número en memoria int n en memoria es de la siguiente forma:

  • Si n es un entero positivo, entonces su representación es el número en notación binaria con los ceros a la izquierda que sean necesarios para completar los 32 (ó 16) bits.

  • Si n es un entero negativo, entonces su representación es su complemento a dos.
    • El complemento a dos se define como el número \(\alpha\) tal que \(2^{32}= n + \alpha\).
    • Si \(n\) es negativo, el complemento a dos es \[\alpha = 2^{32}-|n|,\] donde \(|n|\) es el valor absoluto de \(n\).

Representación en Memoria: float

La notación científica (base 10) de un numero real define como \(m\times{}10^c\), donde:

  • \(m\) es llamado el significando, mantisa o coeficiente.

  • \(c\) es el exponente, orden o magnitud del número.

El estándar IEEE-754 (IEEE Standard for Floating-Point Arithmetic) se estableció en 1985 y e índica un formato ampliamente usado para representar números de punto flotante en memoria. En particular, para binary32 (float en C):

Representación en Memoria 2: float

Donde:

  • El exponente cuenta con un desplazamiento de 127 (\(2^8-1\)) o 1023 (\(2^{11}-1\)).
    • En 8 bits tenemos un valor en binario entre 1 a 254, con 0 y 255 reservados.
    • Para centrar el segmento [-126,127] le sumamos 127.
  • El primer bit de la mantisa siempre se asume como 1.

Representación en Memoria 3: float

Por ejemplo:

Consideremos al número 3.1416

Signo: 0

Ahora, debemos encontrar \(x\) y \(y\) tales que \(3.1416 = (-1)^0(1+x)\times{}2^y\) y \(x<1\).

Dividimos a 3.1416 entre una potencia de dos hasta obtener un número de la forma \(1+x\): \[3.1416/2^1 = 1.5708,\] de donde \(y=1\)

Exponente \(= 1 + 127 = 128 = 10 000 000_2\)

y

Ejemplo continua…

Además tenémos que \[1.5708 = 1.10010010000111111111001.._2,\]

lo que implíca:

Mantisa \(= 1001 0010 0001 1111 1111 001.\)

De donde, el número en memoría es:

0 10000000 10010010000111111111001.

Sobre caracteres, enteros y flotantes.

Es importante enfatizar que en C tenemos solamente dos tipos de datos primitivos:

Números enteros. Números de punto flotante.

Los caracteres son en realidad números enteros de 8 bits (de 0 a 255) y, como números enteros, podemos realizar operaciones aritméticas con ellos.

En particular, el lenguaje C no maneja cadenas de caracteres (strings en ingles) de forma nativa, usando en su lugar la estructura de datos compuestos conocidos como arreglos (arrays).

Ejemplo: caracter + entero.

Por ejemplo, el siguiente programa :

#include <stdio.h>

int main()
{
    char c = 63, 
    int y = 1;
    
    printf("El caracter es: %c \n", c+y);
    
}

Produce la salida:

El caracter es: @

.

Ejemplo: caracter por flotante.

Más aun, el siguiente código

#include <stdio.h>

int main()
{
    char c = 'A';
    float e =  2.71828;
    
    printf("El numero es: %g \n", (e*c)/c);
    
}

produce la salida:

El numero es: 2.71828

.

Tipificación débil

Coloquialmente, los lenguajes de programación se suelen clasificar en débilmente y fuertemente tipificados. Podemos decir que los lenguajes son fuertemente tipificados cuando se requiere que los argumentos de una función u operación coincidan con la definición de la última al momento de querer compilar (o interpretar) el código escrito.

Bajo este contexto, podemos argumentas que el lenguaje C tiene una tipificación débil, ya que aunque requiere una declaración de tipo para todas las variables, podemos operar con distintos tipos de memoria sin realizar una transformación de tipo de memoria por medio de punteros. Esta característica tiene sus ventajas y desventajas.

Es importante señalar que no existe un consenso con respecto a la caracterización dada expresa mi opinión sobre el lenguaje.