Gibt es eine standardisierte und/oder portable Möglichkeit, den kleinsten negativen Wert (z. B. negative Unendlichkeit) in einem C(++)-Programm darzustellen?
DBL_MIN in float.h ist das kleinste positiv Nummer.
Gibt es eine standardisierte und/oder portable Möglichkeit, den kleinsten negativen Wert (z. B. negative Unendlichkeit) in einem C(++)-Programm darzustellen?
DBL_MIN in float.h ist das kleinste positiv Nummer.
dfa
-DBL_MAX
in ANSI-Cdie in float.h definiert ist.
Dies scheint das Standard- und Tragbarste zu sein
– Werden
20. Juli 2009 um 13:50 Uhr
Hier ist die Erklärung für mein -1: Wer oder was sagt, dass -DBL_MAX von der C- oder C++-Sprache garantiert darstellbar ist, ganz zu schweigen vom darstellbaren Mindestwert? Die Tatsache, dass die meiste FP-Hardware IEEE 754-konform ist und diese Darstellung verwendet, bedeutet nicht, dass -DBL_MAX garantiert auf jeder standardkonformen C-Plattform funktioniert.
– j_random_hacker
11. August 2013 um 23:01 Uhr
@j_random_hacker: siehe Fortrans Antwort ‘unten’.
– JohnTortugo
13. Mai 2014 um 21:07 Uhr
@j_random_hacker Das ist ein sehr guter Punkt, aber der C-Standard erfordert -DBL_MAX
genau darstellbar sein, also wenn die FP-Hardware dazu nicht in der Lage ist, muss die Implementierung einfach darum herum arbeiten. Siehe das Fließkommamodell in 5.2.4.2.2 Eigenschaften von Floating-Typen
– Benutzer743382
10. November 2014 um 22:23 Uhr
@j_random_hacker Ja, aber p2 gibt an, dass e_min und e_max unabhängig vom Vorzeichenbit sind, also DBL_MAX
genau (1 − b^−p)b^e_max ist, was genau darstellbar ist, ist der negativste endliche Wert genau -(1 − b^−p)b^e_max, und da das zufällig genau ist -DBL_MAX
verneinend DBL_MAX
kann auch keine Rundungsfehler einführen.
– Benutzer743382
11. November 2014 um 8:35 Uhr
Fortran
Fließkommazahlen (IEEE 754) sind symmetrisch, wenn Sie also den größten Wert darstellen können (DBL_MAX
oder numeric_limits<double>::max()
), stellen Sie einfach ein Minuszeichen voran.
Und dann ist der coole Weg:
double f;
(*((uint64_t*)&f))= ~(1LL<<52);
+1 Für den Hinweis auf die Symmetrie von Gleitkommazahlen 🙂
– Andreas Hase
20. Juli 2009 um 13:35 Uhr
Was ist mit C/C++-Implementierungen, die keine IEEE 754-Gleitkommazahlen verwenden?
– Steve Jessop
20. Juli 2009 um 20:03 Uhr
gccs Handbuch für -ffast-math sagt “Setzt -fno-math-errno, -funsafe-math-optimizations, -finite-math-only, -fno-rounding-math, -fno-signaling-nans und -fcx-limited- Bereich Diese Option wird von keiner -O-Option eingeschaltet, da sie bei Programmen, die von einer exakten Implementierung von IEEE- oder ISO-Regeln/Spezifikationen für mathematische Funktionen abhängen, zu einer falschen Ausgabe führen kann, jedoch schnelleren Code für Programme liefern kann, die dies tun erfordern nicht die Garantien dieser Spezifikationen.” Schnelle Mathematik ist eine gängige Einstellung, und das Intel ICC zum Beispiel ist standardmäßig darauf eingestellt. Alles in allem weiß ich nicht, was das für mich bedeutet 🙂
– Werden
20. Juli 2009 um 22:30 Uhr
Dies bedeutet, dass Implementierungen keine IEEE 754-Arithmetik verwenden, aber um fair zu sein, verwenden diese Optionen immer noch die IEEE-Darstellung. Möglicherweise finden Sie einige Emulationsbibliotheken, die eine Nicht-IEEE-Darstellung verwenden, da nicht alle Prozessoren ein natives Float-Format haben (obwohl sie möglicherweise ein CABI veröffentlichen, das ein Format enthält, das den vom Hersteller gelieferten Emulationsbibliotheken entspricht). Daher können nicht alle Compiler einen verwenden. Kommt nur darauf an, was Sie meinen, wenn Sie nach “Standard und / oder tragbar” fragen, es gibt im Prinzip tragbar und in der Praxis tragbar.
– Steve Jessop
20. Juli 2009 um 22:59 Uhr
Was Sie sagen, gilt für IEEE 754, aber der Standard erfordert nicht die Verwendung dieser Codierung (wie @SteveJessop betont, ist tragbar in der Praxis im Prinzip nicht dasselbe wie tragbar).
– Christoph
22. September 2016 um 20:51 Uhr
rubenvb
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();
War das nicht min()
Funktion vor C++11 verfügbar? Oder ist das ein anderer Wert als -max()
? en.cppreference.com/w/cpp/types/numeric_limits
– Alexis Wilke
23. Oktober 2014 um 3:12 Uhr
@Alexis: Wenn Sie sich die untersten drei Zeilen in der Tabelle auf der Seite ansehen, die Sie verlinkt haben, sehen Sie das min
erhält man den kleinsten positiven Wert in der Größenordnung und lowest
der betragsmäßig größte negative Wert. Ja, es ist schrecklich. Willkommen in der brillanten Welt der C++-Standardbibliothek :-P
.
– rubenvb
23. Oktober 2014 um 7:08 Uhr
für C ist es definiert in float.h
. limits.h
ist für ganze Zahlen
– Ciprian Tomoiagă
18. Februar 2015 um 18:46 Uhr
Versuche dies:
-1 * numeric_limits<double>::max()
Bezug: numeric_limits
Diese Klasse ist auf jeden der grundlegenden Typen spezialisiert, wobei ihre Member die verschiedenen Werte zurückgeben oder auf diese setzen, die die Eigenschaften definieren, die dieser Typ auf der spezifischen Plattform hat, auf der er kompiliert wird.
Christoph
Suchen Sie nach der tatsächlichen Unendlichkeit oder dem minimalen endlichen Wert? Wenn ersteres, verwenden Sie
-numeric_limits<double>::infinity()
was nur funktioniert, wenn
numeric_limits<double>::has_infinity
Andernfalls sollten Sie verwenden
numeric_limits<double>::lowest()
die in C++11 eingeführt wurde.
Wenn lowest()
nicht vorhanden ist, können Sie darauf zurückgreifen
-numeric_limits<double>::max()
wovon abweichen kann lowest()
im Prinzip, aber normalerweise nicht in der Praxis.
+1 für den Unterschied zwischen endlichem und unendlichem Wert! Der Standard garantiert jedoch keine symmetrische Gleitkommacodierung. So -numeric_limits<double>::max()
Auch wenn es in der Praxis funktioniert, ist es theoretisch nicht vollständig tragbar.
– Christoph
22. September 2016 um 20:53 Uhr
@Christoph: [x] Fest
– Christoph
22. September 2016 um 21:45 Uhr
Gemeinschaft
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, wo
y < x
.
Sinnvoll für alle Fachrichtungen, in denenis_bounded != false
.
Es gibt viele Antworten -std::numeric_limits<double>::max()
.
Glücklicherweise werden sie in den meisten Fällen gut funktionieren. Fließkommacodierungsschemata zerlegen eine Zahl in eine Mantisse und einen Exponenten und die meisten von ihnen (z. B. die populäre IEEE-754) verwenden ein eindeutiges Vorzeichenbit, das nicht zur Mantisse gehört. Dies ermöglicht es, das größte Positiv in das kleinste Negativ zu verwandeln, indem man einfach das Vorzeichen umkehrt:
Der Standard schreibt keinen Fließkommastandard vor.
Ich stimme zu, dass mein Argument ein wenig theoretisch ist, aber angenommen, dass ein exzentrischer Compiler-Hersteller ein revolutionäres Codierungsschema mit einer Mantisse verwenden würde, die in einigen Variationen von a codiert ist Zweierkomplement. Zweierkomplementcodierungen sind nicht symmetrisch. Beispielsweise ist für ein vorzeichenbehaftetes 8-Bit-Zeichen der maximale positive Wert 127, aber der minimale negative Wert -128. Wir könnten uns also vorstellen, dass eine Gleitkommacodierung ein ähnliches asymmetrisches Verhalten zeigt.
Mir ist kein solches Codierungsschema bekannt, aber der Punkt ist der Der Standard garantiert nicht, dass das Umdrehen des Vorzeichens das beabsichtigte Ergebnis liefert. Diese beliebte Antwort (sorry Leute!) Kann also nicht als vollständig portable Standardlösung betrachtet werden! /* zumindest nicht, wenn Sie das nicht behauptet haben numeric_limits<double>::is_iec559
ist wahr */
+1 für den Unterschied zwischen endlichem und unendlichem Wert! Der Standard garantiert jedoch keine symmetrische Gleitkommacodierung. So -numeric_limits<double>::max()
Auch wenn es in der Praxis funktioniert, ist es theoretisch nicht vollständig tragbar.
– Christoph
22. September 2016 um 20:53 Uhr
@Christoph: [x] Fest
– Christoph
22. September 2016 um 21:45 Uhr
Ich werde mich für -DBL_MAX entscheiden, aber ich bin mir sicher, dass es einen technischen Grund gibt, warum das nicht so ist 🙂
– anon
20. Juli 2009 um 13:27 Uhr
@Neil, nein, gibt es nicht, es ist nicht wie 2 Komplement-Ganzzahlen
– Fortran
20. Juli 2009 um 13:33 Uhr
Ich habe im Standard noch nichts gesehen, was besagt, dass der Bereich der Fließkommatypen symmetrisch um Null sein muss. Aber die Konstanten in limits.h und deuten darauf hin, dass sowohl der C- als auch der C++-Standard dies erwarten.
– Steve Jessop
20. Juli 2009 um 20:03 Uhr
Tatsächlich ist DBL_MIN in float.h das kleinste positiv normalisiert Nummer. Es gibt noch kleinere Zahlen.
– fdermishin
18. März 2013 um 18:34 Uhr
@fortran: IEEE754 FP verwendet ein Vorzeichenbit, und sicherlich ist heutzutage die meiste FP-Hardware IEEE 754. Aber C und C++ unterstützen nicht-IEEE 754 FP-Hardware, daher ist die Frage offen, ob die Sprache garantiert, dass -DBL_MAX gleich dem sein muss minimal darstellbarer Wert.
– j_random_hacker
11. August 2013 um 22:58 Uhr