2009-12-27 36 views
9

aquí es una cuestión muy simple (pienso), ¿existe un método de biblioteca STL que proporciona el límite de un tipo de variable(por ejemplo número entero)? Sé que estos límites difieren en diferentes computadoras, pero debe haber una forma de obtenerlos a través de un método, ¿no?tipos de variables C++ limita

Además, ¿sería realmente difícil escribir un método para calcular el límite de un tipo de variable?

¡Solo tengo curiosidad! :)

Gracias;).

Respuesta

35

Uso std::numeric_limits:

// numeric_limits example 
// from the page I linked 
#include <iostream> 
#include <limits> 
using namespace std; 

int main() { 
    cout << boolalpha; 
    cout << "Minimum value for int: " << numeric_limits<int>::min() << endl; 
    cout << "Maximum value for int: " << numeric_limits<int>::max() << endl; 
    cout << "int is signed: " << numeric_limits<int>::is_signed << endl; 
    cout << "Non-sign bits in int: " << numeric_limits<int>::digits << endl; 
    cout << "int has infinity: " << numeric_limits<int>::has_infinity << endl; 
    return 0; 
} 
4

(relacionado con C, pero creo que esto también se aplica para C++)

También puede probar "enquire", que es una secuencia de comandos que se pueden volver a crear límites .h para su compilador. Una cita de la página principal del projetc:

Este es un programa que determina muchas propiedades del compilador de C y máquina que se ejecuta en, como mínimo y máximo [un] firmado char/int/long, muchas propiedades de float/[long] double, y así sucesivamente.

Como opción, produce los archivos ANSI C float.h y limits.h.

Como una opción adicional, incluso comprueba que el compilador lee los archivos del encabezado correctamente.

Es una buena prueba de los casos para los compiladores, ya que los ejerce con muchas valores límite, como el número mínimo y máximo de punto flotante.

2
#include <limits> 

std::numeric_limits<type>::max() // min() etc 
12

veo que la respuesta 'correcta' ya se ha dado: Uso <limits> y dejar que la magia suceda. Resulta que encontré esa respuesta insatisfactoria, ya que la pregunta es:

¿Sería realmente difícil escribir un método para calcular el límite de un tipo de variable?

La respuesta es: fácil para tipos enteros, hard for float types. Hay 3 tipos básicos de algoritmos que necesitarías para hacer esto. firmado, sin signo y punto flotante. cada uno tiene un algoritmo diferente para obtener el mínimo y el máximo, y el código real implica algunos giros, y en el caso del punto flotante, debe hacer un bucle a menos que tenga un tipo de entero conocido que sea del mismo tamaño que el flotador tipo.

Entonces, aquí está.

Unsigned es fácil. el mínimo es cuando todos los bits son 0, el máximo es cuando todos los bits son 1.

const unsigned type unsigned_type_min = (unsigned type)0;  
const unsigned type unsigned_type_max = ~(unsigned type)0; 

Para firmado, el min es cuando el bit de signo se establece pero todos los demás bits son ceros, el máximo es cuando se fijan todos los bits excepto el bit de signo. sin conocer el tamaño del tipo, no sabemos dónde está el bit de signo, pero podemos usar algunos trucos para que esto funcione.

const signed type signed_type_max = (signed type)(unsigned_type_max >> 1); 
const signed type signed_type_min = (signed type)(~(signed_type_max)); 

para coma flotante, hay 4 límites, aunque knowning sólo los límites positivos es suficiente, los límites negativos simplemente están signo invertido límites positivos. Existe un potencial de muchas formas de representar números flotantes, pero para aquellos que usan puntos flotantes binarios (en lugar de base 10), casi todos usan representaciones IEEE.

Para flotantes IEEE, el valor de punto flotante positivo más pequeño es cuando el bit bajo del exponente es 1 y todos los demás bits son 0. El valor de punto flotante negativo más grande es el inverso a bit de esto. Sin embargo, sin un tipo entero que se sepa que tiene el mismo tamaño que el tipo de punto flotante dado, no hay ninguna forma de hacer esta manipulación de bit aparte de ejecutar un bucle. si tiene un tipo entero que sabe que tiene el mismo tamaño que su tipo de punto flotante, puede hacerlo como una operación única.

const float_type get_float_type_smallest() { 
    const float_type float_1 = (float_type)1.0; 
    const float_type float_2 = (float_type)0.5; 
    union { 
     byte ab[sizeof(float_type)]; 
     float_type fl; 
     } u; 
    for (int ii = 0; ii < 0; ++ii) 
     u.ab[ii] = ((byte*)&float_1)[ii]^((byte*)&float_2)[ii]; 
    return u.fl; 
    } 

const float_type get_float_type_largest() { 
    union { 
     byte ab[sizeof(float_type)]; 
     float_type fl; 
     } u; 
    u.fl = get_float_type_smallest(); 
    for (int ii = 0; ii < 0; ++ii) 
     u.ab[ii] = ~u.ab[ii]; 
    return -u.fl; // Need to re-invert the sign bit. 
    } 
+0

Creo que su respuesta es la más informativa, así que aquí hay un voto positivo y mis saludos! –

+0

Estás asumiendo el cumplido de dos en enteros, que no es necesariamente cierto. La única forma portátil de obtener el valor máximo sin signo es '= -1', o algunos límites constantes. – GManNickG

+0

@GMan: Los sistemas que no hacen las matemáticas de complementos de dos son teóricamente posibles, pero son una curiosidad histórica, no un problema de portabilidad genuino. –

Cuestiones relacionadas