Voglio verificare che una determinata variabile double/float abbia il bit pattern effettivo 0x0. Non chiedere perché, è utilizzato in una funzione in Qt (qIsNull()
) che mi piacerebbe essere constexpr
.Come verificare il pattern a bit di un doppio è 0x0 in un constexpr C++ 11?
Il codice originale utilizzato un sindacato:
union { double d; int64_t i; } u;
u.d = d;
return u.i == 0;
Questo non funziona come constexpr
naturalmente.
Il tentativo successivo è stato con reinterpret_cast
:
return *reinterpret_cast<int64_t*>(&d) == 0;
Ma mentre che funziona come un constexpr
in GCC 4.7, non riesce (giustamente, b/c del puntatore manipolazione) in Clang 3.1.
L'idea finale è stato di andare Alexandrescuesque e fare questo:
template <typename T1, typename T2>
union Converter {
T1 t1;
T2 t2;
explicit constexpr Converter(T1 t1) : t1(t1) {}
constexpr operator T2() const { return t2; }
};
// in qIsNull():
return Converter<double,int64_t>(d);
Ma non è abbastanza intelligente per Clang, sia:
note: read of member 't2' of union with active member 't1' is not allowed in a constant expression
constexpr operator T2() const { return t2; }
^
Qualcun altro ha una buona idea?
Credo che ci sono altri schemi di bit che rappresentano anche una virgola mobile 0, che don vuoi trovare? –
Esistono esattamente due modelli di bit che rappresentano 0. Sono 000 ... 000 e 100 ... 000. Il primo bit è il bit del segno. Il secondo schema di bit viene talvolta definito "zero negativo". – user763305
Forse 'return d == 0 && 1/d> 0;'? (http://en.wikipedia.org/wiki/Signed_zero#Comparisons) –