Hi Leute,
habe einen Fehler entdeckt, gelöst und dachte mir, es wäre cool anderen Programmieren die einen ähnlichen Fehler hatten, bzw. um einfach alle davor zu warnen, dass sie nicht in die Falle gehen, es hier einmal zu posten.
Ich habe eine Methode programmiert, die eine Rotation durchführt:
private UInt16 rotateLeft(UInt16 value, int positions)
{
positions = positions % 16;
UInt16 helper1 = value, helper2 = value;
helper1 = (UInt16)(helper1 << positions);
helper2 = (UInt16)(helper2 >> (16-positions));
return (Convert.ToUInt16(helper1 + helper2));
}
private UInt32 rotateLeft(UInt32 value, int positions)
{
positions = positions % 32;
UInt32 helper1 = value, helper2 = value;
helper1 = (UInt32)(helper1 << positions);
helper2 = (UInt32)(helper2 >> (32 - positions));
return (Convert.ToUInt32(helper1 + helper2));
}
Interessanter weise funktioniert diese Methode für ein Shifting von 0 bei der 16-Bit variante, jedoch nicht bei der 32-Bit variante. Warum?
Ich weiß es nicht, aber aus irgendeinem Grund funktioniert bei positions=0 bei der 16-Bit Variante das zweite Shifting vollkommen (sprich der Wert wird auf 0 gesetzt -> klar, er wird ja aus dem Wertebereich rausgeschoben);
Aber bei der 32-Bit Variante wird diese Funktion einfach ignoriert:
helper2 = (UInt32)(helper2 >> 32);
Ich weiß nicht warum er das so macht, aber als Lösung fügt man einfach folgende Zeile hinzu, die bei 0 direkt den eingegebenen Wert zurückliefert.
Sprich die Methoden sehen dann so aus:
private UInt16 rotateLeft(UInt16 value, int positions)
{
if(positions==0)
return value;
positions = positions % 16;
UInt16 helper1 = value, helper2 = value;
helper1 = (UInt16)(helper1 << positions);
helper2 = (UInt16)(helper2 >> (16-positions));
return (Convert.ToUInt16(helper1 + helper2));
}
private UInt32 rotateLeft(UInt32 value, int positions)
{
if(positions==0)
return value;
positions = positions % 32;
UInt32 helper1 = value, helper2 = value;
helper1 = (UInt32)(helper1 << positions);
helper2 = (UInt32)(helper2 >> (32 - positions));
return (Convert.ToUInt32(helper1 + helper2));
}
Liebe Grüße
Alex
Aber bei der 32-Bit Variante wird diese Funktion einfach ignoriert:
helper2 = (UInt32)(helper2 >> 32);
Zitat aus der Hilfe:
If the first operand is an int or uint (32-bit quantity), the shift count is given
by the low-order five bits
of the second operand (second operand & 0x1f).
Der maximale Wert ist also 31.
So richtig erschließt sich mir der Sinn deiner Funktionen aber nicht. Einer der beiden Summanden (helper1/2) wird immer zu Null. Warum nicht einfach
wert << position // bzw. >>
So richtig erschließt sich mir der Sinn deiner Funktionen aber nicht. Einer der beiden Summanden (helper1/2) wird immer zu Null.
Ziel ist eine "Rotation", d.h. Bits, die links oder rechts herausgeschoben werden, erscheinen auf der anderen Seite wieder. So ergibt z. B.
UInt16 t = rotateLeft(0xC000, 1);
t=0x8001
Ah ja. Dann würde ich allerdings ver-odern (statt zu addieren). Macht den Sinn klarer.
Ja. Auch %16 bzw. %32 sollten eher durch bit-& ersetzt werden.
Das Problem mit dem Verschieben um 32 Stellen kann man übrigens lösen, wenn man temporär mit long-Variablen arbeitet.