w &= 0xfffffffc
-
Sebastian Pizer schrieb:
Bei
unsignedkann man ja wieder ohne Bedenken bzgl Portabilitätvoid TruncateWidth (unsigned & w) { return w & -4; }schreiben.
wieso? muss -4 auf jedem system dieser erde 0xfffffffc sein?

-
Basher schrieb:
wieso? muss -4 auf jedem system dieser erde 0xfffffffc sein?

Das nicht, aber es wird ja implizit zu einem unsigned konvertiert, bevor & angewendet wird. unsigned(-4) liefert garantiert eine vorzeichenlose Zahl mit Bitmuster "11...1100" -- auch, wenn Du einen Exoten hast, der für vorzeichenbehaftete Ganzzahlen nicht das 2er-Komplement benutzt.
-
Sebastian Pizer schrieb:
Basher schrieb:
wieso? muss -4 auf jedem system dieser erde 0xfffffffc sein?

Das nicht, aber es wird ja implizit zu einem unsigned konvertiert, bevor & angewendet wird. unsigned(-4) liefert garantiert eine vorzeichenlose Zahl mit Bitmuster "11...1100".
wenn nun aber für negative zahlen kein zweier-, sondern z.b. einerkomplement benutzt wird (sowas solls ja geben), dann ist -4 111...1011. damit löschste nur bit 2 weg, nicht bit 1 und 0, wie geplant.
btw, noch 'ne variante:unsigned TruncateWidth (unsigned w) { return (w/4)*4; }
-
Basher schrieb:
wenn nun aber für negative zahlen kein zweier-, sondern z.b. einerkomplement benutzt wird (sowas solls ja geben), dann ist -4 111...1011.
Spielt keine Rolle. Der C++ Standard sagt genau, was passiert, wenn Du eine vorzeichenbehaftete Zahl zu einer vorzeichenlosen Zahl konvertierst. Das Bitmuster, was Du danach erhälst entspricht immer dem 2er-Komplement.
-
Sebastian Pizer schrieb:
Der C++ Standard sagt genau, was passiert, wenn Du eine vorzeichenbehaftete Zahl zu einer vorzeichenlosen Zahl konvertierst. Das Bitmuster, was Du danach erhälst entspricht immer dem 2er-Komplement.
biste sicher? was passiert bei:
// angenommen: negative zahlen sind einerkomplement, 'signed magnitude' oder was anderes unsigned a = (unsigned)-4; // <-- a enthält jetzt bitmuster von -4 im zweierkomplement, nach deiner aussage int b = (int)a; // bekommen wir hier unsere -4 zurück? wohl kaum.
-
Basher schrieb:
biste sicher?
Ja. Soll ich jetzt noch die Stelle aus dem Standard raussuchen? Müste irgendwo bei "standard conversions" sein. Das mit dem Bitmuster ergibt sich aus der Regel, dass bei "u=s;" -- wobei u eine vorzeichenlose Integervariable und s irgend eine andere Integervariable (meinetwegen auch long) ist -- folgendes gilt:
u = s modulo (2 hoch N), N ist hier die Zahl der Bits in u.Basher schrieb:
was passiert bei:
// angenommen: negative zahlen sind einerkomplement, 'signed magnitude' // oder was anderes unsigned a = (unsigned)-4; // <-- a enthält jetzt bitmuster von // -4 im zweierkomplement, nach deiner aussage int b = (int)a; // bekommen wir hier unsere -4 zurück? wohl kaum.Nein. Konvertieren in eine vorzeichenbehaftete Zahl ist "implementation-defined", falls der zugewiesene Wert nicht im Wertebereich liegt. Steht auch so im Standard. Guck mal selbst nach. :p
Gruß,
SP
-
msvc++
ohne probleme kommt da -4 raus. bitmuster bei beiden: 0xfffffffc

-
Für meinen Geschmack ist das diese Variante (x & -4u) ein bisschen zu subtil, auch wenn ich zugeben muss, dass ich das früher auch so geschrieben habe.
x & ~(4u-1) ist vielleicht ein bisschen besser. Bei heutigen Compilern gibt es aber eigentlich nur noch selten einen Grund, das im Code stehen zu lassen.
Sowas hab ich in der Wildnis auch schon gesehen:int foo; while ( foo % 4 != 0 ) foo--;Da ziehe ich dann sogar ein einfaches & vor

-
Sebastian Pizer schrieb:
Das mit dem Bitmuster ergibt sich aus der Regel, dass bei "u=s;" -- wobei u eine vorzeichenlose Integervariable und s irgend eine andere Integervariable (meinetwegen auch long) ist -- folgendes gilt:
u = s modulo (2 hoch N), N ist hier die Zahl der Bits in u.das glaube ich dir, aber das daraus in jedem fall ein zweierkomplement wird, egal mit welcher kodierung ein system negative zahlen speichert, kann ich mir nicht vorstellen.
helferlein schrieb:
msvc++
ohne probleme kommt da -4 raus. bitmuster bei beiden: 0xfffffffcwir reden hier von 'nicht-zweierkomplement' systemen.
camper schrieb:
Für meinen Geschmack ist das diese Variante (x & -4u) ein bisschen zu subtil...
finde ich auch.

-
da wir jetzt alle 1000 tricks kennen, die unteren zwei bits zu löschen, mal andersrum: wie kommt man am schnellsten auf das nächste grössere vielfache von 4? bitte, postet eure vorschläge....

-
Basher schrieb:
Sebastian Pizer schrieb:
Das mit dem Bitmuster ergibt sich aus der Regel, dass bei "u=s;" -- wobei u eine vorzeichenlose Integervariable und s irgend eine andere Integervariable (meinetwegen auch long) ist -- folgendes gilt:
u = s modulo (2 hoch N), N ist hier die Zahl der Bits in u.das glaube ich dir, aber das daraus in jedem fall ein zweierkomplement wird, egal mit welcher kodierung ein system negative zahlen speichert, kann ich mir nicht vorstellen.
Das folgt direkt aus der Modulo-Regel.
// 2er-K 1er-K Sign+Mag int s = -10; // 111...11110110 111...11110101 100...00001010 // 1000...00000000 (2^N) // - 000...00001010 (10) // --------------- unsigned u = s; // 111...11110110 (2^N - 10 = -10 mod 2^N)Gruß,
SP
-
Basher schrieb:
da wir jetzt alle 1000 tricks kennen, die unteren zwei bits zu löschen, mal andersrum: wie kommt man am schnellsten auf das nächste grössere vielfache von 4? bitte, postet eure vorschläge....
Ich nehme an, dass falls die Zahl schon durch 4 teilbar ist, dass sie dann nicht verändert werden soll.
inline unsigned aufrunden(unsigned x) { return (x+3) & unsigned(-4); }Gruß,
SP
-
Sebastian Pizer schrieb:
// 2er-K 1er-K Sign+Mag int s = -10; // 111...11110110 111...11110101 100...00001010 // 1000...00000000 (2^N) // - 000...00001010 (10) // --------------- unsigned u = s; // 111...11110110 (2^N - 10 = -10 mod 2^N)ok, das sieht überzeugend aus (obwohl nicht das 'mod', also % benutzt wird, was wir in C so haben).
Sebastian Pizer schrieb:
Basher schrieb:
da wir jetzt alle 1000 tricks kennen, die unteren zwei bits zu löschen, mal andersrum: wie kommt man am schnellsten auf das nächste grössere vielfache von 4? bitte, postet eure vorschläge....
Ich nehme an, dass falls die Zahl schon durch 4 teilbar ist, dass sie dann nicht verändert werden soll.
ja, und 0 soll auch 0 bleiben. noch mehr vorschläge?

-
Es ist alles Wichtige gesagt. Den Rest mußt du dir denken.