Gibt es eine Standard- und / oder tragbare Methode, um den kleinsten negativen Wert (z. B. negative Unendlichkeit) in einem C (++) -Programm darzustellen?
DBL_MIN in float.h ist die kleinste positive Zahl.
Gibt es eine Standard- und / oder tragbare Methode, um den kleinsten negativen Wert (z. B. negative Unendlichkeit) in einem C (++) -Programm darzustellen?
DBL_MIN in float.h ist die kleinste positive Zahl.
Antworten:
-DBL_MAX
in ANSI C , das in float.h definiert ist.
-DBL_MAX
genau darstellbar sein. Wenn die FP-Hardware dazu nicht in der Lage ist, muss die Implementierung ihn nur umgehen . Siehe das Gleitkommamodell in 5.2.4.2.2 Eigenschaften der Gleitkommatypen <float.h> p2 von C99 (möglicherweise seitdem an einen anderen Ort verschoben).
DBL_MAX
genau (1 - b ^ - p) b ^ e_max, was genau darstellbar ist, der negativste endliche Wert ist genau - (1 - b ^ −p) b ^ e_max, und da dies genau der Fall ist -DBL_MAX
, DBL_MAX
kann das Negieren auch keine Rundungsfehler verursachen.
Gleitkommazahlen (IEEE 754) sind symmetrisch. Wenn Sie also den größten Wert ( DBL_MAX
oder numeric_limits<double>::max()
) darstellen können, stellen Sie einfach ein Minuszeichen voran.
Und dann ist der coole Weg:
double f;
(*((long long*)&f))= ~(1LL<<52);
Verwenden Sie in C
#include <float.h>
const double lowest_double = -DBL_MAX;
Verwenden Sie in C ++ vor 11
#include <limits>
const double lowest_double = -std::numeric_limits<double>::max();
Verwenden Sie in C ++ 11 und höher
#include <limits>
constexpr double lowest_double = std::numeric_limits<double>::lowest();
min()
Funktion vor C ++ 11 nicht verfügbar? Oder ist das ein anderer Wert als -max()
? en.cppreference.com/w/cpp/types/numeric_limits
min
Sie den kleinsten positiven Wert in der Größe und lowest
den größten negativen Wert in der Größe erhalten. Ja, es ist schrecklich. Willkommen in der brillanten Welt der C ++ - Standardbibliothek :-P
.
float.h
. limits.h
ist für ganze Zahlen
Versuche dies:
-1 * numeric_limits<double>::max()
Referenz: numeric_limits
Diese Klasse ist auf jeden der grundlegenden Typen spezialisiert, wobei ihre Mitglieder die verschiedenen Werte zurückgeben oder festlegen, die die Eigenschaften definieren, die der Typ in der spezifischen Plattform hat, auf der er kompiliert wird.
-numeric_limits<double>::max()
?
-1 * ...
, um es etwas klarer zu machen.
Suchen Sie nach der tatsächlichen Unendlichkeit oder dem minimalen endlichen Wert? Wenn erstere, verwenden Sie
-numeric_limits<double>::infinity()
was nur funktioniert wenn
numeric_limits<double>::has_infinity
Andernfalls sollten Sie verwenden
numeric_limits<double>::lowest()
Das wurde in C ++ 11 eingeführt.
Wenn lowest()
nicht verfügbar, können Sie auf zurückgreifen
-numeric_limits<double>::max()
was lowest()
im Prinzip abweichen kann, in der Praxis aber normalerweise nicht.
-numeric_limits<double>::max()
auch wenn es in der Praxis funktioniert , ist nicht vollständig tragbar in der Theorie.
Ab C ++ 11 können Sie verwenden numeric_limits<double>::lowest()
. Gemäß dem Standard gibt es genau das zurück, wonach Sie suchen:
Ein endlicher Wert x, so dass es keinen anderen endlichen Wert y gibt
y < x
.
Sinnvoll für alle Spezialisierungen, in denenis_bounded != false
.
Es gibt viele Antworten -std::numeric_limits<double>::max()
.
Glücklicherweise funktionieren sie in den meisten Fällen gut. Gleitkomma-Codierungsschemata zerlegen eine Zahl in einer Mantisse und einen Exponenten, und die meisten von ihnen (z. B. das beliebte IEEE-754 ) verwenden ein eindeutiges Vorzeichenbit, das nicht zur Mantisse gehört. Dies ermöglicht es, das größte Positiv in das kleinste Negativ umzuwandeln, indem Sie einfach das Vorzeichen umdrehen:
Der Standard schreibt keinen Gleitkomma-Standard vor.
Ich stimme zu, dass mein Argument ein wenig theoretisch ist, aber nehmen wir an, dass ein exzentrischer Compilerhersteller ein revolutionäres Codierungsschema mit einer Mantisse verwenden würde, die in einigen Variationen des Zweierkomplements codiert ist . Die Zweierkomplementcodierung ist nicht symmetrisch. Beispielsweise ist für ein vorzeichenbehaftetes 8-Bit-Zeichen das maximale positive 127, das minimale negative -128. Wir könnten uns also vorstellen, dass einige Gleitkomma-Codierungen ein ähnliches asymmetrisches Verhalten zeigen.
Mir ist kein solches Codierungsschema bekannt, aber der Punkt ist, dass der Standard nicht garantiert, dass das Umdrehen der Vorzeichen das beabsichtigte Ergebnis liefert . Diese beliebte Antwort (sorry Leute!) Kann also nicht als vollständig tragbare Standardlösung angesehen werden! / * zumindest nicht, wenn du nicht behauptet hast, dass numeric_limits<double>::is_iec559
das wahr ist * /
Die ursprüngliche Frage betrifft die Unendlichkeit. Also, warum nicht verwenden
#define Infinity ((double)(42 / 0.0))
nach der IEEE-Definition? Das können Sie natürlich negieren.
numeric_limits<double>::has_infinity && ! numeric_limits<double>::traps
Gibt es eine Standard- und / oder tragbare Methode, um den kleinsten negativen Wert (z. B. negative Unendlichkeit) in einem C (++) -Programm darzustellen?
C-Ansatz.
Viele Implementierungen unterstützen +/- Unendlichkeiten, daher ist der negativste double
Wert -INFINITY
.
#include <math.h>
double most_negative = -INFINITY;
Gibt es einen Standard- und / oder tragbaren Weg ....?
Jetzt müssen wir auch andere Fälle berücksichtigen:
Einfach -DBL_MAX
.
Ich würde in diesem Fall erwarten, OP würde es vorziehen -DBL_MAX
.
DBL_MAX
.Dies ist ein ungewöhnlicher Fall, der wahrscheinlich außerhalb der Besorgnis von OP liegt. Wenn double
es als Paar von Gleitkommazahlen codiert wird , um den gewünschten Bereich / die gewünschte Präzession zu erreichen (siehe Doppel-Doppel ), gibt es eine maximale Normalen double
und möglicherweise eine größere De-Normalen . Ich habe eine Debatte gesehen, wenn ich mich DBL_MAX
auf die größte Normalität beziehen sollte, auf die größte von beiden.
Glücklicherweise enthält dieser gepaarte Ansatz normalerweise eine -Infinity, sodass der negativste Wert erhalten bleibt -INFINITY
.
Für mehr Portabilität kann Code die Route entlang gehen
// HUGE_VAL is designed to be infinity or DBL_MAX (when infinites are not implemented)
// .. yet is problematic with unsigned infinity.
double most_negative1 = -HUGE_VAL;
// Fairly portable, unless system does not understand "INF"
double most_negative2 = strtod("-INF", (char **) NULL);
// Pragmatic
double most_negative3 = strtod("-1.0e999999999", (char **) NULL);
// Somewhat time-consuming
double most_negative4 = pow(-DBL_MAX, 0xFFFF /* odd value */);
// My suggestion
double most_negative5 = (-DBL_MAX)*DBL_MAX;
Wenn Sie keine Float-Ausnahmen aktiviert haben (die Sie nicht imho sollten), können Sie einfach sagen:
double neg_inf = -1/0.0;
Dies ergibt eine negative Unendlichkeit. Wenn Sie einen Float benötigen, können Sie entweder das Ergebnis umwandeln
float neg_inf = (float)-1/0.0;
oder verwenden Sie eine Arithmetik mit einfacher Genauigkeit
float neg_inf = -1.0f/0.0f;
Das Ergebnis ist immer das gleiche, es gibt genau eine Darstellung der negativen Unendlichkeit in einfacher und doppelter Genauigkeit und sie konvertieren wie erwartet ineinander.
-INFINITY
neg_inf
auf einen konstanten Wert initialisiert ist . Der Compiler kümmert sich um die Berechnung des inf
Wertes. Wenn Sie es als Nullwert für die Berechnung eines Maximums verwenden, wird es bei der ersten Iteration im Allgemeinen mit einem größeren Wert überschrieben. Dh die Leistung ist kaum ein Problem. Und das OP fragt speziell nach "zB negative Unendlichkeit verwenden" und -inf
ist in der Tat die einzig richtige Antwort darauf. Sie haben eine korrekte und nützliche Antwort abgelehnt.