Herramientas de usuario

Herramientas del sitio


curso-cpp:mas-tipos

¡Esta es una revisión vieja del documento!


Más tipos de datos básicos de C++

Tipos enteros

En C++ existen múltiples tipos de datos enteros. El más común de ellos es el tipo int, que permite almacenar números entre $-2^31$ y $2^31-1$ , inclusive. Si alguna operación da por resultado números fuera de este rango de valores, obtendremos al trabajar con int resultados incorrectos.

Similarmente, existen en C++ otros tipos de datos enteros fundamentales, pero de distinto tamaño: Los int tienen un tamaño de 32 bits (dígitos binarios), o 4 bytes, y eso además de definir el espacio de memoria RAM que ocupa cada variable de tipo int, limita el rango de valores que estos pueden representar.

En C++ existen otras variables enteras de diversos tamaños:

  • char: Entero de 8 bits, entre $-2^7$ y $2^7-1$ inclusive, es decir, entre -128 y 127 inclusive. Ya lo hemos utilizado cuando trabajamos con caracteres, pues un caracter en C++ se representa directamente mediante un número, que es su código ASCII.
  • short: Entero de 16 bits, entre $-2^15 = -32768$ y $2^15-1 = 32767$ inclusive.
  • int: Entero de 32 bits, entre $-2^31 = -2147483648$ y $2^31-1=2147483647$ inclusive.
  • long long: Entero de 64 bits, entre $-2^63=-9223372036854775808$ y $2^63 - 1=9223372036854775807$ inclusive.

Para referencia, las máximas potencias de 10 que entran en el rango de cada tipo son respectivamente:

  • char: Hasta $100 = 10^2$
  • short: Hasta $10.000 = 10^4$
  • int: Hasta $1.000.000.000 = 10^9$
  • long long: Hasta $1.000.000.000.000.000.000 = 10^{18}$

Todos estos tipos se usan de la misma manera que int, y solo cambia la cantidad de memoria que utilizan estas variables y el rango de valores posibles. Por ejemplo es perfectamente válido lo siguiente:

short x = 32;
int y = 1000;
long long z = x + y;

En las operaciones aritméticas, como regla general el tamaño del resultado de una operación es el máximo tamaño de sus operandos, es decir que si sumamos short e int, obtendremos int, y si sumamos int con long long obtendremos long long. Esto es independiente del resultado de la operación, y solo depende de los tipos involucrados.

Tipo de una literal entero

Cuando escribimos un número directamente en el código, como por ejemplo x = y + 33;, cabe preguntarse: ¿De qué tamaño es ese 33? Esto es importante para las cuentas intermedias, pues ese tipo define el tamaño del resultado. Por ejemplo, si hacemos long long x = y + 1000000000;, donde y es de tipo int, el resultado “matemático” de la cuenta siempre entrará en el rango de long long, pero... ¿Es para la computadora el resultado de la cuenta un long long?

La respuesta a esta última pregunta es que no: Los literales enteros son de tipo int, automáticamente, a menos que les pongamos un LL (indicador de long long) al final, en cuyo caso serán long long.

Así, en el ejemplo de long long x = y + 1000000000;, y es de tipo int, y el 1000000000 se considera de tipo int, por lo tanto el resultado de la suma será de tamaño int, y si este resultado se va del rango posible de valores de int, quedará en x un valor erróneo, incluso cuando el valor verdadero hubiera podido entrar en dicha variable.

Si en cambio hacemos long long x = y + 1000000000LL;, no tendremos este problema pues el resultado de la cuenta será un long long, al serlo 1000000000LL.

Similar problema tendremos si hacemos long long x = y + z, siendo tanto y como z variables de tipo int. Podemos solucionarlo convirtiendo una de ellas a long long: long long x = y + (long long)(z), de forma análoga a lo que hacíamos con el LL para los literales enteros.

El caso más común donde esto ocurre es en la expresión: 1 << i (que es común si se trabaja con máscaras de bits de 64 bits): El resultado de esta operación será de tipo int, que no es lo que queremos si estamos trabajando valores de 64 bits. 1LL << i resuelve por completo este problema.

Reglas prácticas para el manejo de tipos enteros

En general, mezclar distintos tamaños y tipos puede llevar a confusiones y errores. Las “reglas prácticas” más comunes a seguir son las siguientes:

  • Usar int, a menos que sean necesarios números que no entren en int. En tal caso, usar long long para todas las variables involucradas en estos cálculos con números grandes.
  • En las constantes enteras, usar el sufijo LL cuando aparecen en una cuenta con números de tamaño long long.
  • Utilizar los tipos char o short únicamente si es absolutamente necesario ahorrar memoria.
  • Utilizar otros tipos (como por ejemplo los unsigned) solamente en casos excepcionales donde no veamos ninguna buena alternativa.

Observaciones sobre el tamaño de los distintos tipos

Hemos mencionado aquí los tamaños para el caso del compilador gcc para PC, que es probablemente el más utilizado en competencias de programación. Sin embargo, el lenguaje C++ tiene la particularidad de que no garantiza el tamaño exacto de los tipos enteros, que pueden variar entre distintos compiladores del lenguaje.

Por ejemplo, existen compiladores para 64 bits en los cuales int es un tipo de 64 bits como long long. Si usamos compiladores “antiguos” para el sistema operativo DOS (Como el clásico Turbo C++), int será más chico y tendrá solamente 16 bits, ya que ese era el tamaño normal de los números con los que las computadoras podían trabajar rápidamente.

curso-cpp/mas-tipos.1490139880.txt.gz · Última modificación: 2017/03/21 23:44 por santo