¿Qué rango de valores pueden almacenar los tipos enteros en C ++?

86

¿Puede unsigned long intcontener un número de diez dígitos (1,000,000,000 - 9,999,999,999) en una computadora de 32 bits?

Además, ¿cuáles son los rangos de unsigned long int, long int, unsigned int, short int, short unsigned int, y int?

yihangho
fuente

Respuestas:

139

Los rangos mínimos en los que puede confiar son:

  • short inty int: -32,767 a 32,767
  • unsigned short inty unsigned int: 0 a 65,535
  • long int: -2,147,483,647 a 2,147,483,647
  • unsigned long int: 0 a 4.294.967.295

Esto significa que no, long int no se puede confiar en que almacene ningún número de 10 dígitos. Sin embargo, long long intse introdujo un tipo más grande en C en C99 y C ++ en C ++ 11 (este tipo también suele ser admitido como una extensión por compiladores creados para estándares anteriores que no lo incluían). El rango mínimo para este tipo, si su compilador lo admite, es:

  • long long int: -9,223,372,036,854,775,807 a 9,223,372,036,854,775,807
  • unsigned long long int: 0 a 18,446,744,073,709,551,615

Entonces ese tipo será lo suficientemente grande (nuevamente, si lo tiene disponible).


Una nota para aquellos que creen que he cometido un error con estos límites inferiores: no lo he hecho. Los requisitos de C para los rangos están escritos para permitir representaciones enteras de magnitud de signo o complemento de uno, donde el valor representable más bajo y el valor representable más alto difieren solo en el signo. También se permite tener una representación en complemento a dos donde el valor con el bit de signo 1 y todos los bits de valor 0 es una representación de trampa en lugar de un valor legal. En otras palabras, intes que no requiere que sea capaz de representar el valor -32.768.

coste y flete
fuente
El título originalmente decía "C / C ++" también.
caf
por qué long long int rango positivo == rango negativo
mohamed abdallah
1
@mohamedabdallah: Vea el último párrafo de la respuesta: los rangos estándar de C son de esa manera para permitir el complemento de uno o las representaciones de magnitud de signo.
caf
Ajá ... me di cuenta de que eso intsignifica long int.
laberinto
32

El tamaño de los tipos numéricos no está definido en el estándar C ++, aunque los tamaños mínimos sí lo están. La forma de saber qué tamaño tienen en su plataforma es usar límites numéricos

Por ejemplo, el valor máximo de un int se puede encontrar mediante:

std::numeric_limits<int>::max();

Las computadoras no funcionan en base 10, lo que significa que el valor máximo estará en la forma de 2 n -1 debido a cómo se representan los números en la memoria. Tomemos por ejemplo ocho bits (1 byte)

  0100 1000

El bit (número) más a la derecha cuando se establece en 1 representa 2 0 , el siguiente bit 2 1 , luego 2 2 y así sucesivamente hasta que lleguemos al bit más a la izquierda, que si el número no tiene signo representa 2 7 .

Entonces, el número representa 2 6 + 2 3 = 64 + 8 = 72, porque el cuarto bit de la derecha y el séptimo bit de la derecha a la izquierda están establecidos.

Si establecemos todos los valores en 1:

11111111

El número ahora es (asumiendo que no tiene signo )
128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = 255 = 2 8 - 1
Y como podemos ver, ese es el valor más grande posible que se puede representar con 8 bits.

En mi máquina, int y a long son iguales, cada uno capaz de contener entre -2 31 a 2 31 - 1. En mi experiencia, el tamaño más común en la máquina de escritorio moderna de 32 bits.

Yacoby
fuente
Los tamaños mínimos para el tipo entero son obligatorios por los estándares relevantes (aunque los tamaños exactos no lo son).
caf
13

Para conocer los límites de su sistema:

#include <iostream>
#include <limits>
int main(int, char **) {
  std::cout
    << static_cast< int >(std::numeric_limits< char >::max()) << "\n"
    << static_cast< int >(std::numeric_limits< unsigned char >::max()) << "\n"
    << std::numeric_limits< short >::max() << "\n"
    << std::numeric_limits< unsigned short >::max() << "\n"
    << std::numeric_limits< int >::max() << "\n"
    << std::numeric_limits< unsigned int >::max() << "\n"
    << std::numeric_limits< long >::max() << "\n"
    << std::numeric_limits< unsigned long >::max() << "\n"
    << std::numeric_limits< long long >::max() << "\n"
    << std::numeric_limits< unsigned long long >::max() << "\n";
}

Tenga en cuenta que long longsolo es legal en C99 y en C ++ 11.

Hal Canary
fuente
9

Otras personas aquí publicarán enlaces a tamaños de datos y precisiones, etc.
Te diré cómo resolverlo tú mismo.
Escribe una pequeña aplicación que haga lo siguiente.

unsigned int ui;
std::cout <<  sizeof(ui));

esto (dependiendo del compilador y la imagen) imprimirá 2, 4 u 8, diciendo 2 bytes de largo, 4 bytes de largo, etc.

Supongamos que es 4.

Ahora desea el valor máximo que pueden almacenar 4 bytes, el valor máximo para un byte es (en hexadecimal) 0xFF. El valor máximo de cuatro bytes es 0x seguido de 8 f (un par de f para cada byte, el 0x le dice al compilador que la siguiente cadena es un número hexadecimal). Ahora cambie su programa para asignar ese valor e imprima el resultado

unsigned int ui = 0xFFFFFFFF;
std::cout <<  ui;

Ese es el valor máximo que puede contener un int sin firmar, mostrado en la representación de base 10.

Ahora haz eso para largos, cortos y cualquier otro valor INTEGER que te interese.

NB: Este enfoque no funcionará para números de coma flotante (es decir, doble o flotante).

Espero que esto ayude

Preocupado binario
fuente
1
Si intenta esto con ints firmados, obtendrá números negativos. Lea sobre el "cumplido de dos" (enlace proporcionado), es fácil obtener el rango completo (positivo y negativo) de estos también. en.wikipedia.org/wiki/Twos_Compliment
Binary Worrier
8

En C ++, ahora int y otros datos se almacenan utilizando el método complementario de 2. Eso significa que el rango es:

-2147483648 to 2147483647

o -2 ^ 31 a 2 ^ 31-1

1 bit está reservado para 0, por lo que el valor positivo es uno menos que 2 ^ (31)

Shah Rukh Qasim
fuente
4

Puede utilizar las funciones numeric_limits<data_type>::min()y numeric_limits<data_type>::max()presentes en el limitsarchivo de encabezado y encontrar los límites de cada tipo de datos.

#include <iostream>
#include <limits>
using namespace std;
int main()
{
    cout<<"Limits of Data types:\n";    
    cout<<"char\t\t\t: "<<static_cast<int>(numeric_limits<char>::min())<<" to "<<static_cast<int>(numeric_limits<char>::max())<<endl;
    cout<<"unsigned char\t\t: "<<static_cast<int>(numeric_limits<unsigned char>::min())<<" to "<<static_cast<int>(numeric_limits<unsigned char>::max())<<endl;
    cout<<"short\t\t\t: "<<numeric_limits<short>::min()<<" to "<<numeric_limits<short>::max()<<endl;
    cout<<"unsigned short\t\t: "<<numeric_limits<unsigned short>::min()<<" to "<<numeric_limits<unsigned short>::max()<<endl;
    cout<<"int\t\t\t: "<<numeric_limits<int>::min()<<" to "<<numeric_limits<int>::max()<<endl;
    cout<<"unsigned int\t\t: "<<numeric_limits<unsigned int>::min()<<" to "<<numeric_limits<unsigned int>::max()<<endl;
    cout<<"long\t\t\t: "<<numeric_limits<long>::min()<<" to "<<numeric_limits<long>::max()<<endl;
    cout<<"unsigned long\t\t: "<<numeric_limits<unsigned long>::min()<<" to "<<numeric_limits<unsigned long>::max()<<endl;
    cout<<"long long\t\t: "<<numeric_limits<long long>::min()<<" to "<<numeric_limits<long long>::max()<<endl;
    cout<<"unsiged long long\t: "<<numeric_limits<unsigned long long>::min()<<" to "<<numeric_limits<unsigned long long>::max()<<endl;
    cout<<"float\t\t\t: "<<numeric_limits<float>::min()<<" to "<<numeric_limits<float>::max()<<endl;
    cout<<"double\t\t\t: "<<numeric_limits<double>::min()<<" to "<<numeric_limits<double>::max()<<endl;
    cout<<"long double\t\t: "<<numeric_limits<long double>::min()<<" to "<<numeric_limits<long double>::max()<<endl;
}

La salida será: Límites de tipos de datos:

  • char: -128 a 127
  • carácter sin firmar: 0 a 255
  • corto: -32768 a 32767
  • corto sin firmar: 0 a 65535
  • int: -2147483648 a 2147483647
  • unsigned int: 0 a 4294967295
  • largo: -2147483648 a 2147483647
  • unsigned long: 0 a 4294967295
  • largo largo: -9223372036854775808 a 9223372036854775807
  • unsigned long long: 0 a 18446744073709551615
  • flotador: 1.17549e-038 a 3.40282e + 038
  • doble: 2.22507e-308 a 1.79769e + 308
  • doble largo: 3.3621e-4932 a 1.18973e + 4932
insearchofcode
fuente
2

Para el tipo de datos sin firmar no hay bit de signo y todos los bits son para datos; mientras que para el tipo de datos con signo, MSB se indica como bit de signo y los bits restantes son para datos.

Para encontrar el rango, haga lo siguiente:

Paso: 1 -> Averigüe el número de bytes para el tipo de datos dado.

Paso: 2 -> Aplicar los siguientes cálculos.

      Let n = no of bits in data type  

      For signed data type ::
            Lower Range = -(2^(n-1)) 
            Upper Range = (2^(n-1)) - 1)  

      For unsigned data type ::
            Lower Range = 0 
            Upper Range = (2^(n)) - 1 

Por ejemplo

Para tamaño int sin firmar = 4 bytes (32 bits) -> Rango [0, (2 ^ (32)) - 1]

Para tamaño int con signo = 4 bytes (32 bits) -> Rango [- (2 ^ (32-1)), (2 ^ (32-1)) - 1]

Ashish
fuente
1

¿Puede unsigned long int contener un número de diez dígitos (1,000,000,000 - 9,999,999,999) en una computadora de 32 bits.

No

justin
fuente
0

Debería mirar las especializaciones de la plantilla numeric_limits <> para un tipo dado. Está en el encabezado.

PaulJWilliams
fuente