2010-04-21 11 views
70

Wie kann ich einen absoluten Höchst- oder Mindestwert für ein Float oder Double fest codieren? Ich möchte die Max/Min eines Arrays durch einfaches Iterieren und Erfassen des größten suchen.Wie initialisiere ich einen Float auf seinen maximalen/minimalen Wert?

Es gibt auch positive und negative Unendlichkeit für Schwimmer, sollte ich diese stattdessen verwenden? Wenn ja, wie bezeichne ich das in meinem Code?

Antwort

113

Sie können std::numeric_limits verwenden, das in <limits> definiert ist, um den minimalen oder maximalen Wert von Typen zu finden (solange eine Spezialisierung für den Typ existiert). Sie können es auch verwenden, um Unendlich (und setzen Sie eine - in Front für negative Unendlichkeit).

#include <limits> 

//... 

std::numeric_limits<float>::max(); 
std::numeric_limits<float>::min(); 
std::numeric_limits<float>::infinity(); 

Wie in den Kommentaren erwähnt, min() gibt den niedrigsten möglichen positiven Wert. Mit anderen Worten, der positive Wert, der 0 am nächsten kommt, kann dargestellt werden. Der niedrigste mögliche Wert ist der negative Wert des maximal möglichen Wertes.

Es gibt natürlich die std::max_element und min_element Funktionen (definiert in <algorithm>), die eine bessere Wahl in einem Array für die Suche nach den größten oder kleinsten Wert sein kann.

+0

Wie verwende ich das genau? Was muss ich einbeziehen? Ich glaube nicht, dass ich so etwas schon einmal benutzt habe. – Faken

+0

Hmm ... dass die Max-Element-Funktion sehr nützlich gewesen wäre ... das passiert, wenn Sie selbst und nicht formal lernen. Am Ende erfinden Sie das Rad 50-mal neu. Das ist genau wie beim letzten Mal, als ich von ceil() erfuhr. Vielen Dank. – Faken

+16

@Yacoby, möchten Sie vielleicht klar, dass numeric_limits :: min() bedeutet nicht am meisten negativen Wert, es bedeutet kleinste positive. – MSN

5

manuell Um das Minimum eines Arrays finden Sie benötigen, um den Minimalwert des Schwimmers nicht wissen:

float myFloats[]; 
... 
float minimum = myFloats[0]; 
for (int i = 0; i < myFloatsSize; ++i) 
{ 
    if (myFloats[i] < minimum) 
    { 
    minimum = myFloats[i]; 
    } 
} 

und ähnlichen Code für den Maximalwert.

4

Darf ich vorschlagen, dass Sie Ihre Variablen "max und min so weit" nicht auf unendlich, sondern auf die erste Zahl im Array initialisieren?

+0

Bill war schneller. –

15

Es gibt keine wirkliche Notwendigkeit zu kleinsten/größtmöglichen finden den kleinsten/größten im Array zu initialisieren:

double largest = smallest = array[0]; 
for (int i=1; i<array_size; i++) { 
    if (array[i] < smallest) 
     smallest = array[i]; 
    if (array[i] > largest0 
     largest= array[i]; 
} 

Oder, wenn Sie tun es mehr als einmal:

#include <utility> 

template <class iter> 
std::pair<typename iter::value_type, typename iter::value_type> find_extrema(iter begin, iter end) { 
    std::pair<typename iter::value_type, typename iter::value_type> ret; 
    ret.first = ret.second = *begin; 
    while (++begin != end) { 
     if (*begin < ret.first) 
      ret.first = *begin; 
     if (*begin > ret.second) 
      ret.second = *begin; 
    } 
    return ret; 
} 

Der Nachteil der Bereitstellung von Beispielcode - ich sehe andere haben bereits die gleiche Idee vorgeschlagen.

Beachten Sie, dass, während der Standard ein min_element und max_element hat, die Verwendung dieser Daten ein zweimaliges Durchsuchen der Daten erfordern würde, was ein Problem darstellen könnte, wenn das Array überhaupt groß ist. Jüngere Standards haben dies durch Hinzufügen einer std::minmax_element, die das gleiche wie die obigen find_extrema (finden Sie die minimalen und maximalen Elemente in einer Sammlung in einem einzigen Durchgang).

Bearbeiten: Adressieren des Problems der Suche nach dem kleinsten Wert ungleich Null in einem Array von unsigned: Beachten Sie, dass vorzeichenlose Werte "wrap around", wenn sie ein Extrem erreichen. Um den kleinsten Wert ungleich Null zu finden, können wir für den Vergleich jeweils eins abziehen. Alle Nullwerte werden auf den größtmöglichen Wert für den Typ "umgebrochen", aber die Beziehung zwischen anderen Werten wird beibehalten. Nachdem wir fertig sind, fügen wir natürlich einen zurück zu dem Wert hinzu, den wir gefunden haben.

unsigned int min_nonzero(std::vector<unsigned int> const &values) { 
    if (vector.size() == 0) 
     return 0; 
    unsigned int temp = values[0]-1; 
    for (int i=1; i<values.size(); i++) 
     if (values[i]-1 < temp) 
      temp = values[i]-1; 
    return temp+1; 
} 

Hinweis: dieser verwendet immer noch das erste Element für den Anfangswert, aber wir müssen noch keinen „Sonderfall“ Code - da, dass rund um den grösstmöglichen Wert wickeln wird, alle Nicht-Null-Wert wird als kleiner vergleichen. Das Ergebnis ist der kleinste Nicht-Null-Wert oder 0, wenn und nur wenn der Vektor keine Nicht-Null-Werte enthält.

+0

Aber du bekommst von mir ein +1 dafür! –

+0

Ich initialisiere auf max Minuten, weil ich manchmal den kleinsten Wert ungleich Null (in einem unsigned Integer Fall zum Beispiel, meine Daten neigen dazu, viele uninteressante Nullen haben). Es scheint nur sinnvoll zu sein, es zu initialisieren, anstatt zusätzliche Überprüfungen durchzuführen, um sicherzustellen, dass das erste Element nicht Null ist. – Faken

+0

@Faken: Selbst dann können Sie eine Vergleichsfunktion definieren, die Null als größtmöglichen Wert behandelt, so dass Sie 'std :: min_element' weiterhin verwenden können:' bool less_ignoring_zero (unsigned a, unsigned b) {if (a == 0) falsch zurückgeben; wenn (b == 0) wahr zurückgibt; zurückgeben a UncleBens

32

Sie können entweder -FLT_MAX (oder -DBL_MAX) für die maximale Größe negative Zahl und FLT_MAX (oder DBL_MAX) für positive verwenden. Dies gibt Ihnen den Bereich möglicher Float (oder Double) -Werte.

Sie möchten wahrscheinlich nicht verwenden FLT_MIN; es entspricht der positiven Zahl der kleinsten Größe, die mit einem Gleitkomma dargestellt werden kann, und nicht dem negativsten Wert, der mit einem Gleitkomma dargestellt werden kann.

FLT_MIN und FLT_MAX entsprechen std::numeric_limits<float>::min() und std::numeric_limits<float>::max().

+0

Ich denke, ich werde diese Version tatsächlich verwenden, es ist einfacher zu merken und macht mehr Szene für mich. Integer kann ich nur mit hexadezimal initialisieren. Die beste Antwort bleibt jedoch, denn die Antwort führte mich auch zu einigen neuen, äußerst nützlichen Funktionen. – Faken

+2

"[' FLT_MIN'] entspricht der kleinsten positiven Zahl, die mit einem Float dargestellt werden kann "- ** Das ist nicht wahr **. Es ist die kleinste * normale * Nummer. Es gibt auch subnormale Zahlen. – nibot

+0

Sie wollen 'FLT_TRUE_MIN' für die tatsächliche kleinstmögliche Gleitkommazahl, die' std :: numeric_limits :: denorm_min() 'entspricht –

Verwandte Themen