Sie sind auf Seite 1von 5

Tipos bsicos C++: representacin interna y rango

http://www.zator.com/Cpp/E2_2_4.htm

Disponible la versin 6 de OrganiZATOR Descubre un nuevo concepto en el manejo de la informacin. La mejor ayuda para sobrevivir en la moderna jungla de datos la tienes aqu.

Curso C++
[Home] [Inicio] [ndice]

Subir

2.2.4 Tipos bsicos: representacin interna, rango


1 Sinopsis El ANSI C reconoce que el tamao y rangos de valor numrico de los tipos bsicos y sus varias permutaciones ( 2.2.1) dependen de la implementacin y generalmente derivan de la arquitectura del ordenador. La tabla adjunta muestra los tamaos y rangos de los tipos numricos de 32-bits de Borland C++ [1]. Nota: precisamente esta circunstancia, que el Estndar C++ impone relativa libertad en cuanto al tamao de los tipos, es la responsable de que an adhirindose estrictamente al Estndar, puedan existir problemas de portabilidad entre diversas plataformas de los programas C++ (algo que no ocurre con otros lenguajes de definicin ms estricta. Por ejemplo Java). Ver en 2.2.4c unas notas adicionales sobre los tipos bsicos.

2 Almacenamiento y rango Las explicaciones siguientes muestran como se representan internamente estos tipos (en negrita los tipos bsicos). Los ficheros de cabecera <climits> y <float.h> contienen definiciones de los rangos de valor de todos los tipos fundamentales. Tipo unsigned char bits Rango / Tipo de uso 8 0 <= X <= 255 Nmeros pequeos y juego caracteres del PC.

char (signed)

-128 <= X <= 127

Nmeros muy pequeos y juego de caracteres ASCII [5]

short (signed)

16

-32,768 <= X <= 32,767 Nmeros muy pequeos, control de bucles pequeos

unsigned short

16

0 <= X <= 65,535

Nmeros muy pequeos, control de bucles pequeos

unsigned (int)

32

0 <= X <= 4,294,967,295.

Nmeros grandes

int (signed)

32

-2,147,483,648 <= X <= 2,147,483,647 Nmeros pequeos, control de bucles

unsigned long

32

0 <= X <= 4,294,967,295

Distancias astronmicas

enum

32

-2,147,483,648 <= X <= 2,147,483,647

Conjuntos de valores ordenados

long (int)

32

-2,147,483,648 <= X <= 2,147,483,647 Nmeros grandes 1.18e-38 <= |X| <= 3.40e38 2.23e-308 <= |X| <= 1.79e308 Precisin cientfica ( 7-dgitos) Precisin cientfica (15-dgitos)

float double

32 64

long double

80

3.37e-4932 <= |X| <= 1.18e4932

Precisin cientfica (18-dgitos)

Nota: las cuestiones de almacenamiento interno, como se almacenan los datos en memoria y cuanto espacio necesitan, estn influidas por otros factores adems de los sealados. Estas son las que podramos denominar "necesidades mnimas" de almacenamiento. En ocasiones, especialmente en estructuras y uniones, el compilador realiza determinados "ajustes" o "alineaciones" con los datos, de forma que las direcciones de memoria se ajustan a determinadas pautas. El resultado es que en estos casos, el tamao de por ejemplo una estructura, no corresponde con lo que tericamente se deduce de la suma de los miembros ( 4.5.9). Las

1 de 5

12/04/2012 11:30

Tipos bsicos C++: representacin interna y rango

http://www.zator.com/Cpp/E2_2_4.htm

caractersticas de esta "alineacin" pueden ser controladas mediante opciones del compilador (

4.5.9a).

3 Enteros En C++ 32-bit, los tipos int y long son equivalentes, ambos usan 32 bits [3]. Las variedades con signo son todas almacenadas en forma de complemento a dos usando el bit ms significativo como bit de signo (0 positivo y 1 negativo), lo que explica los rangos indicados en la tabla. En las versiones sin signo, se usan todos los bits, con lo que el nmero n n de posibilidades es 2 , y el rango de valores est entre 0 y 2 -1, donde n es el nmero de bits de la palabra del procesador, 8, 16 o 32 (uno, dos, o cuatro octetos). El estndar ANSI C no define el tamao de almacenamiento de los diversos tipos, solamente indica que la serie short, int y long no es descendente, es decir: short <= int <= long. De hecho, legalmente los tres tipos pueden ser del mismo tamao. En muchas (pero no todas) las implementaciones de C y C++ un long es mayor que un int. Actualmente, la mayora de las aplicaciones de oficina y personales, con entornos como Windows o Linux, corren sobre plataformas hardware de 32 bits, de forma que la mayora de los compiladores para estas plataformas utilizan un int de 32 bits (del mismo tamao que el long). En cualquier caso, los rangos vienen indicados por las constantes que se sealan (incluidas en <limits.h>): signed short: SHRT_MIN <= X <= SHRT_MAX.

Siendo: SHRT_MIN <= -32767 y SHRT_MAX >= 32767. Algunas implementaciones hacen SHRT_MIN = -32768 pero no es exigido por el estndar. unsigned short: 0 <= X <= USHRT_MAX.

Siendo: USHRT_MAX >= 65535. Las variedades short deben contener al menos 16 bits para que pueda cubrirse el rango de valores exigidos. En la mayora de los compiladores un short es menor que un int, de forma que algunos programas que deben almacenar grandes matrices de nmeros en memoria o en ficheros pueden economizar espacio utilizando short en lugar de int, pero siempre que se cumplan dos condiciones: 1. En la implementacin un short es realmente menor que un int. 2.- Los valores caben en un short. En algunas arquitecturas el cdigo empleado para manejar los short es ms largo y lento que el correspondiente para los int. Esto es particularmente cierto en los procesadores Intel x86 ejecutando cdigo de 32 bits en programas para Windows (NT/95/98), Linux y otras versiones Unix. En estos cdigos, cada instruccin que referencia a un short es un byte ms larga y generalmente necesita tiempo extra de procesador para ejecutarse. signed int: INT_MIN <= X <= INT_MAX.

Siendo: INT_MIN <= -32767 y INT_MAX >= 32767. Algunas implementaciones utilizan un valor INT_MIN = -32768 pero no es exigido en el estndar. unsigned int: 0 <= X <= UINT_MAX.

Siendo: UINT_MAX >= 65535. Para cubrir esta exigencia, los int deben ser de 16 bits por lo menos. El rango exigido para signed int y unsigned int es idntico que para los signed short y unsigned short. En compiladores para procesadores de 8 y 16 bits (incluyendo los Intel x86 ejecutando cdigo en modo 16 bits, como bajo MS DOS), normalmente un int es de 16 bits, exactamente igual que un short. En los compiladores para procesadores de 32 bit y mayores (incluyendo los Intel x86 ejecutando cdigo de 32 bits como Windows o Linux) generalmente un int es de 32 bits, exactamente igual que un long. signed long: LONG_MIN <= X <= LONG_MAX.

Siendo: LONG_MIN <= -2147483647 y LONG_MAX >= 2147483647. Existen implementaciones que hacen LONG_MIN = -2147483648 pero no es exigido por el estndar. unsigned long: 0 <= X <= ULONG_MAX.

Siendo: ULONG_MAX >= 4294967295. Para poder cubrir este rango, los tipos long deben ser de al menos 32 bits.

4 Nuevos tipos numricos Los rangos previstos para los nuevos tipos ( signed long long: 3.2.3d) long long. que se proyectan incluir en el estndar son:

LLONG_MIN <= X <= LLONG_MAX.

Siendo: LLONG_MIN <= -9223372036854775807 y LLONG_MAX >= 9223372036854775807. Algunas implementaciones hacen LLONG_MIN = -9223372036854775808 pero no es exigido. unsigned long long: 0 <= X <= ULLONG_MAX.

Siendo: ULLONG_MAX >= 18446744073709551615. Las variedades long deben ser de al menos 64 bits para poder cubrir el rango exigido. La diferencia entre enteros con signo y sin signo (signed y unsigned) es que en los primeros el bit ms significativo se usa para guardar el signo (0 positivo, 1 negativo), esto hace que los enteros con signo tengan un rango de valores posibles distinto que los unsigned. Vase al respecto el rango de int y unsigned int.

2 de 5

12/04/2012 11:30

Tipos bsicos C++: representacin interna y rango

http://www.zator.com/Cpp/E2_2_4.htm

Los enteros sin signo se mantienen en valores 0 positivos, dentro de la aritmtica de numeracin de mdulo base 2, es decir 2n, donde n es el nmero de bits de almacenamiento del tipo, de forma que, por ejemplo, si un int se almacena en 32 bits, unsigned int tiene un rango entre 0 y 232 -1 = 4,294,967,295 (el valor 0 ocupa una posicin de las 4.294.967.295 posibles).

5 Carcter La cabecera <limits.h> contiene una macro, CHAR_BIT, que se expande a una constante entera que indica el nmero de bits de un tipo carcter (char), que se almacenan en 1 byte, es decir, siempre ocurre que sizeof(char) == 1. Esta es la definicin ANSI de byte en C/C++, es decir, la memoria requerida para almacenar un carcter, pero este byte no corresponde necesariamente con el byte de la mquina. El valor de CHAR_BIT es al menos 8; la mayora de los ordenadores modernos usan bytes de 8 bits (octetos), pero existen algunos con otros tamaos, por ejemplo 9 bits. Adems algunos procesadores, especialmente de seal (Digital Signal Processors), que no pueden acceder de forma eficiente a la memoria en tamaos menores que la palabra del preprocesador, tienen un CHAR_BIT distinto, por ejemplo 24. En estos casos, los tipos char, short e int son todos de 24 bits, y long de 48 bits. Incluso son ms comunes actualmente procesadores de seal donde todos los tipos enteros incluyendo los long son de 32 bits. signed char: Valores entre: SCHAR_MIN <= X <= SCHAR_MAX, Siendo: SCHAR_MIN <= -127 y SCHAR_MAX >= 127. La mayora de los compiladores utilizan un valor SCHAR_MIN de -128, pero no es exigido por el estndar. unsigned char: Valores entre 0 <= x <= UCHAR_MAX.

Se exige que UCHAR_MAX >= 255. si CHAR_BIT es mayor que 8, se exige que UCHAR_MAX = 2 CHAR_BIT - 1. De forma que una implementacin que utilice un carcter de 9 bits puede almacenar valores entre 0 y 511 en un unsigned char. char (valor carcter a secas "plain char"). Valores entre CHAR_MIN <= X <= CHAR_MAX

Si los valores char son considerados signed char por defecto: CHAR_MIN == SCHAR_MIN y CHAR_MAX == SCHAR_MAX. Si los valores char son considerados unsigned char por defecto: CHAR_MIN == 0 y CHAR_MAX == UCHAR_MAX. Por ejemplo, un trozo del fichero limits.h que acompaa al compilador Microsoft Visual C++ 2008, tiene el siguiente aspecto: #define #define #define #define CHAR_BIT 8 SCHAR_MIN (-128) SCHAR_MAX 127 UCHAR_MAX 0xff /* /* /* /* number of bits in a char */ minimum signed char value */ maximum signed char value */ maximum unsigned char value */

6 Fraccionarios La representacin y rango de valores de los nmeros fraccionarios depende del compilador. Es decir, cada implementacin de C++ es libre para definirlos. La mayora utiliza el formato estndar de la IEEE (Institute of Electrical and Electronics Engineers) para este tipo de nmeros ( 2.2.4a). float y double son tipos fraccionarios de 32 y 64 bits respectivamente. El modificador long puede utilizarse con el tipo double, declarando entonces un nmero fraccionario de 80 bits. En C++Builder las constantes fraccionarias, que pueden ser float, double y long double, tienen los rangos que se indican: Tipo float double bits Rango 32 64 1.17549e-38 <= |X| <= 3.40282e+38 2.22507e-308 <= |X| <= 1.79769e+308 3.37e-4932 <= |X| <= 1.18e4932

long double 80

Generalmente los compiladores C++ incluyen de forma automtica la librera matemtica de punto flotante si el programa utiliza valores fraccionarios [4]. Builder utiliza los siguientes lmites, definidos en el fichero <values.h> float. Valores entre: MINFLOAT <= |X| <= MAXFLOAT (valores actuales entre parntesis) MINFLOAT (1.17549e-38)

MAXFLOAT (3.40282e+38) FEXPLEN Nmero de bits en el exponente (8) FMAXEXP Valor mximo permitido para el exponente (38) FMAXPOWTWO Mxima potencia de dos permitida (127) FMINEXP Valor mnimo permitido para el exponente (-37) FSIGNIF Nmero de bits significativos. (24) double. Valores entre MINDOUBLE MINDOUBLE <= |X| <= MAXDOUBLE

(2.22507e-308)

MAXDOUBLE (1.79769e+308) DEXPLEN Nmero de bits en el exponente (11)

3 de 5

12/04/2012 11:30

Tipos bsicos C++: representacin interna y rango

http://www.zator.com/Cpp/E2_2_4.htm

DMAXEXP Valor mximo permitido para el exponente (308) DMAXPOWTWO Mxima potencia de dos permitida (1023) DMINEXP Valor mnimo permitido para el exponente (-307) DSIGNIF Nmero de bits significativos (53)

7 La clase numeric_limits La Librera Estndar C++ contiene una clase numeric_limits que contiene informacin sobre los escalares. Existen subclases para cada tipo fundamental, enteros (incluyendo los booleanos) y fraccionarios. Esta clase engloba la informacin contenida en los ficheros de cabecera <climits> y <cfloat>; adems de incluir informacin que no est contenida en ninguna otra cabecera. A continuacin se incluye un ejemplo que muestra el espacio disponible (bits) para codificar el valor de los tipos fundamentales (mantisa), as como la salida proporcionada en un caso concreto. #include <cstdlib> #include <iostream> #include <limits> int main(int argc, char *argv[]) { std::cout << "Mantisa de un char: " << std::numeric_limits<char>::digits << '\n'; std::cout << "Mantisa de un unsigned char: " << std::numeric_limits<unsigned char>::digits << '\n'; std::cout << << std::cout << << std::cout << << std::cout << << std::cout << << std::cout << << std::cout << << std::cout << << std::cout << << std::cout << << std::cout << << return 0; } Salida en una mquina Intel con el compilador GNU g++ 3.4.2 para Windows: Mantisa de un char: 7 Mantisa de un unsigned char: 8 Mantisa de un short: 15 Mantisa de un unsigned short: 16 Mantisa de un int: 31 Mantisa de un unsigned int: 32 Mantisa de un long: 31 Mantisa de un unsigned long: 32 Mantisa de un float: 24 Longitud de un double: 53 Longitud de un long double: 64 Mantisa de un long long: 63 Mantisa de un unsigned long long: 64 "Mantisa de un short: " std::numeric_limits<short>::digits << '\n'; "Mantisa de un unsigned short: " std::numeric_limits<unsigned short>::digits << '\n'; "Mantisa de un int: " std::numeric_limits<int>::digits << '\n'; "Mantisa de un unsigned int: " std::numeric_limits<unsigned int>::digits << '\n'; "Mantisa de un long: " std::numeric_limits<long>::digits << '\n'; "Mantisa de un unsigned long: " std::numeric_limits<unsigned long>::digits << '\n'; "Mantisa de un float: " std::numeric_limits<float>::digits << '\n'; "Longitud de un double: " std::numeric_limits<double>::digits << '\n'; "Longitud de un long double: " std::numeric_limits<long double>::digits << '\n'; "Mantisa de un long long: " std::numeric_limits<long long>::digits << '\n'; "Mantisa de un unsigned long long: " std::numeric_limits<unsigned long long>::digits << '\n';

Temas relacionados: Operador sizeof ( Alineacin interna ( Inicio. [1] Dado que Borland C++ ha sido desarrollado para la familia de PCs IBM (y compatibles), la arquitectura de los procesadores Intel 8088 y 80x86 es la que gobierna las posibilidades de representacin interna de los diversos tipos. En 4.9.13) se indican los tamaos para otros compiladores. ( [3] La nica asuncin es que un entero (int) tiene la misma longitud que la palabra del procesador. [4] Los valores fraccionarios son denominados "De punto flotante" en la literatura inglesa. 4.9.13) 4.6.1).

4 de 5

12/04/2012 11:30

Tipos bsicos C++: representacin interna y rango

http://www.zator.com/Cpp/E2_2_4.htm

[5] En cierta ocasin un lector me envi la siguiente pregunta: "Tengo una duda, por qu el caso del tipo char incluye -128 ? Si tenemos el bit de signo el nmero ms pequeo no sera -127?" La cuestin planteada tiene cierta lgica, porque si reservamos 1 bit para el signo, la mayor cantidad que puede representarse con 7 bits es 127, de forma que el patrn de bits 0111 1111 correspondera a +127 y 1111 1111 equivaldra -127. Una forma de ver la respuesta es considerar que el fabricante del compilador puede adoptar la convencin de que el bit de signo tiene un doble significado: signo y valor, de forma que el octeto 1000 0000 puede interpretarse como -128 en lugar de -0, reservando 0000 0000 para el 0. Como puede verse, la consigna de apurar al mximo las posibilidades del almacenamiento, es tomada muy en serio en esta rama de la tecnologa. Otra forma de entender el asunto sera considerarlo desde la ptica de la representacin interna (binaria), que en la mayora de mquinas actuales es en forma de complemento a dos. Veremos que en este sistema ( 2.2.4a), los nmeros positivos se representan reservando el bit ms significativo (que debe ser cero) para el signo, mientras que la representacin de los nmeros positivos se consigue cambiando los bits que seran 0 por 1 y viceversa en el valor positivo del nmero y sumando uno al resultado. Por ejemplo, aplicando este razonamiento para representar el nmero -127, tendramos que el patrn de bits 0111 1111, que corresponde a +127, se transformara en 1000 0000, al que sumamos 1, de forma que el patrn 1000 0001 corresponde al -127. De forma anloga, la operacin inversa permitira obtener el valor absoluto de cualquier patron de bits que comience por 1 (negativo), as que el proceso para obtener el valor absoluto del patrn de bits 1000 0000 sera: restarle uno -> 0111 1111 + cambiar ceros por unos -> 1000 0000 = 128. No obstante lo anterior, no olvidar que por debajo de cualquier convencin que se adopte, con 8 bits solo es posible representar 255 valores distintos (256 si incluimos el cero), de forma que el rango de magnitudes con signo y sin signo (signed y unsigned) puede ser arbitrario, pero debe respetar esta limitacin. En el caso que nos ocupa, el rango de los valores positivos, x <= +127 incluye 128 valores distintos si inclumos el cero, de forma que nos quedan 128 posibilidades para los valores negativos y el rango elegido es desde -1 a -128 inclusive.

Inicio

|ndice|

Copyright 1990-2012 Zator Systems.

5 de 5

12/04/2012 11:30

Das könnte Ihnen auch gefallen