Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Könnt ihr mir diese Funktion erklären?

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
000
25.10.2006, 00:49 Uhr
~derMond
Gast


Hallo,

ich verstehe einfach folgende Funktion (noch) nicht.

C++:
typedef unsigned int U_Int32;
typedef unsigned long long U_Int64;
...
inline U_Int32
hash_d(double x) const
{
    U_Int64* p = reinterpret_cast< U_Int64* > (&x);
    return *p ^ (*p >> 32);
}



was passiert genau mit den Bitwerten.
Soweit mein Versuch:
* casten des 32 Bit Inhalts auf 64 Bit Pointer.
* wird dann sowas mit dem shiften angestellt?: 1001 -> 0000 1001 wegen em p >> 32 ?
und dann wird XOR genommen also kommt dann sowas raus? 1001 1001 ?

Ich wäre dankbar wenn mir jemand genau sagen könnte as mit den bits passiert bzw. warum diese Typen so verwendet werden?

Danke vielmals
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
25.10.2006, 08:49 Uhr
ao

(Operator)


x ist eine double-Variable (64 Bit Fließkomma). Über den reinterpret_cast wird sie als 64-Bit-Ganzzahl zugänglich gemacht. Das ist nötig, weil die XOR- und Schiebe-Operatoren nur auf Ganzzahlen angewendet werden können.

p ist danach ein Zeiger auf eine 64-Bit-Ganzzahl, die das Bitmuster enthält, das (als double interpretiert) dem Wert x entspricht. Bisschen kompliziert, aber beim Bitfrickeln gehts oft so zu.

Jetzt gehts los. *p >> 32 schiebt den 64-Bit-Wert um 32 Stellen nach rechts, dabei wird von links mit Nullen aufgefüllt. Das ergibt also einen 64-Bit-Wert, der in den 32 oberen Bits Null ist und in den 32 unteren Bits die oberen Bits von *p enthält.

Jetzt kommt XOR. XOR bedeutet, es wird bitweise verglichen und die Stellen, die gleiche Werte enthalten (beide 0 oder beide 1), werden im Ergebnis 0, und die Stellen, die verschiedene Bits enthalten, werden 1. Das ziehen wir von links nach rechts durch und erhalten ein 64 Bit langes Ergebnis.

Dieses wird in der Rückgabe auf 32 Bit gekürzt (Rückgabetyp ist U_Int32), d.h. die oberen 32 Bit werden weggeworfen, und nur die unteren 32 werden verwendet.

Unterm Strich bleibt also als Ergebnis die VerXORung der oberen 32 Bit von x (*p>>32) mit den unteren.

Ich hoffe, das hilft weiter.

ao
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
25.10.2006, 09:04 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


VerXORung
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
25.10.2006, 09:27 Uhr
ao

(Operator)



Zitat von Windalf:
VerXORung

VerKORXung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
25.10.2006, 10:39 Uhr
(un)wissender
Niveauwart


Ich glaube sogar, dass das hier nach dem Standard undefiniert ist:

C++:
U_Int64* p = reinterpret_cast< U_Int64* > (&x);




Bearbeitung:

Definiert wäre das casten nach char*. Dann muss man nur wissen wie groß der Kram ist, sizeof(double), dann kann es losgehen mit dem hashen.


--
Wer früher stirbt ist länger tot.

Dieser Post wurde am 25.10.2006 um 10:41 Uhr von (un)wissender editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
25.10.2006, 11:20 Uhr
ao

(Operator)



Zitat von (un)wissender:
Ich glaube sogar, dass das hier nach dem Standard undefiniert ist:

C++:
U_Int64* p = reinterpret_cast< U_Int64* > (&x);


Definiert wäre das casten nach char*.

Soviel ich weiß, sind Casts von einem Zeigertyp auf einen anderen immer möglich. In C++ müssen sie explizit gemacht werden (C-Style-Cast oder reinterpret_cast), in C noch nicht mal das.

Dieser Post wurde am 25.10.2006 um 11:21 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
25.10.2006, 13:59 Uhr
0xdeadbeef
Gott
(Operator)


Joa, der Cast geht so schon. Das Problem ist, woher weißt du, dass ein double 64 bit lang ist?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
25.10.2006, 14:10 Uhr
virtual
Sexiest Bit alive
(Operator)


Die Länge von double Werten ist nicht das einzige Problem dieses Ansatzes:

von einer HashCode funktion würde ich erwarten, daß der Hashcode für zwei gleiche Zahlen den gleichen hashcode zurückliefert. Dies is bei Fliesskommazahlen aber nicht jedenfalls garantiert.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
25.10.2006, 14:23 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


Naja es wird halt nicht jede Zahl sondern nur die gleiche Repräsentation einer Zahl gleich abgebildet... Da ist ja noch nichts "verwerfliches dran"...
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
25.10.2006, 16:09 Uhr
0xdeadbeef
Gott
(Operator)


Naja, ich würde prinzipiell über den Sinn, Fließkommazahlen zu hashen, streiten wollen - selbst wenn man eine sinnvolle Methode findet, es zu tun.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: