minimaler doppelter Wert in C/C++

Lesezeit: 7 Minuten

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.

  • 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

Benutzeravatar von dfa
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 p2 von C99 (kann seitdem an einen anderen Ort verschoben worden sein).

    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_MAXverneinend DBL_MAX kann auch keine Rundungsfehler einführen.

    Benutzer743382

    11. November 2014 um 8:35 Uhr


Benutzeravatar von fortran
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

Benutzeravatar von rubenvb
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.

Benutzeravatar von Christoph
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

Benutzeravatar der Community
Gemeinschaft

Eine wirklich portable C++-Lösung

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 denen is_bounded != false.

Online-Demo


Viele nicht portierbare C++-Antworten hier!

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:

Geben Sie hier die Bildbeschreibung ein

Warum sind diese nicht tragbar?

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

- std::numeric_limits<double>::max()

sollte gut funktionieren

Numerische Grenzen

1421560cookie-checkminimaler doppelter Wert in C/C++

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy