Wie überprüft man das Bitmuster eines Double ist 0x0 in einem C ++ 11 Constexpr?

8

Ich möchte überprüfen, ob eine gegebene double / float-Variable das tatsächliche Bitmuster 0x0 hat. Frag nicht warum, es wird in einer Funktion in Qt ( qIsNull() ) verwendet, die ich gerne constexpr wäre.

Der ursprüngliche Code verwendete eine Union:

%Vor%

Dies funktioniert natürlich nicht als constexpr .

Der nächste Versuch war mit reinterpret_cast :

%Vor%

Aber während dies in GCC 4.7 als constexpr funktioniert, scheitert es (zu Recht, b / c der Zeigermanipulation) in Clang 3.1.

Die letzte Idee war, Alexandrescuesque zu gehen und dies zu tun:

%Vor%

Aber das ist auch nicht clever genug für Clang:

%Vor%

Hat jemand anderes eine gute Idee?

    
Marc Mutz - mmutz 17.02.2012, 12:31
quelle

3 Antworten

6
  

Ich möchte überprüfen, ob eine gegebene double / float Variable das tatsächliche Bitmuster 0x0

hat

Aber wenn es constexpr ist, dann prüft es keine Variable , es prüft den Wert , für den diese Variable statisch bestimmt ist. Deshalb sollten Sie keine Pointer- und Union-Tricks machen, "offiziell" gibt es keinen Speicher, auf den Sie zeigen können.

Wenn Sie Ihre Implementierung davon überzeugen können, IEEE-Division-by-Zero nicht einzufangen, können Sie etwas tun wie:

%Vor%

Nur +/-0 sind gleich 0. 1/-0 ist -Inf , was nicht größer als 0 ist. 1/+0 ist +Inf , was ist. Aber ich weiß nicht, wie man diese Nicht-Überfüllungsarithmetik passieren lässt.

    
Steve Jessop 17.02.2012 13:49
quelle
5

Es scheint, dass sowohl clang ++ 3.0 als auch g ++ 4.7 (aber nicht 4.6) std::signbit als constexpr behandeln.

%Vor%     
kennytm 17.02.2012 13:54
quelle
4

Es ist nicht möglich, das zugrunde liegende Bitmuster eines double innerhalb eines konstanten Ausdrucks zu betrachten. Es gab einen Fehler im C ++ 11-Standard, der eine solche Überprüfung durch Casting über void* zuließ, aber das wurde von C ++ - Kernproblem 1312 .

Als "Beweis" hat die constexpr -Implementierung von clang (die als vollständig angesehen wird) keinen Mechanismus zum Extrahieren der Repräsentation eines konstanten double -Werts (anders als über Nicht-Standard-Vektoroperationen, und selbst dann gibt es) derzeit keine Möglichkeit, das Ergebnis zu überprüfen).

Wie andere vorgeschlagen haben, wenn Sie wissen, dass Sie auf eine Plattform abzielen, die IEEE-754 Fließkommawerte verwendet, entspricht 0x0 dem Wert positive Null. Ich glaube, der einzige Weg dies zu erkennen, der in einem konstanten Ausdruck sowohl in clang als auch in g ++ funktioniert, ist __builtin_copysign :

%Vor%     
Richard Smith 02.03.2012 06:06
quelle