Hashvalue für doubles mittels reinterpret_cast: Deref Type-Pun-Zeigers verursacht seg-faults, wie vermeiden?



  • Hallo,

    ich habe eine Funktion die aus einem double-vektor einen "eindeutigen" Schlüssel generieren soll. Dazu werden einfach pro double-Wert ein Hash-Value berechnet und zum alten schlüssel mit einem-mix-value und einer Primzahl hinzuaddiert.

    Unter meinem alten comiler der version gcc 3.4 (oder sowas) ging alles einwandfrei. Jetzt unter meinem neuen gcc 4.1.3 compiler nicht mehr. Es gibt
    Warnungen vom Compiler beim Compilieren (was vorher nicht der Fall war) und zwar:

    Warnung: Dereferenzierung eines Type-Pun-Zeigers verletzt strict-aliasing-Regeln
    

    Nun zur Arbeitsweise von Hash_Double:
    Ich habe einen 64 Bit Wert und will einen 32 Bit wert daraus generieren der möglichst "unikat" wird. Dazu mache ich ein Xor der unteren und oberen 32 Bit
    der 64 Bit Zahl und gebe Sie zurück.

    Im Moment überlege ich wie ich evtl. den reinterpret_cast umgehen kann bzw. wie ich diese Hash-Value Berechnung allgemein ändern könnte. Für Ideen bzw. auch Ratschläge was den cast oder gar einen komplett anderen Weg angeht wäre ich sehr dankbar.

    Evtl. sollte ich auf 64 Bit Schlüsseln arbeiten und da versuchen einen neuen Weg einzuschlagen?

    typedef unsigned long long U_Int64; 
    typedef unsigned int U_Int32;
    
    template <>	U_Int32 
    Cache<double>::Compute_Key(	const double* vec, 
    							size_t size) const
    {                    
    	U_Int32 ret = 0;
    	U_Int32 mix = Hash_Double(0.13);
    	while(size--)
    	{
    		ret = (ret * 31) + mix + Hash_Double(*vec);
    		vec++;
    	} 
    	return ret;
    }
    
    template <class T>	inline U_Int32 
    Cache<T>::Hash_Double(double x)
    { 
    	U_Int64* p = reinterpret_cast< U_Int64* > (&x); 
    	return *p ^ (*p >> 32); 
    }
    

  • Mod

    template <class T>    inline U_Int32
    Cache<T>::Hash_Double(const double& x)
    {
        U_Int32 p[2];
        memcpy( p, &x, sizeof p );
        return p[0] ^ p[1];
    }
    


  • Danke, so gehts einwandfrei wieder!


Anmelden zum Antworten