Gibt es eine C ++ - Standardkonforme Methode zum Bestimmen der Struktur von 'float', 'double' und 'long double' zur Kompilierungszeit (oder Laufzeit als Alternative)?
Wenn ich std::numeric_limits< T >::is_iec559 == true
und std::numeric_limits< T >::radix == 2
annahm, vermute ich, dass dies durch die folgenden Regeln möglich ist:
mit den folgenden vagen Formulierungen:
size_t num_significand_bits = std::numeric_limits< T >::digits;
size_t num_exponent_bits = log2( 2 * std::numeric_limits< T >::max_exponent );
size_t num_sign_bits = 1u;
außer ich weiß
std::numeric_limits< T >::digits
enthält das "Integer-Bit", unabhängig davon, ob das Format es explizit darstellt oder nicht, daher weiß ich nicht, wie ich dies programmatisch erkennen und anpassen kann. std::numeric_limits< T >::max_exponent
ist immer 2^(num_exponent_bits)/2
. Hintergrund : Ich versuche zwei Probleme portabel zu lösen:
Kurz gesagt, nein. Wenn std::numeric_limits<T>::is_iec559
, dann du
kenne das Format von T
, mehr oder weniger: du musst noch
Bestimmen Sie die Byte-Reihenfolge. Für alles andere sind alle Wetten deaktiviert.
(Die anderen Formate, die ich kenne und die noch immer benutzt werden, sind nicht gleich
Basis 2: IBM Mainframes verwenden zum Beispiel die Basis 16)
"Standard" -Anordnung eines IEC-Gleitkommazeichens hat das Vorzeichen an
das höherwertige Bit, dann der Exponent und die Mantisse auf der
Bits niedriger Ordnung; wenn Sie es als erfolgreich ansehen können
uint64_t
, zum Beispiel (via memcpy
, reinterpret_cast
oder
union
- 'memcpy funktioniert garantiert, ist aber weniger
effizienter als die anderen beiden), dann:
für double
:
für 'float:
%Vor% In Bezug auf long double
ist es schlimmer, weil anders
Compiler behandeln es anders, sogar auf der gleichen Maschine.
Nominell ist es zehn Bytes, aber aus Gründen der Ausrichtung kann es in
Tatsache sein 12 oder 16. Oder nur ein Synonym für double
. Wenn es ist
Mehr als 10 Bytes, denke ich kannst du darauf zählen, dass es gepackt wird
in die ersten 10 Bytes, so dass &myLongDouble
die
Adresse des 10-Byte-Wertes. Aber im Allgemeinen würde ich vermeiden
long double
.
Ich würde sagen, dass der einzige tragbare Weg ist, die Nummer als String zu speichern. Dies beruht nicht auf "Bitmuster interpretieren"
Auch wenn Sie wissen, wie viele Bits etwas ist, bedeutet das nicht, dass es die gleiche Repräsentation hat - der Exponent ist nullbasiert oder voreingenommen. Gibt es eine unsichtbare 1 an der Vorderseite der Mantisse? Das Gleiche gilt für alle anderen Teile der Nummer. Und es wird noch schlimmer für BCD-kodierte oder "hexadezimale" Floats - diese sind in einigen Architekturen verfügbar ...
Wenn Sie sich Sorgen um nicht initialisierte Bits in einer Struktur (Klasse, Array usw.) machen, verwenden Sie memset, um die gesamte Struktur auf Null [oder einen anderen bekannten Wert] zu setzen.
Für die Nachwelt habe ich das getan.
Um meine IEEE-754-Signalisierungs-NaN-Werte zu generieren und zu testen, verwende ich dieses Muster für 'float' und 'double'.
%Vor%Für 'long double' verwende ich die 'doppelten' Funktionen beim Casting. Insbesondere erzeuge ich den "doppelten" Wert und wandle ihn vor der Rückgabe in "long double" um, und ich teste das "long double", indem ich es "verdopple" und dann diesen Wert teste. Meine Idee ist, dass das "Long Double" -Format variieren kann, wenn man ein "Double" in ein "Long Double" umwandelt, sollte es später konsistent sein (dh keine Information verlieren) / p>
Tags und Links c++ floating-point ieee-754 portability bit-representation