2009-12-27 2 views
9

hier ist eine ganz einfache Frage (glaube ich), gibt es eine STL-Bibliothek Methode, die die Grenze eines Variablentyp(z integer)bietet? Ich weiß, dass diese Grenzen auf verschiedenen Computern unterschiedlich sind, aber es muss einen Weg geben, sie durch eine Methode zu bekommen, richtig?C++ Variablentypen begrenzt

Auch wäre es wirklich schwierig sein, eine Methode zu schreiben, die Grenze eines Variablentyp zu berechnen?

Ich bin nur neugierig! :)

Danke;).

Antwort

35

Verwendung 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

(bezogen auf C, aber ich denke, das gilt auch für C++)

Sie können auch "enquire" versuchen, die ein Skript, die Grenzen neu erstellen können .h für deinen Compiler. Ein Zitat aus der Homepage des projetc:

Dies ist ein Programm, das viele Eigenschaften der C-Compiler und Maschine feststellt, dass es laufen soll, wie Minimal- und Maximal [un] unterzeichnet char/int/lang, viele Eigenschaften von float/[long] double, und so weiter.

Als Option es die ANSI-C float.h und limits.h Dateien erzeugt.

Als weitere Option überprüft es sogar , dass der Compiler die Header Dateien korrekt liest.

Es ist ein guter Testfall für Compiler, da er sich mit vielen Grenzwerten, wie sie die Mindest und maximale Gleitkommazahlen ausübt.

2
#include <limits> 

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

Ich sehe, dass die ‚richtige‘ Antwort bereits gegeben worden: Verwenden Sie <limits> und lassen Sie die Magie geschehen. Ich finde diese Antwort unbefriedigend, da die Frage lautet:

wäre es wirklich schwer, eine Methode zu schreiben, um das Limit eines Variablentyps zu berechnen?

Die Antwort lautet: einfach für Integer-Typen, hart für float-Typen. Es gibt 3 grundlegende Arten von Algorithmen, die Sie benötigen, um dies zu tun. signiert, unsigniert und Gleitkomma. Jeder hat einen anderen Algorithmus, wie Sie die Min- und Max-Werte erhalten, und der eigentliche Code beinhaltet etwas Bit-Twiddling, und im Fall von Gleitkommazahlen müssen Sie eine Schleife ausführen, es sei denn, Sie haben einen bekannten Integertyp, der die gleiche Größe wie der Float hat Art.

So, hier ist es.

Unsigned ist einfach. Das Minimum ist, wenn alle Bits 0 sind, das Maximum ist, wenn alle Bits 1 sind.

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

Für unterzeichnet, ist die min, wenn das Vorzeichen-Bit gesetzt ist, aber alle anderen Bits sind Nullen, die max ist, wenn alle Bits außer dem Vorzeichenbit gesetzt sind. Ohne die Größe des Typs zu kennen, wissen wir nicht, wo das Vorzeichen-Bit ist, aber wir können ein paar Bit-Tricks verwenden, um das zu erreichen.

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

für Gleitkommazahl gibt es 4 Grenzen, obwohl nur die positiven Grenzen knowning ausreichend ist, werden die negativen Grenzen nur Vorzeichen positiv Grenzen invertiert. Es gibt möglicherweise viele Möglichkeiten, Fließkommazahlen zu repräsentieren, aber für diejenigen, die Fließkommazahlen mit binärer (statt Basis 10) verwenden, verwenden fast alle IEEE-Darstellungen.

Bei IEEE-Floats ist der kleinste positive Gleitkommawert der Wert, wenn das Low-Bit des Exponenten 1 ist und alle anderen Bits 0 sind. Der größte negative Gleitkommawert ist das bitweise Inverse davon. Ohne einen Integer-Typ, von dem bekannt ist, dass er dieselbe Größe wie der gegebene Gleitkomma-Typ aufweist, gibt es jedoch keine andere Möglichkeit, als die Ausführung einer Schleife, diese Bit-Manipulation durchzuführen. Wenn Sie einen Integertyp haben, von dem Sie wissen, dass er dieselbe Größe wie Ihr Fließkommatyp hat, können Sie dies als eine einzelne Operation ausführen.

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

Ich denke, Ihre Antwort ist die informativste, also hier ist ein upvote und meine Grüße! –

+0

Sie nehmen zwei Kompliment auf Ganzzahlen, was nicht unbedingt wahr ist. Die einzige Möglichkeit, den Wert für den maximal vorzeichenlosen Wert zu erhalten, ist '= -1', oder einige Grenzwerte sind konstant. – GManNickG

+0

@GMan: Systeme, die nicht zwei Kompliment Mathe machen, sind theoretisch möglich, aber sie sind eine historische Neugier, kein echtes Portabilitätsproblem. –