Tipos de datos en C

Anuncio
Algoritmos y Lenguaje de Programación,
Sección 1
Tipos de datos en C
Tipos de Datos
• Representación de datos en C está relacionada
con la arquitectura del computador
)Memoria se direcciona por bytes
)Procesadores tienen registros de 1, 2, 4, 8 bytes
Mario Medina C.
mariomedina@udec.cl
• Un dato cualquiera tiene
)Un tipo (caracter, entero, punto flotante)
)Un valor (que puede ser indeterminado)
)Una posición de memoria donde está almacenado
Tipo de dato char
Tipo de dato short int
• Al menos 8 bits
• Al menos 16 bits
• Puede abreviarse a short
• Rangos mínimos
)Debe poder almacenar un caracter ASCII
• Rangos mínimos
)signed char: -128 a 127
)unsigned char: 0 a 255
)short: -32768 (-215) a 32767 (215 – 1)
)unsigned short: 0 a 65535 (216 - 1)
• Rango de char depende del compilador
)Por omisión, char puede ser signed o
unsigned
Tipo de dato int
• Al menos 16 bits
• Rangos mínimos
)int: -32768 (-215) a 32767 (215 – 1)
)unsigned int: 0 a 65535 (216 - 1)
• 16 bits, 32 bits o 64 bits?
)A elección de la implementación
)Generalmente tamaño de registros de CPU
©Mario Medina C.
Tipo de dato long int
• Al menos 32 bits
• Puede abreviarse como long
• Rangos mínimos
)long: -2147483648 (-231) a 2147483647 (231 –
1)
)unsigned long: 0 a 4294967295 (232 – 1)
1
Algoritmos y Lenguaje de Programación,
Sección 1
Tipo de dato long long int
Archivo<limits.h>
• Al menos 64 bits
• Puede abreviarse como long long
• Introducido en estándar ISO C99
• Rangos mínimos
• Archivo que define los límites usados por el
compilador
-263
263
)long long:
a
–1
)unsigned long long: 0 a 264 – 1
Constantes en <limits.h>
Tipo
Min.
signed
Max.
signed
Max.
unsigned
char
SCHAR_MIN SCHAR_MAX UCHAR_MAX
short
SHRT_MIN
SHRT_MAX
USHRT_MAX
int
INT_MIN
INT_MAX
UINT_MAX
long
LONG_MIN
LONG_MAX
ULONG_MAX
)Residente en \Dev-Cpp\include
• Define rangos de los tipos de datos
)CHAR_BIT: número de bits por byte
` 8 bits
)CHAR_MIN: valor mínimo para char
)CHAR_MAX: valor máximo para char
Operador sizeof()
• Operador retorna el tamaño de un tipo de
datos en bytes
)sizeof(long) ≥ sizeof(int) ≥
sizeof(short)
)sizeof(char) = 1
)sizeof(short) = 2
)sizeof(long) = 4
)sizeof(int) = 2, 4 o 8
)sizeof(long long) = 8
Constantes char
Constantes enteras
• Letras, números y símbolos ASCII son
constantes de tipo char
• Números tienen tipo int por omisión
)‘A’ = ASCII 65
)‘F’ = ASCII 70
)‘A’ + ‘F’ = 135
)‘\t’: tab (ASCII 9)
)‘\n’: avance de línea (ASCII 13)
)‘\0’: ASCII 0 (no confundir con ‘0’: ASCII 48)
©Mario Medina C.
)Números long int se especifican con L ó l
)234: tipo int
)234U: tipo unsigned int
)234L: tipo long int
• Números hexadecimales precedidos de 0x
)0x234 = 23416 = 56410
• Números octales precedidos de 0
)0234 = 2348 = 15610
2
Algoritmos y Lenguaje de Programación,
Sección 1
Porqué usar constantes?
Promoción de enteros
• Conveniencia y claridad en el código
• Código puede mezclar tipos
• El tipo más corto es promovido al tipo mayor
antes de la operación
• Promoción no pierde información
• ‘B’ + 5 ⇒ char + int
numero = numero – 48;
numero = numero – 060;
numero = numero – ‘0’;
• Todos hacen lo mismo
)Todos corresponden a la misma secuencia de
bits: 001110002
Rebalse de enteros
int k;
(k * 1024);
• Qué pasa si int es de 16 bits?
)Si k es menor de 32, resultado cabe en 16 bits
)Si k es mayor de 32, rebalse!
)Este es un error de tiempo de ejecución
• Solución: usar constante long y promoción
k * 1024L;
Rebalse en sumas en C
)Resultado es de tipo int
Curiosidades del C
• 0 igual a 0U: Verdadero
• -1 < 0: Verdadero
• -1 < 0U: Falso
)Operación se realiza en aritmética sin signo
• 2147483647 > -2147483647 - 1: V
• 2147483647U > -2147483647 - 1: F
)Operación se realiza en aritmética sin signo
• 2147483647 > (int) 2147483648U: V
)Cast convierte número sin signo a con signo
Rebalse en suma sin signo
• Rebalse (Overflow) se produce si resultado de
suma excede capacidad de representación del
tipo de datos
)Operación se transforma en aritmética modular
• Aritmética entera con signo
)Puede ocurrir rebalse positivo
• Aritmética con signo (complemento a 2)
)Pueden ocurrir rebalses positivos y negativos
©Mario Medina C.
3
Algoritmos y Lenguaje de Programación,
Sección 1
Rebalse en suma con signo
Ejercicios de enteros
T w o 's c o m p le m e n t a d d itio n (4 -b it w o rd )
8
6
4
2
0
6
-2
4
2
-4
0
-6
-2
-8
-4
-8
-6
-4
-6
-2
0
2
4
• Indique si estas
aseveraciones 1. x < 0 implica (x*2) < 0
2. ux >= 0
son V ó F
3. x&7==7 implica (x<<30) < 0
)Suponga
4. ux > -1
int x;
5. x > y implica –x < -y
int y;
6. x*x >= 0
unsigned ux;
7. x>0 && y>0 implica x+y > 0
8. x >= 0 implica –x <= 0
9. x <= 0 implica –x >= 0
-8
6
Enumeraciones
Enumeraciones
• Permite definir secuencias de enteros
• Usa constantes simbólicas
• Enumeración siempre comienza en 0
)enum dias {LUNES, MARTES, MIERCOLES,
JUEVES, VIERNES, SABADO, DOMINGO};
)Una vez definidas, no se deben redefinir!
• Equivalente a
)int LUNES = 0, MARTES = 1, MIERCOLES
= 2, JUEVES = 3, VIERNES = 4, SABADO
= 5, DOMINGO = 6;
Punto flotante
• Números decimales representados en
codificación llamada “punto flotante”
)Pueden darse valores explícitamente
)Puede usar números enteros positivos y negativos
)Constantes no especificadas toman valor de
constante anterior + 1
)enum numeros {UNO = 1,DOS, CUATRO =
4, CINCO, OCHO = 8};
)X = CINCO + OCHO; /* X vale 13 */
Archivo <float.h>
Tipo
Mínimo
` Tamaño típico: 32 bits
float
FLT_MIN
FLT_MAX
)double: precisión doble
double
DBL_MIN
DBL_MAX
Long double
LDBL_MIN
LDBL_MAX
)float: precisión simple
` Tamaño típico: 64 bits
Máximo
)long double: precisión extendida
` Tamaño típico: 80 bits
©Mario Medina C.
4
Algoritmos y Lenguaje de Programación,
Sección 1
Rangos de tipos (aproximados)
Constantes de punto flotante
• float
• Números con punto decimal tienen tipo
double por omisión
)10-38 ≤ float ≤ 1038
)-1038 ≤ float ≤ -10-38
)2.3421: tipo double
• double
• Números float se especifican con F ó f
)10-308 ≤ double ≤ 10308
)-10308 ≤ double ≤ -10-308
)2.3421f: tipo float
• long double
≤ long double ≤
)-104932 ≤ long double ≤ -10-4932
)10-4932
104932
• Números long double se especifican con L
ól
)2.3421L: tipo long double
Constantes de punto flotante
Aritmética de punto flotante
• Pueden especificarse también en notación
científica
• Actualmente, en forma generalizada, se usa
formato IEEE-754
• Codifica números de la forma (-1)s·0.m·2e
)2.34e21 equivalente a 2.34x1021
)6.02e-23 equivalente a 6.02x10-23
• Constantes también pueden ser números
hexadecimales
)0x14p10 equivalente a 20x210 = 2048010
` P indica exponente binario
)s corresponde al signo
)m corresponde a la mantisa
)e corresponde al exponente
• En computación, siempre se usa base 2
• Exponente e puede ser positivo o negativo
Números de precisión simple
Números de precisión doble
• Precisión simple (float) utiliza 32 bits
• Precisión simple (double) utiliza 64 bits
)1 bit de signo s, 23 de mantisa m y 8 de
exponente e
)1 bit de signo s, 52 de mantisa m y 11 de
exponente e
• Exponente e va entre -126 y +127
)Codificado como e+127
• Mantisa m toma valores 0 ≤ m < 1
)Parte fraccionaria f es 1+ m (“1 implícito”)
• Exponente e va entre -1022 y +1023
)Codificado como e+1023
• Mantisa m toma valores 0 ≤ m < 1
)Parte fraccionaria f es 1+ m (“1 implícito”)
• Estos son los valores normalizados
)No representan el 0!
©Mario Medina C.
5
Algoritmos y Lenguaje de Programación,
Sección 1
Valores denormalizados
Valores especiales
• Bits del exponente e toman valor 0
• Representación del 0
)Precisión simple: exponente es -127
)Precisión doble: exponente es -1023
• Valor fraccionario f es valor de la mantisa m
)Sin el 1 implícito
• Permiten representar números cercanos al 0
)Bit de signo s es 0, bits del exponente e son 0s y
mantisa m es 0
)-0.0: Bit de signo s es 1, bits del exponente e son
0s y mantisa m es 0
• Bits del exponente e son sólo 1s
)Si mantisa m es 0, número es +∞ ó -∞
)Si mantisa m es diferente de 0, número es NaN
(Not a Number)
` Ejemplo: Raíz de -1
Ejemplo de conversión a punto
flotante
• Convertir entero 12345 a precisión simple
)1234510 es 110000001110012
)Forma normalizada: 1.10000001110012x213
)Eliminando el 1 y completando a 23 bits, se tiene
m = 10000001110010000000000
)El exponente es e = 127 + 13 = 14010 =
100011002
)El signo s es 0 (número positivo)
)El resultado completo es 0x4640E400, o
0 10001100 100000011100100000000002
Ejemplos precisión simple
Ejemplo de conversión
• Convertir 0x40490FDB a su equivalente
decimal en punto flotante
)010000000100100100001111110010112
)Signo 0 implica número positivo
)Exponente 128 implica e es 1
)Mantisa 100100100001111110010112 implica
número con el 1 implícito es
1.100100100001111110010112, que es
1.570710
)Número es entonces1.5707x21=3.1414
Ejemplos precisión doble
Valor decimal
Descripción Exponente
Fracción Valor
Valor
decimal
Descripción
Exponente
Fracción Valor
Cero
00…00
0….00
0
0.0
Cero
00…00
0….00
0
1.4x10-45
Denorm.
mínimo
00…00
0….01
2-52x2-1022
4.9x10-324
0.0
Denorm.
mínimo
00…00
0….01
2-23x2-126
Denorm.
máximo
00…00
1….11
(1-2-23) x2-126
1.2x10-38
Denorm.
máximo
00…00
1….11
(1-2-52) x2-1022
2.2x10-308
Normal
mínimo
00…01
0….00
1x2-126
1.2x10-38
Normal
mínimo
00…01
0….00
1x2-1022
2.2x10-308
Uno
01…11
0….00
1x20
1.0
Uno
01…11
0….00
1x20
Normal
máximo
11…10
1….11
(2-2-23)x2126
3.4x1038
Normal
máximo
11…10
1….11
(2-2-52)x2126
©Mario Medina C.
1.0
1.8x10308
6
Algoritmos y Lenguaje de Programación,
Sección 1
Punto flotante en Intel x86
• Procesadores Intel x86 tiene registros
especiales de 80 bits para punto flotante
)Formato tiene 1 bit de signo, 63 de mantisa y
15 de exponente
` Incluye además 1 bit para el 1 implícito
)Todas las operaciones de punto flotante entre
registros se realizan usando números de 80 bits
` Resultados luego se truncan y/o redondean a 64 o
32 bits
)Estándar C tiene tipo de dato long double
para forzar este comportamiento
Ejercicios de punto flotante
• Indique si estas
aseveraciones
son V ó F
)Suponga
int x;
float f;
double d;
1.
2.
3.
4.
5.
6.
7.
x == (int) (float) x;
x == (int) (double) x;
f == (float) (double) f;
d == (float) d;
f == -(-f);
2/3 == 2/3.0;
d < 0.0 implica (d*2) <
0.0
8. d > f implica –f > -d
9. d*d >= 0.0
10.(d + f) – d == f
Otros tipos de datos
Conversión de tipos
• _Bool
• Conversión entre enteros y punto flotante se
hace mediante un cast
)Introducido por ISO C99
` No todos los compiladores lo incluyen
)Definido en <stdbool.h>
` No está presente en Dev-C++
)Define valores de true y false como
` false es 0
` true es 1
)Se fuerza la conversión a otro tipo indicando el
tipo nuevo entre paréntesis
int a = (int) 4.566;
/* a vale 4 */
float b = (float) 2;
/* b vale 2.0 */
double c = (double) ‘A’; /* c vale 65.0 */
)También puede usarse bool en vez de _Bool
Conversión de tipos
• Ojo con los paréntesis!
)Importante al usar división entera
float
float
float
float
float
a
b
c
d
e
=
=
=
=
=
5/2; /* a vale 2.0 */
5.0/2; /* b vale 2.5 */
(float) 5/2; /* c vale 2.5 */
(float) (5/2); /* d vale 2.0 */
((float) 5)/2; /* e vale 2.5 */
Conversión de tipos
• Es posible usar un cast para convertir de un
número entero a otro de menor tamaño
)Compilador se va a quejar, pero es posible!
)Resultado es indefinido
char a = 424343242;
• También puede hacerse con números de
punto flotante
float b = 4.5342e45;
©Mario Medina C.
7
Descargar